Index: /trunk/admin/themes/default/js/LocalStorageCache.js
===================================================================
--- /trunk/admin/themes/default/js/LocalStorageCache.js	(revision 28549)
+++ /trunk/admin/themes/default/js/LocalStorageCache.js	(revision 28550)
@@ -1,165 +1,351 @@
-/**
- * Base LocalStorage cache
- *
- * @param options {object}
- *    - key (required) identifier of the collection
- *    - serverId (recommended) identifier of the Piwigo instance
- *    - serverKey (required) state of collection server-side
- *    - lifetime (optional) cache lifetime in seconds
- *    - loader (required) function called to fetch data, takes a callback as first argument
- *        which must be called with the loaded date
- */
-var LocalStorageCache = function(options) {
-  this._init(options);
-};
-
-/*
- * Constructor (deported for easy inheritance)
- */
-LocalStorageCache.prototype._init = function(options) {
-  this.key = options.key + '_' + options.serverId;
-  this.serverKey = options.serverKey;
-  this.lifetime = options.lifetime ? options.lifetime*1000 : 3600*1000;
-  this.loader = options.loader;
-  
-  this.storage = window.localStorage;
-  this.ready = !!this.storage;
-};
-
-/*
- * Get the cache content
- * @param callback {function} called with the data as first parameter
- */
-LocalStorageCache.prototype.get = function(callback) {
-  var now = new Date().getTime(),
-      that = this;
-  
-  if (this.ready && this.storage[this.key] != undefined) {
-    var cache = JSON.parse(this.storage[this.key]);
-    
-    if (now - cache.timestamp <= this.lifetime && cache.key == this.serverKey) {
-      callback(cache.data);
-      return;
+(function($, exports) {
+  "use strict";
+  
+  /**
+   * Base LocalStorage cache
+   *
+   * @param options {object}
+   *    - key (required) identifier of the collection
+   *    - serverId (recommended) identifier of the Piwigo instance
+   *    - serverKey (required) state of collection server-side
+   *    - lifetime (optional) cache lifetime in seconds
+   *    - loader (required) function called to fetch data, takes a callback as first argument
+   *        which must be called with the loaded date
+   */
+  var LocalStorageCache = function(options) {
+    this._init(options);
+  };
+
+  /*
+   * Constructor (deported for easy inheritance)
+   */
+  LocalStorageCache.prototype._init = function(options) {
+    this.key = options.key + '_' + options.serverId;
+    this.serverKey = options.serverKey;
+    this.lifetime = options.lifetime ? options.lifetime*1000 : 3600*1000;
+    this.loader = options.loader;
+    
+    this.storage = window.localStorage;
+    this.ready = !!this.storage;
+  };
+
+  /*
+   * Get the cache content
+   * @param callback {function} called with the data as first parameter
+   */
+  LocalStorageCache.prototype.get = function(callback) {
+    var now = new Date().getTime(),
+        that = this;
+    
+    if (this.ready && this.storage[this.key] != undefined) {
+      var cache = JSON.parse(this.storage[this.key]);
+      
+      if (now - cache.timestamp <= this.lifetime && cache.key == this.serverKey) {
+        callback(cache.data);
+        return;
+      }
     }
-  }
-  
-  this.loader(function(data) {
-    that.set.call(that, data);
-    callback(data);
-  });
-};
-
-/*
- * Manually set the cache content
- * @param data {mixed}
- */
-LocalStorageCache.prototype.set = function(data) {
-  if (this.ready) {
-    this.storage[this.key] = JSON.stringify({
-      timestamp: new Date().getTime(),
-      key: this.serverKey,
-      data: data
-    });
-  }
-};
-
-/*
- * Manually clear the cache
- */
-LocalStorageCache.prototype.clear = function() {
-  if (this.ready) {
-    this.storage.removeItem(this.key);
-  }
-};
-
-
-/**
- * Special LocalStorage for admin categories list
- *
- * @param options {object}
- *    - serverId (recommended) identifier of the Piwigo instance
- *    - serverKey (required) state of collection server-side
- *    - rootUrl (required) used for WS call
- */
-var CategoriesCache = function(options) {
-  options.key = 'categoriesAdminList';
-  
-  options.loader = function(callback) {
-    jQuery.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.categories.getAdminList', function(data) {
-      callback(data.result.categories);
-    });
-  };
-  
-  this._init(options);
-};
-
-CategoriesCache.prototype = new LocalStorageCache({});
-
-/*
- * Init Selectize with cache content
- * @param $target {jQuery}
- * @param options {object}
- *    - default (optional) default value which will be forced if the select is emptyed
- *    - filter (optional) function called for each select before applying the data
- *      takes two parameters: cache data, options
- *      must return new data
- */
-CategoriesCache.prototype.selectize = function($target, options) {
-  options = options || {};
-
-  $target.selectize({
-    valueField: 'id',
-    labelField: 'fullname',
-    sortField: 'global_rank',
-    searchField: ['fullname'],
-    plugins: ['remove_button']
-  });
-  
-  this.get(function(categories) {
-    $target.each(function() {
-      var data;
-      if (options.filter != undefined) {
-        data = options.filter.call(this, categories, options);
-      }
-      else {
-        data = categories;
-      }
+    
+    this.loader(function(data) {
+      that.set.call(that, data);
+      callback(data);
+    });
+  };
+
+  /*
+   * Manually set the cache content
+   * @param data {mixed}
+   */
+  LocalStorageCache.prototype.set = function(data) {
+    if (this.ready) {
+      this.storage[this.key] = JSON.stringify({
+        timestamp: new Date().getTime(),
+        key: this.serverKey,
+        data: data
+      });
+    }
+  };
+
+  /*
+   * Manually clear the cache
+   */
+  LocalStorageCache.prototype.clear = function() {
+    if (this.ready) {
+      this.storage.removeItem(this.key);
+    }
+  };
+
+  
+  /**
+   * Abstract class containing common initialization code for selectize
+   */
+  var AbstractSelectizer = function(){};
+  AbstractSelectizer.prototype = new LocalStorageCache({});
+
+  /*
+   * Load Selectize with cache content
+   * @param $target {jQuery}
+   * @param options {object}
+   *    - default (optional) default value which will be forced if the select is emptyed
+   *    - filter (optional) function called for each select before applying the data
+   *      takes two parameters: cache data, options
+   *      must return new data
+   */
+  AbstractSelectizer.prototype._selectize = function($target, options) {
+    this.get(function(data) {
+      $target.each(function() {
+        var filtered, value;
+        
+        // apply filter function
+        if (options.filter != undefined) {
+          filtered = options.filter.call(this, data, options);
+        }
+        else {
+          filtered = data;
+        }
+        
+        // active creation mode
+        if (this.hasAttribute('data-selectize-create')) {
+          this.selectize.settings.create = true;
+        }
+        
+        // load options
+        this.selectize.load(function(callback) {
+          if ($.isEmptyObject(this.options)) {
+            callback(filtered);
+          }
+        });
+
+        // load items
+        if ((value = $(this).data('value'))) {
+          $.each(value, $.proxy(function(i, cat) {
+            if ($.isNumeric(cat))
+              this.selectize.addItem(cat);
+            else
+              this.selectize.addItem(cat.id);
+          }, this));
+        }
+        
+        if (options.default != undefined) {
+          // add default item
+          if (this.selectize.getValue() == '') {
+            this.selectize.addItem(options.default);
+          }
+
+          // if multiple: prevent item deletion
+          if (this.multiple) {
+            this.selectize.getItem(options.default).find('.remove').hide();
+            
+            this.selectize.on('item_remove', function(id) {
+              if (id == options.default) {
+                this.addItem(id);
+                this.getItem(id).find('.remove').hide();
+              }
+            });
+          }
+          // if single: restore default on blur
+          else {
+            this.selectize.on('dropdown_close', function() {
+              if (this.getValue() == '') {
+                this.addItem(options.default);
+              }
+            });
+          }
+        }
+      });
+    });
+  };
+
+
+  /**
+   * Special LocalStorage for admin categories list
+   *
+   * @param options {object}
+   *    - serverId (recommended) identifier of the Piwigo instance
+   *    - serverKey (required) state of collection server-side
+   *    - rootUrl (required) used for WS call
+   */
+  var CategoriesCache = function(options) {
+    options.key = 'categoriesAdminList';
+    
+    options.loader = function(callback) {
+      $.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.categories.getAdminList', function(data) {
+        callback(data.result.categories);
+      });
+    };
+    
+    this._init(options);
+  };
+
+  CategoriesCache.prototype = new AbstractSelectizer();
+
+  /*
+   * Init Selectize with cache content
+   * @see AbstractSelectizer._selectize
+   */
+  CategoriesCache.prototype.selectize = function($target, options) {
+    options = options || {};
+
+    $target.selectize({
+      valueField: 'id',
+      labelField: 'fullname',
+      sortField: 'global_rank',
+      searchField: ['fullname'],
+      plugins: ['remove_button']
+    });
+    
+    this._selectize($target, options);
+  };
+
+
+  /**
+   * Special LocalStorage for admin tags list
+   *
+   * @param options {object}
+   *    - serverId (recommended) identifier of the Piwigo instance
+   *    - serverKey (required) state of collection server-side
+   *    - rootUrl (required) used for WS call
+   */
+  var TagsCache = function(options) {
+    options.key = 'tagsAdminList';
+    
+    options.loader = function(callback) {
+      $.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.tags.getAdminList', function(data) {
+        var tags = data.result.tags;
+        
+        for (var i=0, l=tags.length; i<l; i++) {
+          tags[i].id = '~~' + tags[i].id + '~~';
+        }
+        
+        callback(tags);
+      });
+    };
+    
+    this._init(options);
+  };
+
+  TagsCache.prototype = new AbstractSelectizer();
+
+  /*
+   * Init Selectize with cache content
+   * @see AbstractSelectizer._selectize
+   */
+  TagsCache.prototype.selectize = function($target, options) {
+    options = options || {};
+
+    $target.selectize({
+      valueField: 'id',
+      labelField: 'name',
+      sortField: 'name',
+      searchField: ['name'],
+      plugins: ['remove_button']
+    });
+    
+    this._selectize($target, options);
+  };
+  
+  
+  /**
+   * Special LocalStorage for admin groups list
+   *
+   * @param options {object}
+   *    - serverId (recommended) identifier of the Piwigo instance
+   *    - serverKey (required) state of collection server-side
+   *    - rootUrl (required) used for WS call
+   */
+  var GroupsCache = function(options) {
+    options.key = 'groupsAdminList';
+    
+    options.loader = function(callback) {
+      $.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.groups.getList&per_page=9999', function(data) {
+        callback(data.result.groups);
+      });
+    };
+    
+    this._init(options);
+  };
+
+  GroupsCache.prototype = new AbstractSelectizer();
+
+  /*
+   * Init Selectize with cache content
+   * @see AbstractSelectizer._selectize
+   */
+  GroupsCache.prototype.selectize = function($target, options) {
+    options = options || {};
+
+    $target.selectize({
+      valueField: 'id',
+      labelField: 'name',
+      sortField: 'name',
+      searchField: ['name'],
+      plugins: ['remove_button']
+    });
+    
+    this._selectize($target, options);
+  };
+  
+  
+  /**
+   * Special LocalStorage for admin users list
+   *
+   * @param options {object}
+   *    - serverId (recommended) identifier of the Piwigo instance
+   *    - serverKey (required) state of collection server-side
+   *    - rootUrl (required) used for WS call
+   */
+  var UsersCache = function(options) {
+    options.key = 'usersAdminList';
+    
+    options.loader = function(callback) {
+      var users = [];
       
-      this.selectize.load(function(callback) {
-        callback(data);
-      });
-
-      if (jQuery(this).data('value')) {
-        jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, id) {
-          this.selectize.addItem(id);
-        }, this));
-      }
-      
-      if (options.default != undefined) {
-        if (this.selectize.getValue() == '') {
-          this.selectize.addItem(options.default);
-        }
-
-        // if multiple: prevent item deletion
-        if (this.multiple) {
-          this.selectize.getItem(options.default).find('.remove').hide();
+      // recursive loader
+      (function load(page){
+        jQuery.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.users.getList&display=username&per_page=9999&page='+ page, function(data) {
+          users = users.concat(data.result.users);
           
-          this.selectize.on('item_remove', function(id) {
-            if (id == options.default) {
-              this.addItem(id);
-              this.getItem(id).find('.remove').hide();
-            }
-          });
-        }
-        // if single: restore default on blur
-        else {
-          this.selectize.on('dropdown_close', function() {
-            if (this.getValue() == '') {
-              this.addItem(options.default);
-            }
-          });
-        }
-      }
-    });
-  });
-};
+          if (data.result.paging.count == data.result.paging.per_page) {
+            load(++page);
+          }
+          else {
+            callback(users);
+          }
+        });
+      }(0));
+    };
+    
+    this._init(options);
+  };
+
+  UsersCache.prototype = new AbstractSelectizer();
+
+  /*
+   * Init Selectize with cache content
+   * @see AbstractSelectizer._selectize
+   */
+  UsersCache.prototype.selectize = function($target, options) {
+    options = options || {};
+
+    $target.selectize({
+      valueField: 'id',
+      labelField: 'username',
+      sortField: 'username',
+      searchField: ['username'],
+      plugins: ['remove_button']
+    });
+    
+    this._selectize($target, options);
+  };
+  
+  
+  /**
+   * Expose classes in global scope
+   */
+  exports.LocalStorageCache = LocalStorageCache;
+  exports.CategoriesCache = CategoriesCache;
+  exports.TagsCache = TagsCache;
+  exports.GroupsCache = GroupsCache;
+  exports.UsersCache = UsersCache;
+  
+}(jQuery, window));
Index: /trunk/admin/themes/default/template/batch_manager_global.tpl
===================================================================
--- /trunk/admin/themes/default/template/batch_manager_global.tpl	(revision 28549)
+++ /trunk/admin/themes/default/template/batch_manager_global.tpl	(revision 28550)
@@ -69,53 +69,11 @@
   
   {* <!-- TAGS --> *}
