otsdaq_utilities  v2_05_02_indev
page.js
1 /* Tabulator v4.5.3 (c) Oliver Folkerd */
2 
3 var Page = function Page(table) {
4 
5  this.table = table; //hold Tabulator object
6 
7  this.mode = "local";
8  this.progressiveLoad = false;
9 
10  this.size = 0;
11  this.page = 1;
12  this.count = 5;
13  this.max = 1;
14 
15  this.displayIndex = 0; //index in display pipeline
16 
17  this.pageSizes = [];
18 
19  this.createElements();
20 };
21 
22 Page.prototype.createElements = function () {
23 
24  var button;
25 
26  this.element = document.createElement("span");
27  this.element.classList.add("tabulator-paginator");
28 
29  this.pagesElement = document.createElement("span");
30  this.pagesElement.classList.add("tabulator-pages");
31 
32  button = document.createElement("button");
33  button.classList.add("tabulator-page");
34  button.setAttribute("type", "button");
35  button.setAttribute("role", "button");
36  button.setAttribute("aria-label", "");
37  button.setAttribute("title", "");
38 
39  this.firstBut = button.cloneNode(true);
40  this.firstBut.setAttribute("data-page", "first");
41 
42  this.prevBut = button.cloneNode(true);
43  this.prevBut.setAttribute("data-page", "prev");
44 
45  this.nextBut = button.cloneNode(true);
46  this.nextBut.setAttribute("data-page", "next");
47 
48  this.lastBut = button.cloneNode(true);
49  this.lastBut.setAttribute("data-page", "last");
50 
51  if (this.table.options.paginationSizeSelector) {
52  this.pageSizeSelect = document.createElement("select");
53  this.pageSizeSelect.classList.add("tabulator-page-size");
54  }
55 };
56 
57 Page.prototype.generatePageSizeSelectList = function () {
58  var _this = this;
59 
60  var pageSizes = [];
61 
62  if (this.pageSizeSelect) {
63 
64  if (Array.isArray(this.table.options.paginationSizeSelector)) {
65  pageSizes = this.table.options.paginationSizeSelector;
66  this.pageSizes = pageSizes;
67 
68  if (this.pageSizes.indexOf(this.size) == -1) {
69  pageSizes.unshift(this.size);
70  }
71  } else {
72 
73  if (this.pageSizes.indexOf(this.size) == -1) {
74  pageSizes = [];
75 
76  for (var i = 1; i < 5; i++) {
77  pageSizes.push(this.size * i);
78  }
79 
80  this.pageSizes = pageSizes;
81  } else {
82  pageSizes = this.pageSizes;
83  }
84  }
85 
86  while (this.pageSizeSelect.firstChild) {
87  this.pageSizeSelect.removeChild(this.pageSizeSelect.firstChild);
88  }pageSizes.forEach(function (item) {
89  var itemEl = document.createElement("option");
90  itemEl.value = item;
91  itemEl.innerHTML = item;
92 
93  _this.pageSizeSelect.appendChild(itemEl);
94  });
95 
96  this.pageSizeSelect.value = this.size;
97  }
98 };
99 
100 //setup pageination
101 Page.prototype.initialize = function (hidden) {
102  var self = this,
103  pageSelectLabel;
104 
105  //update param names
106  for (var key in self.table.options.paginationDataSent) {
107  self.paginationDataSentNames[key] = self.table.options.paginationDataSent[key];
108  }
109 
110  for (var _key in self.table.options.paginationDataReceived) {
111  self.paginationDataReceivedNames[_key] = self.table.options.paginationDataReceived[_key];
112  }
113 
114  //build pagination element
115 
116  //bind localizations
117  self.table.modules.localize.bind("pagination|first", function (value) {
118  self.firstBut.innerHTML = value;
119  });
120 
121  self.table.modules.localize.bind("pagination|first_title", function (value) {
122  self.firstBut.setAttribute("aria-label", value);
123  self.firstBut.setAttribute("title", value);
124  });
125 
126  self.table.modules.localize.bind("pagination|prev", function (value) {
127  self.prevBut.innerHTML = value;
128  });
129 
130  self.table.modules.localize.bind("pagination|prev_title", function (value) {
131  self.prevBut.setAttribute("aria-label", value);
132  self.prevBut.setAttribute("title", value);
133  });
134 
135  self.table.modules.localize.bind("pagination|next", function (value) {
136  self.nextBut.innerHTML = value;
137  });
138 
139  self.table.modules.localize.bind("pagination|next_title", function (value) {
140  self.nextBut.setAttribute("aria-label", value);
141  self.nextBut.setAttribute("title", value);
142  });
143 
144  self.table.modules.localize.bind("pagination|last", function (value) {
145  self.lastBut.innerHTML = value;
146  });
147 
148  self.table.modules.localize.bind("pagination|last_title", function (value) {
149  self.lastBut.setAttribute("aria-label", value);
150  self.lastBut.setAttribute("title", value);
151  });
152 
153  //click bindings
154  self.firstBut.addEventListener("click", function () {
155  self.setPage(1);
156  });
157 
158  self.prevBut.addEventListener("click", function () {
159  self.previousPage();
160  });
161 
162  self.nextBut.addEventListener("click", function () {
163  self.nextPage().then(function () {}).catch(function () {});
164  });
165 
166  self.lastBut.addEventListener("click", function () {
167  self.setPage(self.max);
168  });
169 
170  if (self.table.options.paginationElement) {
171  self.element = self.table.options.paginationElement;
172  }
173 
174  if (this.pageSizeSelect) {
175  pageSelectLabel = document.createElement("label");
176 
177  self.table.modules.localize.bind("pagination|page_size", function (value) {
178  self.pageSizeSelect.setAttribute("aria-label", value);
179  self.pageSizeSelect.setAttribute("title", value);
180  pageSelectLabel.innerHTML = value;
181  });
182 
183  self.element.appendChild(pageSelectLabel);
184  self.element.appendChild(self.pageSizeSelect);
185 
186  self.pageSizeSelect.addEventListener("change", function (e) {
187  self.setPageSize(self.pageSizeSelect.value);
188  self.setPage(1).then(function () {}).catch(function () {});
189  });
190  }
191 
192  //append to DOM
193  self.element.appendChild(self.firstBut);
194  self.element.appendChild(self.prevBut);
195  self.element.appendChild(self.pagesElement);
196  self.element.appendChild(self.nextBut);
197  self.element.appendChild(self.lastBut);
198 
199  if (!self.table.options.paginationElement && !hidden) {
200  self.table.footerManager.append(self.element, self);
201  }
202 
203  //set default values
204  self.mode = self.table.options.pagination;
205 
206  self.size = self.table.options.paginationSize || Math.floor(self.table.rowManager.getElement().clientHeight / 24);
207  // self.page = self.table.options.paginationInitialPage || 1;
208  self.count = self.table.options.paginationButtonCount;
209 
210  self.generatePageSizeSelectList();
211 };
212 
213 Page.prototype.initializeProgressive = function (mode) {
214  this.initialize(true);
215  this.mode = "progressive_" + mode;
216  this.progressiveLoad = true;
217 };
218 
219 Page.prototype.setDisplayIndex = function (index) {
220  this.displayIndex = index;
221 };
222 
223 Page.prototype.getDisplayIndex = function () {
224  return this.displayIndex;
225 };
226 
227 //calculate maximum page from number of rows
228 Page.prototype.setMaxRows = function (rowCount) {
229  if (!rowCount) {
230  this.max = 1;
231  } else {
232  this.max = Math.ceil(rowCount / this.size);
233  }
234 
235  if (this.page > this.max) {
236  this.page = this.max;
237  }
238 };
239 
240 //reset to first page without triggering action
241 Page.prototype.reset = function (force) {
242  if (this.mode == "local" || force) {
243  this.page = 1;
244  }
245  return true;
246 };
247 
248 //set the maxmum page
249 Page.prototype.setMaxPage = function (max) {
250 
251  max = parseInt(max);
252 
253  this.max = max || 1;
254 
255  if (this.page > this.max) {
256  this.page = this.max;
257  this.trigger();
258  }
259 };
260 
261 //set current page number
262 Page.prototype.setPage = function (page) {
263  var _this2 = this;
264 
265  var self = this;
266 
267  return new Promise(function (resolve, reject) {
268 
269  page = parseInt(page);
270 
271  if (page > 0 && page <= _this2.max) {
272  _this2.page = page;
273  _this2.trigger().then(function () {
274  resolve();
275  }).catch(function () {
276  reject();
277  });
278 
279  if (self.table.options.persistence && self.table.modExists("persistence", true) && self.table.modules.persistence.config.page) {
280  self.table.modules.persistence.save("page");
281  }
282  } else {
283  console.warn("Pagination Error - Requested page is out of range of 1 - " + _this2.max + ":", page);
284  reject();
285  }
286  });
287 };
288 
289 Page.prototype.setPageToRow = function (row) {
290  var _this3 = this;
291 
292  return new Promise(function (resolve, reject) {
293 
294  var rows = _this3.table.rowManager.getDisplayRows(_this3.displayIndex - 1);
295  var index = rows.indexOf(row);
296 
297  if (index > -1) {
298  var page = Math.ceil((index + 1) / _this3.size);
299 
300  _this3.setPage(page).then(function () {
301  resolve();
302  }).catch(function () {
303  reject();
304  });
305  } else {
306  console.warn("Pagination Error - Requested row is not visible");
307  reject();
308  }
309  });
310 };
311 
312 Page.prototype.setPageSize = function (size) {
313  size = parseInt(size);
314 
315  if (size > 0) {
316  this.size = size;
317  }
318 
319  if (this.pageSizeSelect) {
320  // this.pageSizeSelect.value = size;
321  this.generatePageSizeSelectList();
322  }
323 
324  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.page) {
325  this.table.modules.persistence.save("page");
326  }
327 };
328 
329 //setup the pagination buttons
330 Page.prototype._setPageButtons = function () {
331  var self = this;
332 
333  var leftSize = Math.floor((this.count - 1) / 2);
334  var rightSize = Math.ceil((this.count - 1) / 2);
335  var min = this.max - this.page + leftSize + 1 < this.count ? this.max - this.count + 1 : Math.max(this.page - leftSize, 1);
336  var max = this.page <= rightSize ? Math.min(this.count, this.max) : Math.min(this.page + rightSize, this.max);
337 
338  while (self.pagesElement.firstChild) {
339  self.pagesElement.removeChild(self.pagesElement.firstChild);
340  }if (self.page == 1) {
341  self.firstBut.disabled = true;
342  self.prevBut.disabled = true;
343  } else {
344  self.firstBut.disabled = false;
345  self.prevBut.disabled = false;
346  }
347 
348  if (self.page == self.max) {
349  self.lastBut.disabled = true;
350  self.nextBut.disabled = true;
351  } else {
352  self.lastBut.disabled = false;
353  self.nextBut.disabled = false;
354  }
355 
356  for (var i = min; i <= max; i++) {
357  if (i > 0 && i <= self.max) {
358  self.pagesElement.appendChild(self._generatePageButton(i));
359  }
360  }
361 
362  this.footerRedraw();
363 };
364 
365 Page.prototype._generatePageButton = function (page) {
366  var self = this,
367  button = document.createElement("button");
368 
369  button.classList.add("tabulator-page");
370  if (page == self.page) {
371  button.classList.add("active");
372  }
373 
374  button.setAttribute("type", "button");
375  button.setAttribute("role", "button");
376  button.setAttribute("aria-label", "Show Page " + page);
377  button.setAttribute("title", "Show Page " + page);
378  button.setAttribute("data-page", page);
379  button.textContent = page;
380 
381  button.addEventListener("click", function (e) {
382  self.setPage(page);
383  });
384 
385  return button;
386 };
387 
388 //previous page
389 Page.prototype.previousPage = function () {
390  var _this4 = this;
391 
392  return new Promise(function (resolve, reject) {
393  if (_this4.page > 1) {
394  _this4.page--;
395  _this4.trigger().then(function () {
396  resolve();
397  }).catch(function () {
398  reject();
399  });
400  } else {
401  console.warn("Pagination Error - Previous page would be less than page 1:", 0);
402  reject();
403  }
404  });
405 };
406 
407 //next page
408 Page.prototype.nextPage = function () {
409  var _this5 = this;
410 
411  return new Promise(function (resolve, reject) {
412  if (_this5.page < _this5.max) {
413  _this5.page++;
414  _this5.trigger().then(function () {
415  resolve();
416  }).catch(function () {
417  reject();
418  });
419  } else {
420  if (!_this5.progressiveLoad) {
421  console.warn("Pagination Error - Next page would be greater than maximum page of " + _this5.max + ":", _this5.max + 1);
422  }
423  reject();
424  }
425  });
426 };
427 
428 //return current page number
429 Page.prototype.getPage = function () {
430  return this.page;
431 };
432 
433 //return max page number
434 Page.prototype.getPageMax = function () {
435  return this.max;
436 };
437 
438 Page.prototype.getPageSize = function (size) {
439  return this.size;
440 };
441 
442 Page.prototype.getMode = function () {
443  return this.mode;
444 };
445 
446 //return appropriate rows for current page
447 Page.prototype.getRows = function (data) {
448  var output, start, end;
449 
450  if (this.mode == "local") {
451  output = [];
452  start = this.size * (this.page - 1);
453  end = start + parseInt(this.size);
454 
455  this._setPageButtons();
456 
457  for (var i = start; i < end; i++) {
458  if (data[i]) {
459  output.push(data[i]);
460  }
461  }
462 
463  return output;
464  } else {
465 
466  this._setPageButtons();
467 
468  return data.slice(0);
469  }
470 };
471 
472 Page.prototype.trigger = function () {
473  var _this6 = this;
474 
475  var left;
476 
477  return new Promise(function (resolve, reject) {
478 
479  switch (_this6.mode) {
480  case "local":
481  left = _this6.table.rowManager.scrollLeft;
482 
483  _this6.table.rowManager.refreshActiveData("page");
484  _this6.table.rowManager.scrollHorizontal(left);
485 
486  _this6.table.options.pageLoaded.call(_this6.table, _this6.getPage());
487  resolve();
488  break;
489 
490  case "remote":
491  case "progressive_load":
492  case "progressive_scroll":
493  _this6.table.modules.ajax.blockActiveRequest();
494  _this6._getRemotePage().then(function () {
495  resolve();
496  }).catch(function () {
497  reject();
498  });
499  break;
500 
501  default:
502  console.warn("Pagination Error - no such pagination mode:", _this6.mode);
503  reject();
504  }
505  });
506 };
507 
508 Page.prototype._getRemotePage = function () {
509  var _this7 = this;
510 
511  var self = this,
512  oldParams,
513  pageParams;
514 
515  return new Promise(function (resolve, reject) {
516 
517  if (!self.table.modExists("ajax", true)) {
518  reject();
519  }
520 
521  //record old params and restore after request has been made
522  oldParams = Tabulator.prototype.helpers.deepClone(self.table.modules.ajax.getParams() || {});
523  pageParams = self.table.modules.ajax.getParams();
524 
525  //configure request params
526  pageParams[_this7.paginationDataSentNames.page] = self.page;
527 
528  //set page size if defined
529  if (_this7.size) {
530  pageParams[_this7.paginationDataSentNames.size] = _this7.size;
531  }
532 
533  //set sort data if defined
534  if (_this7.table.options.ajaxSorting && _this7.table.modExists("sort")) {
535  var sorters = self.table.modules.sort.getSort();
536 
537  sorters.forEach(function (item) {
538  delete item.column;
539  });
540 
541  pageParams[_this7.paginationDataSentNames.sorters] = sorters;
542  }
543 
544  //set filter data if defined
545  if (_this7.table.options.ajaxFiltering && _this7.table.modExists("filter")) {
546  var filters = self.table.modules.filter.getFilters(true, true);
547  pageParams[_this7.paginationDataSentNames.filters] = filters;
548  }
549 
550  self.table.modules.ajax.setParams(pageParams);
551 
552  self.table.modules.ajax.sendRequest(_this7.progressiveLoad).then(function (data) {
553  self._parseRemoteData(data);
554  resolve();
555  }).catch(function (e) {
556  reject();
557  });
558 
559  self.table.modules.ajax.setParams(oldParams);
560  });
561 };
562 
563 Page.prototype._parseRemoteData = function (data) {
564  var self = this,
565  left,
566  data,
567  margin;
568 
569  if (typeof data[this.paginationDataReceivedNames.last_page] === "undefined") {
570  console.warn("Remote Pagination Error - Server response missing '" + this.paginationDataReceivedNames.last_page + "' property");
571  }
572 
573  if (data[this.paginationDataReceivedNames.data]) {
574  this.max = parseInt(data[this.paginationDataReceivedNames.last_page]) || 1;
575 
576  if (this.progressiveLoad) {
577  switch (this.mode) {
578  case "progressive_load":
579  this.table.rowManager.addRows(data[this.paginationDataReceivedNames.data]);
580  if (this.page < this.max) {
581  setTimeout(function () {
582  self.nextPage().then(function () {}).catch(function () {});
583  }, self.table.options.ajaxProgressiveLoadDelay);
584  }
585  break;
586 
587  case "progressive_scroll":
588  data = this.table.rowManager.getData().concat(data[this.paginationDataReceivedNames.data]);
589 
590  this.table.rowManager.setData(data, true);
591 
592  margin = this.table.options.ajaxProgressiveLoadScrollMargin || this.table.rowManager.element.clientHeight * 2;
593 
594  if (self.table.rowManager.element.scrollHeight <= self.table.rowManager.element.clientHeight + margin) {
595  self.nextPage().then(function () {}).catch(function () {});
596  }
597  break;
598  }
599  } else {
600  left = this.table.rowManager.scrollLeft;
601 
602  this.table.rowManager.setData(data[this.paginationDataReceivedNames.data]);
603 
604  this.table.rowManager.scrollHorizontal(left);
605 
606  this.table.columnManager.scrollHorizontal(left);
607 
608  this.table.options.pageLoaded.call(this.table, this.getPage());
609  }
610  } else {
611  console.warn("Remote Pagination Error - Server response missing '" + this.paginationDataReceivedNames.data + "' property");
612  }
613 };
614 
615 //handle the footer element being redrawn
616 Page.prototype.footerRedraw = function () {
617  var footer = this.table.footerManager.element;
618 
619  if (Math.ceil(footer.clientWidth) - footer.scrollWidth < 0) {
620  this.pagesElement.style.display = 'none';
621  } else {
622  this.pagesElement.style.display = '';
623 
624  if (Math.ceil(footer.clientWidth) - footer.scrollWidth < 0) {
625  this.pagesElement.style.display = 'none';
626  }
627  }
628 };
629 
630 //set the paramter names for pagination requests
631 Page.prototype.paginationDataSentNames = {
632  "page": "page",
633  "size": "size",
634  "sorters": "sorters",
635  // "sort_dir":"sort_dir",
636  "filters": "filters"
637  // "filter_value":"filter_value",
638  // "filter_type":"filter_type",
639 };
640 
641 //set the property names for pagination responses
642 Page.prototype.paginationDataReceivedNames = {
643  "current_page": "current_page",
644  "last_page": "last_page",
645  "data": "data"
646 };
647 
648 Tabulator.prototype.registerModule("page", Page);