otsdaq_utilities  v2_05_02_indev
persistence.js
1 /* Tabulator v4.5.3 (c) Oliver Folkerd */
2 
3 var Persistence = function Persistence(table) {
4  this.table = table; //hold Tabulator object
5  this.mode = "";
6  this.id = "";
7  // this.persistProps = ["field", "width", "visible"];
8  this.defWatcherBlock = false;
9  this.config = {};
10  this.readFunc = false;
11  this.writeFunc = false;
12 };
13 
14 // Test for whether localStorage is available for use.
15 Persistence.prototype.localStorageTest = function () {
16  var testKey = "_tabulator_test";
17 
18  try {
19  window.localStorage.setItem(testKey, testKey);
20  window.localStorage.removeItem(testKey);
21  return true;
22  } catch (e) {
23  return false;
24  }
25 };
26 
27 //setup parameters
28 Persistence.prototype.initialize = function () {
29  //determine persistent layout storage type
30 
31  var mode = this.table.options.persistenceMode,
32  id = this.table.options.persistenceID,
33  retreivedData;
34 
35  this.mode = mode !== true ? mode : this.localStorageTest() ? "local" : "cookie";
36 
37  if (this.table.options.persistenceReaderFunc) {
38  if (typeof this.table.options.persistenceReaderFunc === "function") {
39  this.readFunc = this.table.options.persistenceReaderFunc;
40  } else {
41  if (this.readers[this.table.options.persistenceReaderFunc]) {
42  this.readFunc = this.readers[this.table.options.persistenceReaderFunc];
43  } else {
44  console.warn("Persistence Read Error - invalid reader set", this.table.options.persistenceReaderFunc);
45  }
46  }
47  } else {
48  if (this.readers[this.mode]) {
49  this.readFunc = this.readers[this.mode];
50  } else {
51  console.warn("Persistence Read Error - invalid reader set", this.mode);
52  }
53  }
54 
55  if (this.table.options.persistenceWriterFunc) {
56  if (typeof this.table.options.persistenceWriterFunc === "function") {
57  this.writeFunc = this.table.options.persistenceWriterFunc;
58  } else {
59  if (this.readers[this.table.options.persistenceWriterFunc]) {
60  this.writeFunc = this.readers[this.table.options.persistenceWriterFunc];
61  } else {
62  console.warn("Persistence Write Error - invalid reader set", this.table.options.persistenceWriterFunc);
63  }
64  }
65  } else {
66  if (this.writers[this.mode]) {
67  this.writeFunc = this.writers[this.mode];
68  } else {
69  console.warn("Persistence Write Error - invalid writer set", this.mode);
70  }
71  }
72 
73  //set storage tag
74  this.id = "tabulator-" + (id || this.table.element.getAttribute("id") || "");
75 
76  this.config = {
77  sort: this.table.options.persistence === true || this.table.options.persistence.sort,
78  filter: this.table.options.persistence === true || this.table.options.persistence.filter,
79  group: this.table.options.persistence === true || this.table.options.persistence.group,
80  page: this.table.options.persistence === true || this.table.options.persistence.page,
81  columns: this.table.options.persistence === true ? ["title", "width", "visible"] : this.table.options.persistence.columns
82  };
83 
84  //load pagination data if needed
85  if (this.config.page) {
86  retreivedData = this.retreiveData("page");
87 
88  if (retreivedData) {
89  if (typeof retreivedData.paginationSize !== "undefined" && (this.config.page === true || this.config.page.size)) {
90  this.table.options.paginationSize = retreivedData.paginationSize;
91  }
92 
93  if (typeof retreivedData.paginationInitialPage !== "undefined" && (this.config.page === true || this.config.page.page)) {
94  this.table.options.paginationInitialPage = retreivedData.paginationInitialPage;
95  }
96  }
97  }
98 
99  //load group data if needed
100  if (this.config.group) {
101  retreivedData = this.retreiveData("group");
102 
103  if (retreivedData) {
104  if (typeof retreivedData.groupBy !== "undefined" && (this.config.group === true || this.config.group.groupBy)) {
105  this.table.options.groupBy = retreivedData.groupBy;
106  }
107  if (typeof retreivedData.groupStartOpen !== "undefined" && (this.config.group === true || this.config.group.groupStartOpen)) {
108  this.table.options.groupStartOpen = retreivedData.groupStartOpen;
109  }
110  if (typeof retreivedData.groupHeader !== "undefined" && (this.config.group === true || this.config.group.groupHeader)) {
111  this.table.options.groupHeader = retreivedData.groupHeader;
112  }
113  }
114  }
115 };
116 
117 Persistence.prototype.initializeColumn = function (column) {
118  var self = this,
119  def,
120  keys;
121 
122  if (this.config.columns) {
123  this.defWatcherBlock = true;
124 
125  def = column.getDefinition();
126 
127  keys = this.config.columns === true ? Object.keys(def) : this.config.columns;
128 
129  keys.forEach(function (key) {
130  var props = Object.getOwnPropertyDescriptor(def, key);
131  var value = def[key];
132  if (props) {
133  Object.defineProperty(def, key, {
134  set: function set(newValue) {
135  value = newValue;
136 
137  if (!self.defWatcherBlock) {
138  self.save("columns");
139  }
140 
141  if (props.set) {
142  props.set(newValue);
143  }
144  },
145  get: function get() {
146  if (props.get) {
147  props.get();
148  }
149  return value;
150  }
151  });
152  }
153  });
154 
155  this.defWatcherBlock = false;
156  }
157 };
158 
159 //load saved definitions
160 Persistence.prototype.load = function (type, current) {
161  var data = this.retreiveData(type);
162 
163  if (current) {
164  data = data ? this.mergeDefinition(current, data) : current;
165  }
166 
167  return data;
168 };
169 
170 //retreive data from memory
171 Persistence.prototype.retreiveData = function (type) {
172  return this.readFunc ? this.readFunc(this.id, type) : false;
173 };
174 
175 //merge old and new column definitions
176 Persistence.prototype.mergeDefinition = function (oldCols, newCols) {
177  var self = this,
178  output = [];
179 
180  // oldCols = oldCols || [];
181  newCols = newCols || [];
182 
183  newCols.forEach(function (column, to) {
184 
185  var from = self._findColumn(oldCols, column),
186  keys;
187 
188  if (from) {
189 
190  if (self.config.columns === true || self.config.columns == undefined) {
191  keys = Object.keys(from);
192  keys.push("width");
193  } else {
194  keys = self.config.columns;
195  }
196 
197  keys.forEach(function (key) {
198  if (typeof column[key] !== "undefined") {
199  from[key] = column[key];
200  }
201  });
202 
203  if (from.columns) {
204  from.columns = self.mergeDefinition(from.columns, column.columns);
205  }
206 
207  output.push(from);
208  }
209  });
210 
211  oldCols.forEach(function (column, i) {
212  var from = self._findColumn(newCols, column);
213  if (!from) {
214  if (output.length > i) {
215  output.splice(i, 0, column);
216  } else {
217  output.push(column);
218  }
219  }
220  });
221 
222  return output;
223 };
224 
225 //find matching columns
226 Persistence.prototype._findColumn = function (columns, subject) {
227  var type = subject.columns ? "group" : subject.field ? "field" : "object";
228 
229  return columns.find(function (col) {
230  switch (type) {
231  case "group":
232  return col.title === subject.title && col.columns.length === subject.columns.length;
233  break;
234 
235  case "field":
236  return col.field === subject.field;
237  break;
238 
239  case "object":
240  return col === subject;
241  break;
242  }
243  });
244 };
245 
246 //save data
247 Persistence.prototype.save = function (type) {
248  var data = {};
249 
250  switch (type) {
251  case "columns":
252  data = this.parseColumns(this.table.columnManager.getColumns());
253  break;
254 
255  case "filter":
256  data = this.table.modules.filter.getFilters();
257  break;
258 
259  case "sort":
260  data = this.validateSorters(this.table.modules.sort.getSort());
261  break;
262 
263  case "group":
264  data = this.getGroupConfig();
265  break;
266 
267  case "page":
268  data = this.getPageConfig();
269  break;
270  }
271 
272  if (this.writeFunc) {
273  this.writeFunc(this.id, type, data);
274  }
275 };
276 
277 //ensure sorters contain no function data
278 Persistence.prototype.validateSorters = function (data) {
279  data.forEach(function (item) {
280  item.column = item.field;
281  delete item.field;
282  });
283 
284  return data;
285 };
286 
287 Persistence.prototype.getGroupConfig = function () {
288  if (this.config.group) {
289  if (this.config.group === true || this.config.group.groupBy) {
290  data.groupBy = this.table.options.groupBy;
291  }
292 
293  if (this.config.group === true || this.config.group.groupStartOpen) {
294  data.groupStartOpen = this.table.options.groupStartOpen;
295  }
296 
297  if (this.config.group === true || this.config.group.groupHeader) {
298  data.groupHeader = this.table.options.groupHeader;
299  }
300  }
301 
302  return data;
303 };
304 
305 Persistence.prototype.getPageConfig = function () {
306  var data = {};
307 
308  if (this.config.page) {
309  if (this.config.page === true || this.config.page.size) {
310  data.paginationSize = this.table.modules.page.getPageSize();
311  }
312 
313  if (this.config.page === true || this.config.page.page) {
314  data.paginationInitialPage = this.table.modules.page.getPage();
315  }
316  }
317 
318  return data;
319 };
320 
321 //parse columns for data to store
322 Persistence.prototype.parseColumns = function (columns) {
323  var self = this,
324  definitions = [];
325 
326  columns.forEach(function (column) {
327  var defStore = {},
328  colDef = column.getDefinition(),
329  keys;
330 
331  if (column.isGroup) {
332  defStore.title = colDef.title;
333  defStore.columns = self.parseColumns(column.getColumns());
334  } else {
335  defStore.field = column.getField();
336 
337  if (self.config.columns === true || self.config.columns == undefined) {
338  keys = Object.keys(colDef);
339  keys.push("width");
340  } else {
341  keys = self.config.columns;
342  }
343 
344  keys.forEach(function (key) {
345 
346  switch (key) {
347  case "width":
348  defStore.width = column.getWidth();
349  break;
350  case "visible":
351  defStore.visible = column.visible;
352  break;
353 
354  default:
355  defStore[key] = colDef[key];
356  }
357  });
358  }
359 
360  definitions.push(defStore);
361  });
362 
363  return definitions;
364 };
365 
366 // read peristence information from storage
367 Persistence.prototype.readers = {
368  local: function local(id, type) {
369  var data = localStorage.getItem(id + "-" + type);
370 
371  return data ? JSON.parse(data) : false;
372  },
373  cookie: function cookie(id, type) {
374  var cookie = document.cookie,
375  key = id + "-" + type,
376  cookiePos = cookie.indexOf(key + "="),
377  end;
378 
379  //if cookie exists, decode and load column data into tabulator
380  if (cookiePos > -1) {
381  cookie = cookie.substr(cookiePos);
382 
383  end = cookie.indexOf(";");
384 
385  if (end > -1) {
386  cookie = cookie.substr(0, end);
387  }
388 
389  data = cookie.replace(key + "=", "");
390  }
391 
392  return data ? JSON.parse(data) : false;
393  }
394 };
395 
396 //write persistence information to storage
397 Persistence.prototype.writers = {
398  local: function local(id, type, data) {
399  localStorage.setItem(id + "-" + type, JSON.stringify(data));
400  },
401  cookie: function cookie(id, type, data) {
402  var expireDate = new Date();
403 
404  expireDate.setDate(expireDate.getDate() + 10000);
405 
406  document.cookie = id + "_" + type + "=" + JSON.stringify(data) + "; expires=" + expireDate.toUTCString();
407  }
408 };
409 
410 Tabulator.prototype.registerModule("persistence", Persistence);