-  var tagsCache = new LocalStorageCache({
-    key: 'tagsAdminList',
+  var tagsCache = new TagsCache({
     serverKey: '{$CACHE_KEYS.tags}',
     serverId: '{$CACHE_KEYS._hash}',
-
-    loader: function(callback) {
-      jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.tags.getAdminList', function(data) {
-        var tags = data.result.tags;
-        
-        for (var i=0, l=tags.length; i<l; i++) {
-          tags[i].id = '~~' + tags[i].id + '~~';
-        }
-        
-        callback(tags);
-      });
-    }
-  });
-  
-  jQuery('[data-selectize=tags]').selectize({
-    valueField: 'id',
-    labelField: 'name',
-    searchField: ['name'],
-    plugins: ['remove_button']
-  });
-  
-  jQuery('[data-selectize=tags-create]').selectize({
-    valueField: 'id',
-    labelField: 'name',
-    searchField: ['name'],
-    plugins: ['remove_button'],
-    create: true
-  });
-  
-  tagsCache.get(function(tags) {
-    jQuery('[data-selectize^=tags]').each(function() {
-      this.selectize.load(function(callback) {
-        // one select is populated with <option>
-        if (jQuery.isEmptyObject(this.options)) {
-          callback(tags);
-        }
-      });
-
-      if (jQuery(this).data('value')) {
-        jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, tag) {
-          this.selectize.addItem(tag.id);
-        }, this));
-      }
-    });
-  });
+    rootUrl: '{$ROOT_URL}'
+  });
+
+  tagsCache.selectize(jQuery('[data-selectize=tags]'));
   
   {* <!-- CATEGORIES --> *}
