source: sipes/modules_contrib/hierarchical_select/hierarchical_select_cache.js @ ef72343

stableversion-3.0
Last change on this file since ef72343 was 177a560, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se agrego el directorio de modulos contribuidos de drupal

  • Propiedad mode establecida a 100755
File size: 9.1 KB
Línea 
1
2/**
3 * @file
4 * Cache system for Hierarchical Select.
5 * This cache system takes advantage of the HTML 5 client-side database
6 * storage specification to reduce the number of queries to the server. A lazy
7 * loading strategy is used.
8 */
9
10
11/**
12 * Note: this cache system can be replaced by another one, as long as you
13 * provide the following methods:
14 *  - initialize()
15 *  - status()
16 *  - load()
17 *  - sync()
18 *  - updateHierarchicalSelect()
19 *
20 * TODO: better documentation
21 */
22
23(function ($) {
24
25Drupal.HierarchicalSelect.cache = {};
26
27Drupal.HierarchicalSelect.cache.initialize = function() {
28  try {
29    if (window.openDatabase) {
30      this.db = openDatabase("Hierarchical Select", "3.x", "Hierarchical Select cache", 200000);
31
32      this.db
33      // Create the housekeeping table if it doesn't exist yet.
34      .transaction(function(tx) {
35        tx.executeSql("SELECT COUNT(*) FROM hierarchical_select", [], null, function(tx, error) {
36          tx.executeSql("CREATE TABLE hierarchical_select (table_name TEXT UNIQUE, expires REAL)", []);
37          console.log("Created housekeeping table.");
38        });       
39      })
40      // Empty tables that have expired, based on the information in the
41      // housekeeping table.
42      .transaction(function(tx) {
43        tx.executeSql("SELECT table_name FROM hierarchical_select WHERE expires < ?", [ new Date().getTime() ], function(tx, resultSet) {
44          for (var i = 0; i < resultSet.rows.length; i++) {
45            var row = resultSet.rows.item(i);
46            var newExpiresTimestamp = new Date().getTime() + 86400;
47
48            tx.executeSql("DELETE * FROM " + row.table_name);
49            tx.executeSql("UPDATE hierarchical_select SET expires = ? WHERE table_name = ?", [ newExpiresTimestamp, row.table_name ]);
50
51            console.log("Table "+ row.table_name +" was expired: emptied it. Will expire again in "+ (newExpiresTimestamp - new Date().getTime()) / 3600 +" hours.");
52          }
53        });
54      });
55    }
56    else {
57      this.db = false;
58    }
59  }
60  catch(err) { }
61};
62
63Drupal.HierarchicalSelect.cache.status = function() {
64  return Drupal.HierarchicalSelect.cache.db !== false;
65};
66
67Drupal.HierarchicalSelect.cache.table = function(hsid) {
68  return Drupal.settings.HierarchicalSelect.settings[hsid].cacheId;
69};
70
71Drupal.HierarchicalSelect.cache.load = function(hsid) {
72  // If necessary, create the cache table for the given Hierarchical Select.
73  Drupal.HierarchicalSelect.cache.db.transaction(function(tx) {
74    var table = Drupal.HierarchicalSelect.cache.table(hsid);
75
76    tx.executeSql("SELECT value FROM "+ table, [], function(tx, resultSet) {
77      console.log("" + resultSet.rows.length + " cached items in the " + table + " table.");
78    }, function(tx, error) {
79      var expiresTimestamp = new Date().getTime() + 86400;
80
81      tx.executeSql("CREATE TABLE "+ table +" (parent REAL, value REAL UNIQUE, label REAL, weight REAL)");
82      tx.executeSql("INSERT INTO hierarchical_select (table_name, expires) VALUES (?, ?)", [ table, expiresTimestamp ]);
83
84      console.log("Created table "+ table +", will expire in "+ (expiresTimestamp - new Date().getTime()) / 3600 +" hours.");
85    });
86  });
87};
88
89Drupal.HierarchicalSelect.cache.insertOnDuplicateKeyUpdate = function(table, row) {
90//  console.log("storing: value: "+ row.value +", label: "+ row.label +", parent: "+ row.parent +", weight: "+ row.weight);
91  Drupal.HierarchicalSelect.cache.db.transaction(function(tx) {
92    tx.executeSql("INSERT INTO "+ table +" (parent, value, label, weight) VALUES (?, ?, ?, ?)", [ row.parent, row.value, row.label, row.weight ], null, function(tx, error) {
93//      console.log("UPDATING value: "+ row.value +", label: "+ row.label +", parent: "+ row.parent +", weight: "+ row.weight);
94      tx.executeSql("UPDATE "+ table +" SET parent = ?, label = ?, weight = ? WHERE value = ?", [ row.parent, row.label, row.weight, row.value ], null, function(tx, error) {
95//        console.log("sql error: " + error.message);
96      });
97    });
98  });
99};
100
101Drupal.HierarchicalSelect.cache.sync = function(hsid, info) {
102  var table = Drupal.HierarchicalSelect.cache.table(hsid);
103  for (var id in info) {
104    var closure = function(_info, id) {
105      Drupal.HierarchicalSelect.cache.insertOnDuplicateKeyUpdate(table, _info[id]);
106    } (info, id);
107  } 
108};
109
110Drupal.HierarchicalSelect.cache.hasChildren = function(hsid, value, successCallback, failCallback) {
111  var table = Drupal.HierarchicalSelect.cache.table(hsid);
112  Drupal.HierarchicalSelect.cache.db.transaction(function(tx) {
113    tx.executeSql("SELECT * FROM "+ table +" WHERE parent = ?", [ value ], function(tx, resultSet) {
114      if (resultSet.rows.length > 0) {
115        successCallback();
116      }
117      else {
118        failCallback();
119      }
120    });
121  });
122};
123
124Drupal.HierarchicalSelect.cache.getSubLevels = function(hsid, value, callback, previousSubLevels) {
125  var table = Drupal.HierarchicalSelect.cache.table(hsid);
126
127  var subLevels = new Array();
128  if (previousSubLevels != undefined) {
129    subLevels = previousSubLevels;
130  }
131
132  Drupal.HierarchicalSelect.cache.db.transaction(function(tx) {
133    tx.executeSql("SELECT value, label FROM "+ table +" WHERE parent = ? ORDER BY weight", [ value ], function(tx, resultSet) {
134      var numChildren = resultSet.rows.length;
135
136      // If there's only one child, check if it has the dummy "<value>-has-no-children" value.
137      if (numChildren == 1) {
138        var valueOfFirstRow = String(resultSet.rows.item(0).value);
139        var isDummy = valueOfFirstRow.match(/^.*-has-no-children$/);
140      }
141
142      // Only pass the children if there are any (and not a fake one either).
143      if (numChildren && !isDummy) {
144        var level = new Array();
145        for (var i = 0; i < resultSet.rows.length; i++) {
146          var row = resultSet.rows.item(i);
147          level[i] = { 'value' : row.value, 'label' : row.label };
148          console.log("child of "+ value +": ("+ row.value +", "+ row.label +")");
149        }
150
151        subLevels.push(level);
152
153        Drupal.HierarchicalSelect.cache.getSubLevels(hsid, level[0].value, callback, subLevels);
154      }
155      else {
156        if (subLevels.length > 0) {
157          callback(subLevels);
158        }
159        else {
160          callback(false);
161        }
162      }
163    });
164  });
165};
166
167Drupal.HierarchicalSelect.cache.createAndUpdateSelects = function(hsid, subLevels, lastUnchanged) {
168  // Remove all levels below the level in which a value was selected, if they
169  // exist.
170  // Note: the root level can never change because of this!
171  $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select').slice(lastUnchanged).remove();
172
173  // Create the new sublevels, by cloning the root level and then modifying
174  // that clone.
175  var $rootSelect = $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select:first');
176  for (var depth in subLevels) {
177    var optionElements = $.map(subLevels[depth], function(item) { return '<option value="'+ item.value +'">'+ item.label +'</option>'; });
178
179    var level = parseInt(lastUnchanged) + parseInt(depth);
180
181    $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select:last').after(
182      $rootSelect.clone()
183      // Update the name attribute.
184      .attr('name', $rootSelect.attr('name').replace(/(.*)\d+\]$/, "$1"+ level +"]"))
185      // Update the id attribute.
186      .attr('id', $rootSelect.attr('id').replace(/(.*-hierarchical-select-selects-)\d+/, "$1"+ level))
187      // Remove the existing options and set the new ones.
188      .empty().append(optionElements.join(''))
189    );
190  }
191};
192
193Drupal.HierarchicalSelect.cache.updateHierarchicalSelect = function(hsid, value, settings, lastUnchanged, ajaxOptions) {
194  // If the selected value has children
195  Drupal.HierarchicalSelect.cache.hasChildren(hsid, value, function() {
196    console.log("Cache hit.");
197    Drupal.HierarchicalSelect.cache.getSubLevels(hsid, value, function(subLevels) {
198      Drupal.HierarchicalSelect.preUpdateAnimations(hsid, 'update-hierarchical-select', lastUnchanged, function() {       
199        if (subLevels !== false) {
200          Drupal.HierarchicalSelect.cache.createAndUpdateSelects(hsid, subLevels, lastUnchanged);             
201        }
202        else {
203          // Nothing must happen: the user selected a value that doesn't
204          // have any subLevels.
205          $('#hierarchical-select-' + hsid + '-wrapper .hierarchical-select .selects select').slice(lastUnchanged).remove();
206        }
207
208        Drupal.HierarchicalSelect.postUpdateAnimations(hsid, 'update-hierarchical-select', lastUnchanged, function() {
209          // Reattach the bindings.
210          Drupal.HierarchicalSelect.attachBindings(hsid);
211
212          Drupal.HierarchicalSelect.triggerEvents(hsid, 'update-hierarchical-select', settings);
213
214          // The selection of this hierarchical select has changed!
215          Drupal.HierarchicalSelect.triggerEvents(hsid, 'change-hierarchical-select', settings);
216        });
217      });
218    });   
219  }, function() {
220    // This item was not yet requested before, so we still have to perform
221    // the dynamic form submit.
222    console.log("Cache miss. Querying the server.");
223    Drupal.HierarchicalSelect.preUpdateAnimations(hsid, 'update-hierarchical-select', lastUnchanged, function() {
224      $.ajax(ajaxOptions); 
225    });
226  });
227};
228
229})(jQuery);
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.