Ignore:
Timestamp:
May 27, 2014, 11:47:57 PM (10 years ago)
Author:
mistic100
Message:

feature 3077 : factorize code for cache/selectize

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin/themes/default/js/LocalStorageCache.js

    r28542 r28550  
    1 /**
    2  * Base LocalStorage cache
    3  *
    4  * @param options {object}
    5  *    - key (required) identifier of the collection
    6  *    - serverId (recommended) identifier of the Piwigo instance
    7  *    - serverKey (required) state of collection server-side
    8  *    - lifetime (optional) cache lifetime in seconds
    9  *    - loader (required) function called to fetch data, takes a callback as first argument
    10  *        which must be called with the loaded date
    11  */
    12 var LocalStorageCache = function(options) {
    13   this._init(options);
    14 };
    15 
    16 /*
    17  * Constructor (deported for easy inheritance)
    18  */
    19 LocalStorageCache.prototype._init = function(options) {
    20   this.key = options.key + '_' + options.serverId;
    21   this.serverKey = options.serverKey;
    22   this.lifetime = options.lifetime ? options.lifetime*1000 : 3600*1000;
    23   this.loader = options.loader;
    24  
    25   this.storage = window.localStorage;
    26   this.ready = !!this.storage;
    27 };
    28 
    29 /*
    30  * Get the cache content
    31  * @param callback {function} called with the data as first parameter
    32  */
    33 LocalStorageCache.prototype.get = function(callback) {
    34   var now = new Date().getTime(),
    35       that = this;
    36  
    37   if (this.ready && this.storage[this.key] != undefined) {
    38     var cache = JSON.parse(this.storage[this.key]);
    39    
    40     if (now - cache.timestamp <= this.lifetime && cache.key == this.serverKey) {
    41       callback(cache.data);
    42       return;
     1(function($, exports) {
     2  "use strict";
     3 
     4  /**
     5   * Base LocalStorage cache
     6   *
     7   * @param options {object}
     8   *    - key (required) identifier of the collection
     9   *    - serverId (recommended) identifier of the Piwigo instance
     10   *    - serverKey (required) state of collection server-side
     11   *    - lifetime (optional) cache lifetime in seconds
     12   *    - loader (required) function called to fetch data, takes a callback as first argument
     13   *        which must be called with the loaded date
     14   */
     15  var LocalStorageCache = function(options) {
     16    this._init(options);
     17  };
     18
     19  /*
     20   * Constructor (deported for easy inheritance)
     21   */
     22  LocalStorageCache.prototype._init = function(options) {
     23    this.key = options.key + '_' + options.serverId;
     24    this.serverKey = options.serverKey;
     25    this.lifetime = options.lifetime ? options.lifetime*1000 : 3600*1000;
     26    this.loader = options.loader;
     27   
     28    this.storage = window.localStorage;
     29    this.ready = !!this.storage;
     30  };
     31
     32  /*
     33   * Get the cache content
     34   * @param callback {function} called with the data as first parameter
     35   */
     36  LocalStorageCache.prototype.get = function(callback) {
     37    var now = new Date().getTime(),
     38        that = this;
     39   
     40    if (this.ready && this.storage[this.key] != undefined) {
     41      var cache = JSON.parse(this.storage[this.key]);
     42     
     43      if (now - cache.timestamp <= this.lifetime && cache.key == this.serverKey) {
     44        callback(cache.data);
     45        return;
     46      }
    4347    }
    44   }
    45  
    46   this.loader(function(data) {
    47     that.set.call(that, data);
    48     callback(data);
    49   });
    50 };
    51 
    52 /*
    53  * Manually set the cache content
    54  * @param data {mixed}
    55  */
    56 LocalStorageCache.prototype.set = function(data) {
    57   if (this.ready) {
    58     this.storage[this.key] = JSON.stringify({
    59       timestamp: new Date().getTime(),
    60       key: this.serverKey,
    61       data: data
    62     });
    63   }
    64 };
    65 
    66 /*
    67  * Manually clear the cache
    68  */
    69 LocalStorageCache.prototype.clear = function() {
    70   if (this.ready) {
    71     this.storage.removeItem(this.key);
    72   }
    73 };
    74 
    75 
    76 /**
    77  * Special LocalStorage for admin categories list
    78  *
    79  * @param options {object}
    80  *    - serverId (recommended) identifier of the Piwigo instance
    81  *    - serverKey (required) state of collection server-side
    82  *    - rootUrl (required) used for WS call
    83  */
    84 var CategoriesCache = function(options) {
    85   options.key = 'categoriesAdminList';
    86  
    87   options.loader = function(callback) {
    88     jQuery.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.categories.getAdminList', function(data) {
    89       callback(data.result.categories);
    90     });
    91   };
    92  
    93   this._init(options);
    94 };
    95 
    96 CategoriesCache.prototype = new LocalStorageCache({});
    97 
    98 /*
    99  * Init Selectize with cache content
    100  * @param $target {jQuery}
    101  * @param options {object}
    102  *    - default (optional) default value which will be forced if the select is emptyed
    103  *    - filter (optional) function called for each select before applying the data
    104  *      takes two parameters: cache data, options
    105  *      must return new data
    106  */
    107 CategoriesCache.prototype.selectize = function($target, options) {
    108   options = options || {};
    109 
    110   $target.selectize({
    111     valueField: 'id',
    112     labelField: 'fullname',
    113     sortField: 'global_rank',
    114     searchField: ['fullname'],
    115     plugins: ['remove_button']
    116   });
    117  
    118   this.get(function(categories) {
    119     $target.each(function() {
    120       var data;
    121       if (options.filter != undefined) {
    122         data = options.filter.call(this, categories, options);
    123       }
    124       else {
    125         data = categories;
    126       }
     48   
     49    this.loader(function(data) {
     50      that.set.call(that, data);
     51      callback(data);
     52    });
     53  };
     54
     55  /*
     56   * Manually set the cache content
     57   * @param data {mixed}
     58   */
     59  LocalStorageCache.prototype.set = function(data) {
     60    if (this.ready) {
     61      this.storage[this.key] = JSON.stringify({
     62        timestamp: new Date().getTime(),
     63        key: this.serverKey,
     64        data: data
     65      });
     66    }
     67  };
     68
     69  /*
     70   * Manually clear the cache
     71   */
     72  LocalStorageCache.prototype.clear = function() {
     73    if (this.ready) {
     74      this.storage.removeItem(this.key);
     75    }
     76  };
     77
     78 
     79  /**
     80   * Abstract class containing common initialization code for selectize
     81   */
     82  var AbstractSelectizer = function(){};
     83  AbstractSelectizer.prototype = new LocalStorageCache({});
     84
     85  /*
     86   * Load Selectize with cache content
     87   * @param $target {jQuery}
     88   * @param options {object}
     89   *    - default (optional) default value which will be forced if the select is emptyed
     90   *    - filter (optional) function called for each select before applying the data
     91   *      takes two parameters: cache data, options
     92   *      must return new data
     93   */
     94  AbstractSelectizer.prototype._selectize = function($target, options) {
     95    this.get(function(data) {
     96      $target.each(function() {
     97        var filtered, value;
     98       
     99        // apply filter function
     100        if (options.filter != undefined) {
     101          filtered = options.filter.call(this, data, options);
     102        }
     103        else {
     104          filtered = data;
     105        }
     106       
     107        // active creation mode
     108        if (this.hasAttribute('data-selectize-create')) {
     109          this.selectize.settings.create = true;
     110        }
     111       
     112        // load options
     113        this.selectize.load(function(callback) {
     114          if ($.isEmptyObject(this.options)) {
     115            callback(filtered);
     116          }
     117        });
     118
     119        // load items
     120        if ((value = $(this).data('value'))) {
     121          $.each(value, $.proxy(function(i, cat) {
     122            if ($.isNumeric(cat))
     123              this.selectize.addItem(cat);
     124            else
     125              this.selectize.addItem(cat.id);
     126          }, this));
     127        }
     128       
     129        if (options.default != undefined) {
     130          // add default item
     131          if (this.selectize.getValue() == '') {
     132            this.selectize.addItem(options.default);
     133          }
     134
     135          // if multiple: prevent item deletion
     136          if (this.multiple) {
     137            this.selectize.getItem(options.default).find('.remove').hide();
     138           
     139            this.selectize.on('item_remove', function(id) {
     140              if (id == options.default) {
     141                this.addItem(id);
     142                this.getItem(id).find('.remove').hide();
     143              }
     144            });
     145          }
     146          // if single: restore default on blur
     147          else {
     148            this.selectize.on('dropdown_close', function() {
     149              if (this.getValue() == '') {
     150                this.addItem(options.default);
     151              }
     152            });
     153          }
     154        }
     155      });
     156    });
     157  };
     158
     159
     160  /**
     161   * Special LocalStorage for admin categories list
     162   *
     163   * @param options {object}
     164   *    - serverId (recommended) identifier of the Piwigo instance
     165   *    - serverKey (required) state of collection server-side
     166   *    - rootUrl (required) used for WS call
     167   */
     168  var CategoriesCache = function(options) {
     169    options.key = 'categoriesAdminList';
     170   
     171    options.loader = function(callback) {
     172      $.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.categories.getAdminList', function(data) {
     173        callback(data.result.categories);
     174      });
     175    };
     176   
     177    this._init(options);
     178  };
     179
     180  CategoriesCache.prototype = new AbstractSelectizer();
     181
     182  /*
     183   * Init Selectize with cache content
     184   * @see AbstractSelectizer._selectize
     185   */
     186  CategoriesCache.prototype.selectize = function($target, options) {
     187    options = options || {};
     188
     189    $target.selectize({
     190      valueField: 'id',
     191      labelField: 'fullname',
     192      sortField: 'global_rank',
     193      searchField: ['fullname'],
     194      plugins: ['remove_button']
     195    });
     196   
     197    this._selectize($target, options);
     198  };
     199
     200
     201  /**
     202   * Special LocalStorage for admin tags list
     203   *
     204   * @param options {object}
     205   *    - serverId (recommended) identifier of the Piwigo instance
     206   *    - serverKey (required) state of collection server-side
     207   *    - rootUrl (required) used for WS call
     208   */
     209  var TagsCache = function(options) {
     210    options.key = 'tagsAdminList';
     211   
     212    options.loader = function(callback) {
     213      $.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.tags.getAdminList', function(data) {
     214        var tags = data.result.tags;
     215       
     216        for (var i=0, l=tags.length; i<l; i++) {
     217          tags[i].id = '~~' + tags[i].id + '~~';
     218        }
     219       
     220        callback(tags);
     221      });
     222    };
     223   
     224    this._init(options);
     225  };
     226
     227  TagsCache.prototype = new AbstractSelectizer();
     228
     229  /*
     230   * Init Selectize with cache content
     231   * @see AbstractSelectizer._selectize
     232   */
     233  TagsCache.prototype.selectize = function($target, options) {
     234    options = options || {};
     235
     236    $target.selectize({
     237      valueField: 'id',
     238      labelField: 'name',
     239      sortField: 'name',
     240      searchField: ['name'],
     241      plugins: ['remove_button']
     242    });
     243   
     244    this._selectize($target, options);
     245  };
     246 
     247 
     248  /**
     249   * Special LocalStorage for admin groups list
     250   *
     251   * @param options {object}
     252   *    - serverId (recommended) identifier of the Piwigo instance
     253   *    - serverKey (required) state of collection server-side
     254   *    - rootUrl (required) used for WS call
     255   */
     256  var GroupsCache = function(options) {
     257    options.key = 'groupsAdminList';
     258   
     259    options.loader = function(callback) {
     260      $.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.groups.getList&per_page=9999', function(data) {
     261        callback(data.result.groups);
     262      });
     263    };
     264   
     265    this._init(options);
     266  };
     267
     268  GroupsCache.prototype = new AbstractSelectizer();
     269
     270  /*
     271   * Init Selectize with cache content
     272   * @see AbstractSelectizer._selectize
     273   */
     274  GroupsCache.prototype.selectize = function($target, options) {
     275    options = options || {};
     276
     277    $target.selectize({
     278      valueField: 'id',
     279      labelField: 'name',
     280      sortField: 'name',
     281      searchField: ['name'],
     282      plugins: ['remove_button']
     283    });
     284   
     285    this._selectize($target, options);
     286  };
     287 
     288 
     289  /**
     290   * Special LocalStorage for admin users list
     291   *
     292   * @param options {object}
     293   *    - serverId (recommended) identifier of the Piwigo instance
     294   *    - serverKey (required) state of collection server-side
     295   *    - rootUrl (required) used for WS call
     296   */
     297  var UsersCache = function(options) {
     298    options.key = 'usersAdminList';
     299   
     300    options.loader = function(callback) {
     301      var users = [];
    127302     
    128       this.selectize.load(function(callback) {
    129         callback(data);
    130       });
    131 
    132       if (jQuery(this).data('value')) {
    133         jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, id) {
    134           this.selectize.addItem(id);
    135         }, this));
    136       }
    137      
    138       if (options.default != undefined) {
    139         if (this.selectize.getValue() == '') {
    140           this.selectize.addItem(options.default);
    141         }
    142 
    143         // if multiple: prevent item deletion
    144         if (this.multiple) {
    145           this.selectize.getItem(options.default).find('.remove').hide();
     303      // recursive loader
     304      (function load(page){
     305        jQuery.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.users.getList&display=username&per_page=9999&page='+ page, function(data) {
     306          users = users.concat(data.result.users);
    146307         
    147           this.selectize.on('item_remove', function(id) {
    148             if (id == options.default) {
    149               this.addItem(id);
    150               this.getItem(id).find('.remove').hide();
    151             }
    152           });
    153         }
    154         // if single: restore default on blur
    155         else {
    156           this.selectize.on('dropdown_close', function() {
    157             if (this.getValue() == '') {
    158               this.addItem(options.default);
    159             }
    160           });
    161         }
    162       }
    163     });
    164   });
    165 };
     308          if (data.result.paging.count == data.result.paging.per_page) {
     309            load(++page);
     310          }
     311          else {
     312            callback(users);
     313          }
     314        });
     315      }(0));
     316    };
     317   
     318    this._init(options);
     319  };
     320
     321  UsersCache.prototype = new AbstractSelectizer();
     322
     323  /*
     324   * Init Selectize with cache content
     325   * @see AbstractSelectizer._selectize
     326   */
     327  UsersCache.prototype.selectize = function($target, options) {
     328    options = options || {};
     329
     330    $target.selectize({
     331      valueField: 'id',
     332      labelField: 'username',
     333      sortField: 'username',
     334      searchField: ['username'],
     335      plugins: ['remove_button']
     336    });
     337   
     338    this._selectize($target, options);
     339  };
     340 
     341 
     342  /**
     343   * Expose classes in global scope
     344   */
     345  exports.LocalStorageCache = LocalStorageCache;
     346  exports.CategoriesCache = CategoriesCache;
     347  exports.TagsCache = TagsCache;
     348  exports.GroupsCache = GroupsCache;
     349  exports.UsersCache = UsersCache;
     350 
     351}(jQuery, window));
Note: See TracChangeset for help on using the changeset viewer.