@@ -655,5 +613,5 @@
         {'Tags'|@translate}
         <select data-selectize="tags" data-value="{$filter_tags|@json_encode|escape:html}"
-          name="filter_tags[]" multiple style="width:400px;" ></select>
+          name="filter_tags[]" multiple style="width:400px;"></select>
         <label><span><input type="radio" name="tag_mode" value="AND" {if !isset($filter.tag_mode) or $filter.tag_mode eq 'AND'}checked="checked"{/if}> {'All tags'|@translate}</span></label>
         <label><span><input type="radio" name="tag_mode" value="OR" {if isset($filter.tag_mode) and $filter.tag_mode eq 'OR'}checked="checked"{/if}> {'Any tag'|@translate}</span></label>
@@ -875,5 +833,5 @@
     <!-- add_tags -->
     <div id="action_add_tags" class="bulkAction">
-      <select data-selectize="tags-create" name="add_tags[]" multiple style="width:400px;"></select>
+      <select data-selectize="tags" data-selectize-create name="add_tags[]" multiple style="width:400px;"></select>
     </div>
 
Index: /trunk/admin/themes/default/template/batch_manager_unit.tpl
===================================================================
--- /trunk/admin/themes/default/template/batch_manager_unit.tpl	(revision 28549)
+++ /trunk/admin/themes/default/template/batch_manager_unit.tpl	(revision 28550)
@@ -11,41 +11,11 @@
 (function(){
 {* <!-- TAGS --> *}
-var tagsCache = new LocalStorageCache({
-  key: 'tagsAdminList',
+var tagsCache = new TagsCache({
   serverKey: '{$CACHE_KEYS.tags}',
   serverId: '{$CACHE_KEYS._hash}',
-
-  loader: function(callback) {
-    jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.tags.getAdminList', function(data) {
-      var tags = data.result.tags;
-      
-      for (var i=0, l=tags.length; i<l; i++) {
-        tags[i].id = '~~' + tags[i].id + '~~';
-      }
-      
-      callback(tags);
-    });
-  }
+  rootUrl: '{$ROOT_URL}'
 });
 
-jQuery('[data-selectize=tags]').selectize({
-  valueField: 'id',
-  labelField: 'name',
-  searchField: ['name'],
-  plugins: ['remove_button'],
-  create: true
-});
-
-tagsCache.get(function(tags) {
-  jQuery('[data-selectize=tags]').each(function() {
-    this.selectize.load(function(callback) {
-      callback(tags);
-    });
-
-    jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, tag) {
-      this.selectize.addItem(tag.id);
-    }, this));
-  });
-});
+tagsCache.selectize(jQuery('[data-selectize=tags]'));
 
 {* <!-- DATEPICKER --> *}
