3 var Page =
function Page(table) {
8 this.progressiveLoad =
false;
15 this.displayIndex = 0;
19 this.createElements();
22 Page.prototype.createElements =
function () {
26 this.element = document.createElement(
"span");
27 this.element.classList.add(
"tabulator-paginator");
29 this.pagesElement = document.createElement(
"span");
30 this.pagesElement.classList.add(
"tabulator-pages");
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",
"");
39 this.firstBut = button.cloneNode(
true);
40 this.firstBut.setAttribute(
"data-page",
"first");
42 this.prevBut = button.cloneNode(
true);
43 this.prevBut.setAttribute(
"data-page",
"prev");
45 this.nextBut = button.cloneNode(
true);
46 this.nextBut.setAttribute(
"data-page",
"next");
48 this.lastBut = button.cloneNode(
true);
49 this.lastBut.setAttribute(
"data-page",
"last");
51 if (this.table.options.paginationSizeSelector) {
52 this.pageSizeSelect = document.createElement(
"select");
53 this.pageSizeSelect.classList.add(
"tabulator-page-size");
57 Page.prototype.generatePageSizeSelectList =
function () {
62 if (this.pageSizeSelect) {
64 if (Array.isArray(
this.table.options.paginationSizeSelector)) {
65 pageSizes = this.table.options.paginationSizeSelector;
66 this.pageSizes = pageSizes;
68 if (this.pageSizes.indexOf(
this.size) == -1) {
69 pageSizes.unshift(this.size);
73 if (this.pageSizes.indexOf(
this.size) == -1) {
76 for (var i = 1; i < 5; i++) {
77 pageSizes.push(this.size * i);
80 this.pageSizes = pageSizes;
82 pageSizes = this.pageSizes;
86 while (this.pageSizeSelect.firstChild) {
87 this.pageSizeSelect.removeChild(this.pageSizeSelect.firstChild);
88 }pageSizes.forEach(
function (item) {
89 var itemEl = document.createElement(
"option");
91 itemEl.innerHTML = item;
93 _this.pageSizeSelect.appendChild(itemEl);
96 this.pageSizeSelect.value = this.size;
101 Page.prototype.initialize =
function (hidden) {
106 for (var key in
self.table.options.paginationDataSent) {
107 self.paginationDataSentNames[key] =
self.table.options.paginationDataSent[key];
110 for (var _key in
self.table.options.paginationDataReceived) {
111 self.paginationDataReceivedNames[_key] =
self.table.options.paginationDataReceived[_key];
117 self.table.modules.localize.bind(
"pagination|first",
function (value) {
118 self.firstBut.innerHTML = value;
121 self.table.modules.localize.bind(
"pagination|first_title",
function (value) {
122 self.firstBut.setAttribute(
"aria-label", value);
123 self.firstBut.setAttribute(
"title", value);
126 self.table.modules.localize.bind(
"pagination|prev",
function (value) {
127 self.prevBut.innerHTML = value;
130 self.table.modules.localize.bind(
"pagination|prev_title",
function (value) {
131 self.prevBut.setAttribute(
"aria-label", value);
132 self.prevBut.setAttribute(
"title", value);
135 self.table.modules.localize.bind(
"pagination|next",
function (value) {
136 self.nextBut.innerHTML = value;
139 self.table.modules.localize.bind(
"pagination|next_title",
function (value) {
140 self.nextBut.setAttribute(
"aria-label", value);
141 self.nextBut.setAttribute(
"title", value);
144 self.table.modules.localize.bind(
"pagination|last",
function (value) {
145 self.lastBut.innerHTML = value;
148 self.table.modules.localize.bind(
"pagination|last_title",
function (value) {
149 self.lastBut.setAttribute(
"aria-label", value);
150 self.lastBut.setAttribute(
"title", value);
154 self.firstBut.addEventListener(
"click",
function () {
158 self.prevBut.addEventListener(
"click",
function () {
162 self.nextBut.addEventListener(
"click",
function () {
163 self.nextPage().then(
function () {}).
catch(
function () {});
166 self.lastBut.addEventListener(
"click",
function () {
167 self.setPage(
self.max);
170 if (
self.table.options.paginationElement) {
171 self.element =
self.table.options.paginationElement;
174 if (this.pageSizeSelect) {
175 pageSelectLabel = document.createElement(
"label");
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;
183 self.element.appendChild(pageSelectLabel);
184 self.element.appendChild(
self.pageSizeSelect);
186 self.pageSizeSelect.addEventListener(
"change",
function (e) {
187 self.setPageSize(
self.pageSizeSelect.value);
188 self.setPage(1).then(
function () {}).
catch(
function () {});
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);
199 if (!
self.table.options.paginationElement && !hidden) {
200 self.table.footerManager.append(
self.element,
self);
204 self.mode =
self.table.options.pagination;
206 self.size =
self.table.options.paginationSize || Math.floor(
self.table.rowManager.getElement().clientHeight / 24);
208 self.count =
self.table.options.paginationButtonCount;
210 self.generatePageSizeSelectList();
213 Page.prototype.initializeProgressive =
function (mode) {
214 this.initialize(
true);
215 this.mode =
"progressive_" + mode;
216 this.progressiveLoad =
true;
219 Page.prototype.setDisplayIndex =
function (index) {
220 this.displayIndex = index;
223 Page.prototype.getDisplayIndex =
function () {
224 return this.displayIndex;
228 Page.prototype.setMaxRows =
function (rowCount) {
232 this.max = Math.ceil(rowCount / this.size);
235 if (this.page > this.max) {
236 this.page = this.max;
241 Page.prototype.reset =
function (force) {
242 if (this.mode ==
"local" || force) {
249 Page.prototype.setMaxPage =
function (max) {
255 if (this.page > this.max) {
256 this.page = this.max;
262 Page.prototype.setPage =
function (page) {
267 return new Promise(
function (resolve, reject) {
269 page = parseInt(page);
271 if (page > 0 && page <= _this2.max) {
273 _this2.trigger().then(
function () {
275 }).
catch(
function () {
279 if (
self.table.options.persistence &&
self.table.modExists(
"persistence",
true) &&
self.table.modules.persistence.config.page) {
280 self.table.modules.persistence.save(
"page");
283 console.warn(
"Pagination Error - Requested page is out of range of 1 - " + _this2.max +
":", page);
289 Page.prototype.setPageToRow =
function (row) {
292 return new Promise(
function (resolve, reject) {
294 var rows = _this3.table.rowManager.getDisplayRows(_this3.displayIndex - 1);
295 var index = rows.indexOf(row);
298 var page = Math.ceil((index + 1) / _this3.size);
300 _this3.setPage(page).then(
function () {
302 }).
catch(
function () {
306 console.warn(
"Pagination Error - Requested row is not visible");
312 Page.prototype.setPageSize =
function (size) {
313 size = parseInt(size);
319 if (this.pageSizeSelect) {
321 this.generatePageSizeSelectList();
324 if (this.table.options.persistence &&
this.table.modExists(
"persistence",
true) && this.table.modules.persistence.config.page) {
325 this.table.modules.persistence.save(
"page");
330 Page.prototype._setPageButtons =
function () {
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);
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;
344 self.firstBut.disabled =
false;
345 self.prevBut.disabled =
false;
348 if (
self.page ==
self.max) {
349 self.lastBut.disabled =
true;
350 self.nextBut.disabled =
true;
352 self.lastBut.disabled =
false;
353 self.nextBut.disabled =
false;
356 for (var i = min; i <= max; i++) {
357 if (i > 0 && i <=
self.max) {
358 self.pagesElement.appendChild(
self._generatePageButton(i));
365 Page.prototype._generatePageButton =
function (page) {
367 button = document.createElement(
"button");
369 button.classList.add(
"tabulator-page");
370 if (page ==
self.page) {
371 button.classList.add(
"active");
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;
381 button.addEventListener(
"click",
function (e) {
389 Page.prototype.previousPage =
function () {
392 return new Promise(
function (resolve, reject) {
393 if (_this4.page > 1) {
395 _this4.trigger().then(
function () {
397 }).
catch(
function () {
401 console.warn(
"Pagination Error - Previous page would be less than page 1:", 0);
408 Page.prototype.nextPage =
function () {
411 return new Promise(
function (resolve, reject) {
412 if (_this5.page < _this5.max) {
414 _this5.trigger().then(
function () {
416 }).
catch(
function () {
420 if (!_this5.progressiveLoad) {
421 console.warn(
"Pagination Error - Next page would be greater than maximum page of " + _this5.max +
":", _this5.max + 1);
429 Page.prototype.getPage =
function () {
434 Page.prototype.getPageMax =
function () {
438 Page.prototype.getPageSize =
function (size) {
442 Page.prototype.getMode =
function () {
447 Page.prototype.getRows =
function (data) {
448 var output, start, end;
450 if (this.mode ==
"local") {
452 start = this.size * (this.page - 1);
453 end = start + parseInt(this.size);
455 this._setPageButtons();
457 for (var i = start; i < end; i++) {
459 output.push(data[i]);
466 this._setPageButtons();
468 return data.slice(0);
472 Page.prototype.trigger =
function () {
477 return new Promise(
function (resolve, reject) {
479 switch (_this6.mode) {
481 left = _this6.table.rowManager.scrollLeft;
483 _this6.table.rowManager.refreshActiveData(
"page");
484 _this6.table.rowManager.scrollHorizontal(left);
486 _this6.table.options.pageLoaded.call(_this6.table, _this6.getPage());
491 case "progressive_load":
492 case "progressive_scroll":
493 _this6.table.modules.ajax.blockActiveRequest();
494 _this6._getRemotePage().then(
function () {
496 }).
catch(
function () {
502 console.warn(
"Pagination Error - no such pagination mode:", _this6.mode);
508 Page.prototype._getRemotePage =
function () {
515 return new Promise(
function (resolve, reject) {
517 if (!
self.table.modExists(
"ajax",
true)) {
522 oldParams = Tabulator.prototype.helpers.deepClone(
self.table.modules.ajax.getParams() || {});
523 pageParams =
self.table.modules.ajax.getParams();
526 pageParams[_this7.paginationDataSentNames.page] =
self.page;
530 pageParams[_this7.paginationDataSentNames.size] = _this7.size;
534 if (_this7.table.options.ajaxSorting && _this7.table.modExists(
"sort")) {
535 var sorters =
self.table.modules.sort.getSort();
537 sorters.forEach(
function (item) {
541 pageParams[_this7.paginationDataSentNames.sorters] = sorters;
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;
550 self.table.modules.ajax.setParams(pageParams);
552 self.table.modules.ajax.sendRequest(_this7.progressiveLoad).then(
function (data) {
553 self._parseRemoteData(data);
555 }).
catch(
function (e) {
559 self.table.modules.ajax.setParams(oldParams);
563 Page.prototype._parseRemoteData =
function (data) {
569 if (typeof data[this.paginationDataReceivedNames.last_page] ===
"undefined") {
570 console.warn(
"Remote Pagination Error - Server response missing '" + this.paginationDataReceivedNames.last_page +
"' property");
573 if (data[this.paginationDataReceivedNames.data]) {
574 this.max = parseInt(data[this.paginationDataReceivedNames.last_page]) || 1;
576 if (this.progressiveLoad) {
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);
587 case "progressive_scroll":
588 data = this.table.rowManager.getData().concat(data[this.paginationDataReceivedNames.data]);
590 this.table.rowManager.setData(data,
true);
592 margin = this.table.options.ajaxProgressiveLoadScrollMargin || this.table.rowManager.element.clientHeight * 2;
594 if (
self.table.rowManager.element.scrollHeight <=
self.table.rowManager.element.clientHeight + margin) {
595 self.nextPage().then(
function () {}).
catch(
function () {});
600 left = this.table.rowManager.scrollLeft;
602 this.table.rowManager.setData(data[this.paginationDataReceivedNames.data]);
604 this.table.rowManager.scrollHorizontal(left);
606 this.table.columnManager.scrollHorizontal(left);
608 this.table.options.pageLoaded.call(this.table, this.getPage());
611 console.warn(
"Remote Pagination Error - Server response missing '" + this.paginationDataReceivedNames.data +
"' property");
616 Page.prototype.footerRedraw =
function () {
617 var footer = this.table.footerManager.element;
619 if (Math.ceil(footer.clientWidth) - footer.scrollWidth < 0) {
620 this.pagesElement.style.display =
'none';
622 this.pagesElement.style.display =
'';
624 if (Math.ceil(footer.clientWidth) - footer.scrollWidth < 0) {
625 this.pagesElement.style.display =
'none';
631 Page.prototype.paginationDataSentNames = {
634 "sorters":
"sorters",
642 Page.prototype.paginationDataReceivedNames = {
643 "current_page":
"current_page",
644 "last_page":
"last_page",
648 Tabulator.prototype.registerModule(
"page", Page);