@@ -129,5 +99,5 @@
       <td>
         <select data-selectize="tags" data-value="{$element.TAGS|@json_encode|escape:html}"
-          name="tags-{$element.id}[]" multiple style="width:500px;" ></select>
+          name="tags-{$element.id}[]" multiple style="width:500px;" data-selectize-create></select>
       </td>
     </tr>
Index: /trunk/admin/themes/default/template/cat_perm.tpl
===================================================================
--- /trunk/admin/themes/default/template/cat_perm.tpl	(revision 28549)
+++ /trunk/admin/themes/default/template/cat_perm.tpl	(revision 28550)
@@ -7,78 +7,20 @@
 (function(){
 {* <!-- GROUPS --> *}
-var groupsCache = new LocalStorageCache({
-  key: 'groupsAdminList',
+var groupsCache = new GroupsCache({
   serverKey: '{$CACHE_KEYS.groups}',
   serverId: '{$CACHE_KEYS._hash}',
-
-  loader: function(callback) {
-    jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.groups.getList&per_page=99999', function(data) {
-      callback(data.result.groups);
-    });
-  }
+  rootUrl: '{$ROOT_URL}'
 });
 
-jQuery('[data-selectize=groups]').selectize({
-  valueField: 'id',
-  labelField: 'name',
-  searchField: ['name'],
-  plugins: ['remove_button']
+groupsCache.selectize(jQuery('[data-selectize=groups]'));
+
+{* <!-- USERS --> *}
+var usersCache = new UsersCache({
+  serverKey: '{$CACHE_KEYS.users}',
+  serverId: '{$CACHE_KEYS._hash}',
+  rootUrl: '{$ROOT_URL}'
 });
 
-groupsCache.get(function(groups) {
-  jQuery('[data-selectize=groups]').each(function() {
-    this.selectize.load(function(callback) {
-      callback(groups);
-    });
-
-    jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, id) {
-      this.selectize.addItem(id);
-    }, this));
-  });
-});
-
-{* <!-- USERS --> *}
-var usersCache = new LocalStorageCache({
-  key: 'usersAdminList',
-  serverKey: '{$CACHE_KEYS.users}',
-  serverId: '{$CACHE_KEYS._hash}',
-
-  loader: function(callback) {
-    var users = [];
-    
-    // recursive loader
-    (function load(page){
-      jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.users.getList&display=username&per_page=99999&page='+ page, function(data) {
-        users = users.concat(data.result.users);
-        
-        if (data.result.paging.count == data.result.paging.per_page) {
-          load(++page);
-        }
-        else {
-          callback(users);
-        }
-      });
-    }(0));
-  }
-});
-
-jQuery('[data-selectize=users]').selectize({
-  valueField: 'id',
-  labelField: 'username',
-  searchField: ['username'],
-  plugins: ['remove_button']
-});
-
-usersCache.get(function(users) {
-  jQuery('[data-selectize=users]').each(function() {
-    this.selectize.load(function(callback) {
-      callback(users);
-    });
-
-    jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, id) {
-      this.selectize.addItem(id);
-    }, this));
-  });
-});
+usersCache.selectize(jQuery('[data-selectize=users]'));
 
 {* <!-- TOGGLES --> *}
@@ -131,5 +73,5 @@
     <br>
     <select data-selectize="groups" data-value="{$groups_selected|@json_encode|escape:html}"
-        name="groups[]" multiple style="width:600px;" ></select>
+        name="groups[]" multiple style="width:600px;"></select>
 {else}
     {'There is no group in this gallery.'|@translate} <a href="admin.php?page=group_list" class="externalLink">{'Group management'|@translate}</a>
@@ -141,5 +83,5 @@
     <br>
     <select data-selectize="users" data-value="{$users_selected|@json_encode|escape:html}"
-        name="users[]" multiple style="width:600px;" ></select>
+        name="users[]" multiple style="width:600px;"></select>
   </p>
 
Index: /trunk/admin/themes/default/template/picture_modify.tpl
===================================================================
--- /trunk/admin/themes/default/template/picture_modify.tpl	(revision 28549)
+++ /trunk/admin/themes/default/template/picture_modify.tpl	(revision 28550)
@@ -25,41 +25,11 @@
 
 {* <!-- TAGS --> *}
-var tagsCache = new LocalStorageCache({
-  key: 'tagsAdminList',
+var tagsCache = new TagsCache({
   serverKey: '{$CACHE_KEYS.tags}',
   serverId: '{$CACHE_KEYS._hash}',
-
-  loader: function(callback) {
-    jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.tags.getAdminList', function(data) {
-      var tags = data.result.tags;
-      
-      for (var i=0, l=tags.length; i<l; i++) {
-        tags[i].id = '~~' + tags[i].id + '~~';
-      }
-      
-      callback(tags);
-    });
-  }
+  rootUrl: '{$ROOT_URL}'
 });
 
-jQuery('[data-selectize=tags]').selectize({
-  valueField: 'id',
-  labelField: 'name',
-  searchField: ['name'],
-  plugins: ['remove_button'],
-  create: true
-});
-
-tagsCache.get(function(tags) {
-  jQuery('[data-selectize=tags]').each(function() {
-    this.selectize.load(function(callback) {
-      callback(tags);
-    });
-
-    jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, tag) {
-      this.selectize.addItem(tag.id);
-    }, this));
-  });
-});
+tagsCache.selectize(jQuery('[data-selectize=tags]'));
 
 {* <!-- DATEPICKER --> *}
@@ -140,5 +110,5 @@
       <br>
       <select data-selectize="categories" data-value="{$associated_albums|@json_encode|escape:html}"
-        name="associate[]" multiple style="width:600px;" ></select>
+        name="associate[]" multiple style="width:600px;"></select>
     </p>
 
@@ -147,5 +117,5 @@
       <br>
       <select data-selectize="categories" data-value="{$represented_albums|@json_encode|escape:html}"
-        name="represent[]" multiple style="width:600px;" ></select>
+        name="represent[]" multiple style="width:600px;"></select>
     </p>
 
@@ -154,5 +124,5 @@
       <br>
       <select data-selectize="tags" data-value="{$tag_selection|@json_encode|escape:html}"
-        name="tags[]" multiple style="width:600px;" ></select>
+        name="tags[]" multiple style="width:600px;" data-selectize-create></select>
     </p>
 
