tabulator-tables 5.0.9 → 5.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/.editorconfig +6 -0
  2. package/LICENSE +1 -1
  3. package/bower.json +1 -1
  4. package/build/rollup.js +2 -1
  5. package/dist/css/tabulator.css +26 -10
  6. package/dist/css/tabulator.css.map +1 -1
  7. package/dist/css/tabulator.min.css +1 -1
  8. package/dist/css/tabulator.min.css.map +1 -1
  9. package/dist/css/tabulator_bootstrap3.css +26 -10
  10. package/dist/css/tabulator_bootstrap3.css.map +1 -1
  11. package/dist/css/tabulator_bootstrap3.min.css +1 -1
  12. package/dist/css/tabulator_bootstrap3.min.css.map +1 -1
  13. package/dist/css/tabulator_bootstrap4.css +26 -10
  14. package/dist/css/tabulator_bootstrap4.css.map +1 -1
  15. package/dist/css/tabulator_bootstrap4.min.css +1 -1
  16. package/dist/css/tabulator_bootstrap4.min.css.map +1 -1
  17. package/dist/css/tabulator_bulma.css +26 -10
  18. package/dist/css/tabulator_bulma.css.map +1 -1
  19. package/dist/css/tabulator_bulma.min.css +1 -1
  20. package/dist/css/tabulator_bulma.min.css.map +1 -1
  21. package/dist/css/tabulator_materialize.css +33 -14
  22. package/dist/css/tabulator_materialize.css.map +1 -1
  23. package/dist/css/tabulator_materialize.min.css +1 -1
  24. package/dist/css/tabulator_materialize.min.css.map +1 -1
  25. package/dist/css/tabulator_midnight.css +30 -10
  26. package/dist/css/tabulator_midnight.css.map +1 -1
  27. package/dist/css/tabulator_midnight.min.css +1 -1
  28. package/dist/css/tabulator_midnight.min.css.map +1 -1
  29. package/dist/css/tabulator_modern.css +26 -10
  30. package/dist/css/tabulator_modern.css.map +1 -1
  31. package/dist/css/tabulator_modern.min.css +1 -1
  32. package/dist/css/tabulator_modern.min.css.map +1 -1
  33. package/dist/css/tabulator_semanticui.css +26 -10
  34. package/dist/css/tabulator_semanticui.css.map +1 -1
  35. package/dist/css/tabulator_semanticui.min.css +1 -1
  36. package/dist/css/tabulator_semanticui.min.css.map +1 -1
  37. package/dist/css/tabulator_simple.css +26 -10
  38. package/dist/css/tabulator_simple.css.map +1 -1
  39. package/dist/css/tabulator_simple.min.css +1 -1
  40. package/dist/css/tabulator_simple.min.css.map +1 -1
  41. package/dist/css/tabulator_site.css +30 -10
  42. package/dist/css/tabulator_site.css.map +1 -1
  43. package/dist/css/tabulator_site.min.css +1 -1
  44. package/dist/css/tabulator_site.min.css.map +1 -1
  45. package/dist/js/tabulator.js +1077 -530
  46. package/dist/js/tabulator.js.map +1 -1
  47. package/dist/js/tabulator.min.js +2 -2
  48. package/dist/js/tabulator.min.js.map +1 -1
  49. package/dist/js/tabulator_esm.js +1696 -1171
  50. package/dist/js/tabulator_esm.js.map +1 -1
  51. package/dist/js/tabulator_esm.min.js +2 -2
  52. package/dist/js/tabulator_esm.min.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/js/core/FooterManager.js +14 -2
  55. package/src/js/core/RowManager.js +318 -291
  56. package/src/js/core/Tabulator.js +8 -68
  57. package/src/js/core/cell/Cell.js +5 -1
  58. package/src/js/core/column/Column.js +20 -5
  59. package/src/js/core/column/ColumnComponent.js +6 -0
  60. package/src/js/core/column/defaults/options.js +1 -0
  61. package/src/js/core/defaults/options.js +2 -2
  62. package/src/js/core/modules/optional.js +1 -0
  63. package/src/js/core/rendering/Renderer.js +1 -1
  64. package/src/js/core/rendering/renderers/BasicVertical.js +2 -1
  65. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +165 -151
  66. package/src/js/core/row/Row.js +2 -2
  67. package/src/js/core/tools/DataLoader.js +5 -5
  68. package/src/js/core/tools/InteractionMonitor.js +63 -32
  69. package/src/js/core/tools/ModuleBinder.js +15 -3
  70. package/src/js/modules/Ajax/Ajax.js +62 -82
  71. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +3 -3
  72. package/src/js/modules/DataTree/DataTree.js +5 -1
  73. package/src/js/modules/Download/defaults/downloaders/json.js +1 -1
  74. package/src/js/modules/Download/defaults/downloaders/jsonLines.js +32 -0
  75. package/src/js/modules/Download/defaults/downloaders.js +2 -0
  76. package/src/js/modules/Edit/Edit.js +26 -31
  77. package/src/js/modules/Export/Export.js +2 -1
  78. package/src/js/modules/Filter/Filter.js +2 -3
  79. package/src/js/modules/Format/defaults/formatters/datetime.js +1 -1
  80. package/src/js/modules/Format/defaults/formatters/datetimediff.js +2 -1
  81. package/src/js/modules/Format/defaults/formatters/rownum.js +1 -1
  82. package/src/js/modules/FrozenColumns/FrozenColumns.js +1 -1
  83. package/src/js/modules/FrozenRows/FrozenRows.js +9 -0
  84. package/src/js/modules/GroupRows/Group.js +2 -61
  85. package/src/js/modules/GroupRows/GroupComponent.js +1 -1
  86. package/src/js/modules/GroupRows/GroupRows.js +2 -2
  87. package/src/js/modules/Import/Import.js +195 -0
  88. package/src/js/modules/Import/defaults/importers/csv.js +63 -0
  89. package/src/js/modules/Import/defaults/importers/json.js +8 -0
  90. package/src/js/modules/Import/defaults/importers.js +7 -0
  91. package/src/js/modules/Interaction/Interaction.js +5 -0
  92. package/src/js/modules/Keybindings/Keybindings.js +9 -14
  93. package/src/js/modules/Keybindings/defaults/bindings.js +3 -3
  94. package/src/js/modules/Localize/defaults/langs.js +6 -0
  95. package/src/js/modules/Menu/Menu.js +200 -155
  96. package/src/js/modules/MoveRows/MoveRows.js +4 -0
  97. package/src/js/modules/Page/Page.js +279 -176
  98. package/src/js/modules/Page/defaults/pageCounters/pages.js +33 -0
  99. package/src/js/modules/Page/defaults/pageCounters/rows.js +32 -0
  100. package/src/js/modules/Page/defaults/pageCounters.js +8 -0
  101. package/src/js/modules/Persistence/Persistence.js +6 -4
  102. package/src/js/modules/ResizeRows/ResizeRows.js +1 -1
  103. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +8 -10
  104. package/src/js/modules/SelectRow/SelectRow.js +1 -1
  105. package/src/js/modules/Sort/defaults/sorters/datetime.js +2 -2
  106. package/src/js/modules/Validate/Validate.js +7 -5
  107. package/src/scss/tabulator.scss +31 -12
  108. package/src/scss/themes/materialize/tabulator_materialize.scss +5 -4
  109. package/src/scss/themes/tabulator_midnight.scss +4 -0
  110. package/src/scss/themes/tabulator_site.scss +4 -0
@@ -1,42 +1,50 @@
1
1
  import Module from '../../core/Module.js';
2
2
 
3
- import Helpers from '../../core/tools/Helpers.js';
3
+ import defaultPageCounters from './defaults/pageCounters.js';
4
4
 
5
5
  class Page extends Module{
6
-
6
+
7
7
  constructor(table){
8
8
  super(table);
9
-
9
+
10
10
  this.mode = "local";
11
11
  this.progressiveLoad = false;
12
-
12
+
13
+ this.element = null;
14
+ this.pageCounterElement = null;
15
+ this.pageCounter = null;
16
+
13
17
  this.size = 0;
14
18
  this.page = 1;
15
19
  this.count = 5;
16
20
  this.max = 1;
17
21
 
22
+ this.remoteRowCountEstimate = null;
23
+
18
24
  this.displayIndex = 0; //index in display pipeline
19
-
25
+
20
26
  this.initialLoad = true;
21
27
  this.dataChanging = false; //flag to check if data is being changed by this module
22
-
28
+
23
29
  this.pageSizes = [];
24
-
30
+
25
31
  this.registerTableOption("pagination", false); //set pagination type
26
32
  this.registerTableOption("paginationMode", "local"); //local or remote pagination
27
33
  this.registerTableOption("paginationSize", false); //set number of rows to a page
28
34
  this.registerTableOption("paginationInitialPage", 1); //initial page to show on load
35
+ this.registerTableOption("paginationCounter", false); // set pagination counter
36
+ this.registerTableOption("paginationCounterElement", false); // set pagination counter
29
37
  this.registerTableOption("paginationButtonCount", 5); // set count of page button
30
38
  this.registerTableOption("paginationSizeSelector", false); //add pagination size selector element
31
39
  this.registerTableOption("paginationElement", false); //element to hold pagination numbers
32
40
  // this.registerTableOption("paginationDataSent", {}); //pagination data sent to the server
33
41
  // this.registerTableOption("paginationDataReceived", {}); //pagination data received from the server
34
42
  this.registerTableOption("paginationAddRow", "page"); //add rows on table or page
35
-
43
+
36
44
  this.registerTableOption("progressiveLoad", false); //progressive loading
37
45
  this.registerTableOption("progressiveLoadDelay", 0); //delay between requests
38
46
  this.registerTableOption("progressiveLoadScrollMargin", 0); //margin before scroll begins
39
-
47
+
40
48
  this.registerTableFunction("setMaxPage", this.setMaxPage.bind(this));
41
49
  this.registerTableFunction("setPage", this.setPage.bind(this));
42
50
  this.registerTableFunction("setPageToRow", this.userSetPageToRow.bind(this));
@@ -46,52 +54,56 @@ class Page extends Module{
46
54
  this.registerTableFunction("nextPage", this.nextPage.bind(this));
47
55
  this.registerTableFunction("getPage", this.getPage.bind(this));
48
56
  this.registerTableFunction("getPageMax", this.getPageMax.bind(this));
49
-
57
+
50
58
  //register component functions
51
59
  this.registerComponentFunction("row", "pageTo", this.setPageToRow.bind(this));
52
60
  }
53
-
61
+
54
62
  initialize(){
55
63
  if(this.table.options.pagination){
56
64
  this.subscribe("row-deleted", this.rowsUpdated.bind(this));
57
- this.subscribe("row-adding-position", this.rowAddingPosition.bind(this));
58
65
  this.subscribe("row-added", this.rowsUpdated.bind(this));
59
66
  this.subscribe("data-processed", this.initialLoadComplete.bind(this));
60
67
  this.subscribe("table-built", this.calculatePageSizes.bind(this));
61
68
 
69
+ if(this.table.options.paginationAddRow == "page"){
70
+ this.subscribe("row-adding-position", this.rowAddingPosition.bind(this));
71
+ }
72
+
62
73
  if(this.table.options.paginationMode === "remote"){
63
74
  this.subscribe("data-params", this.remotePageParams.bind(this));
64
75
  this.subscribe("data-loaded", this._parseRemoteData.bind(this));
65
76
  }
66
-
77
+
67
78
  if(this.table.options.progressiveLoad){
68
79
  console.error("Progressive Load Error - Pagination and progressive load cannot be used at the same time");
69
80
  }
70
-
81
+
71
82
  this.registerDisplayHandler(this.restOnRenderBefore.bind(this), 40);
72
83
  this.registerDisplayHandler(this.getRows.bind(this), 50);
73
-
84
+
74
85
  this.createElements();
86
+ this.initializePageCounter();
75
87
  this.initializePaginator();
76
88
  }else if(this.table.options.progressiveLoad){
77
89
  this.subscribe("data-params", this.remotePageParams.bind(this));
78
90
  this.subscribe("data-loaded", this._parseRemoteData.bind(this));
79
91
  this.subscribe("table-built", this.calculatePageSizes.bind(this));
80
92
  this.subscribe("data-processed", this.initialLoadComplete.bind(this));
81
-
93
+
82
94
  this.initializeProgressive(this.table.options.progressiveLoad)
83
-
95
+
84
96
  if(this.table.options.progressiveLoad === "scroll"){
85
97
  this.subscribe("scroll-vertical", this.scrollVertical.bind(this));
86
98
  }
87
99
  }
88
100
  }
89
-
101
+
90
102
  rowAddingPosition(row, top){
91
103
  var rowManager = this.table.rowManager,
92
104
  dispRows = rowManager.getDisplayRows(),
93
105
  index;
94
-
106
+
95
107
  if(top){
96
108
  if(dispRows.length){
97
109
  index = dispRows[0];
@@ -107,74 +119,74 @@ class Page extends Module{
107
119
  top = dispRows.length < this.size ? false : true;
108
120
  }
109
121
  }
110
-
122
+
111
123
  return {index, top}
112
124
  }
113
-
125
+
114
126
  calculatePageSizes(){
115
127
  var testElRow, testElCell;
116
-
128
+
117
129
  if(this.table.options.paginationSize){
118
130
  this.size = this.table.options.paginationSize;
119
131
  }else{
120
132
  testElRow = document.createElement("div");
121
133
  testElRow.classList.add("tabulator-row");
122
134
  testElRow.style.visibility = "hidden";
123
-
135
+
124
136
  testElCell = document.createElement("div");
125
137
  testElCell.classList.add("tabulator-cell");
126
138
  testElCell.innerHTML = "Page Row Test";
127
-
139
+
128
140
  testElRow.appendChild(testElCell);
129
-
141
+
130
142
  this.table.rowManager.getTableElement().appendChild(testElRow);
131
-
143
+
132
144
  this.size = Math.floor(this.table.rowManager.getElement().clientHeight / testElRow.offsetHeight);
133
-
145
+
134
146
  this.table.rowManager.getTableElement().removeChild(testElRow);
135
147
  }
136
-
148
+
137
149
  this.generatePageSizeSelectList();
138
150
  }
139
-
151
+
140
152
  initialLoadComplete(){
141
153
  this.initialLoad = false;
142
154
  }
143
-
155
+
144
156
  remotePageParams(data, config, silent, params){
145
157
  if(!this.initialLoad){
146
158
  if((this.progressiveLoad && !silent) || (!this.progressiveLoad && !this.dataChanging)){
147
159
  this.reset(true);
148
160
  }
149
161
  }
150
-
162
+
151
163
  //configure request params
152
164
  params.page = this.page;
153
-
165
+
154
166
  //set page size if defined
155
167
  if(this.size){
156
168
  params.size = this.size;
157
169
  }
158
-
170
+
159
171
  return params;
160
172
  }
161
-
173
+
162
174
  ///////////////////////////////////
163
175
  ///////// Table Functions /////////
164
176
  ///////////////////////////////////
165
-
177
+
166
178
  userSetPageToRow(row){
167
179
  if(this.table.options.pagination){
168
180
  row = this.rowManager.findRow(row);
169
-
181
+
170
182
  if(row){
171
183
  return this.setPageToRow(row)
172
184
  }
173
185
  }
174
-
186
+
175
187
  return Promise.reject();
176
188
  }
177
-
189
+
178
190
  userSetPageSize(size){
179
191
  if(this.table.options.pagination){
180
192
  this.setPageSize(size);
@@ -186,102 +198,102 @@ class Page extends Module{
186
198
  ///////////////////////////////////
187
199
  ///////// Internal Logic //////////
188
200
  ///////////////////////////////////
189
-
201
+
190
202
  scrollVertical(top, dir){
191
203
  var element, diff, margin;
192
204
  if(!dir && !this.table.dataLoader.loading){
193
205
  element = this.table.rowManager.getElement();
194
206
  diff = element.scrollHeight - element.clientHeight - top;
195
207
  margin = this.table.options.progressiveLoadScrollMargin || (element.clientHeight * 2);
196
-
208
+
197
209
  if(diff < margin){
198
210
  this.nextPage()
199
211
  .catch(() => {}); //consume the exception thrown when on the last page
200
212
  }
201
213
  }
202
214
  }
203
-
215
+
204
216
  restOnRenderBefore(rows, renderInPosition){
205
217
  if(!renderInPosition){
206
218
  if(this.mode === "local"){
207
219
  this.reset();
208
220
  }
209
221
  }
210
-
222
+
211
223
  return rows;
212
224
  }
213
-
225
+
214
226
  rowsUpdated(){
215
227
  this.refreshData(true, "all");
216
228
  }
217
-
229
+
218
230
  createElements(){
219
231
  var button;
220
-
232
+
221
233
  this.element = document.createElement("span");
222
234
  this.element.classList.add("tabulator-paginator");
223
-
235
+
224
236
  this.pagesElement = document.createElement("span");
225
237
  this.pagesElement.classList.add("tabulator-pages");
226
-
238
+
227
239
  button = document.createElement("button");
228
240
  button.classList.add("tabulator-page");
229
241
  button.setAttribute("type", "button");
230
242
  button.setAttribute("role", "button");
231
243
  button.setAttribute("aria-label", "");
232
244
  button.setAttribute("title", "");
233
-
245
+
234
246
  this.firstBut = button.cloneNode(true);
235
247
  this.firstBut.setAttribute("data-page", "first");
236
-
248
+
237
249
  this.prevBut = button.cloneNode(true);
238
250
  this.prevBut.setAttribute("data-page", "prev");
239
-
251
+
240
252
  this.nextBut = button.cloneNode(true);
241
253
  this.nextBut.setAttribute("data-page", "next");
242
-
254
+
243
255
  this.lastBut = button.cloneNode(true);
244
256
  this.lastBut.setAttribute("data-page", "last");
245
-
257
+
246
258
  if(this.table.options.paginationSizeSelector){
247
259
  this.pageSizeSelect = document.createElement("select");
248
260
  this.pageSizeSelect.classList.add("tabulator-page-size");
249
261
  }
250
262
  }
251
-
263
+
252
264
  generatePageSizeSelectList(){
253
265
  var pageSizes = [];
254
-
266
+
255
267
  if(this.pageSizeSelect){
256
-
268
+
257
269
  if(Array.isArray(this.table.options.paginationSizeSelector)){
258
270
  pageSizes = this.table.options.paginationSizeSelector;
259
271
  this.pageSizes = pageSizes;
260
-
272
+
261
273
  if(this.pageSizes.indexOf(this.size) == -1){
262
274
  pageSizes.unshift(this.size);
263
275
  }
264
276
  }else{
265
-
277
+
266
278
  if(this.pageSizes.indexOf(this.size) == -1){
267
279
  pageSizes = [];
268
-
280
+
269
281
  for (let i = 1; i < 5; i++){
270
282
  pageSizes.push(this.size * i);
271
283
  }
272
-
284
+
273
285
  this.pageSizes = pageSizes;
274
286
  }else{
275
287
  pageSizes = this.pageSizes;
276
288
  }
277
289
  }
278
-
290
+
279
291
  while(this.pageSizeSelect.firstChild) this.pageSizeSelect.removeChild(this.pageSizeSelect.firstChild);
280
-
292
+
281
293
  pageSizes.forEach((item) => {
282
294
  var itemEl = document.createElement("option");
283
295
  itemEl.value = item;
284
-
296
+
285
297
  if(item === true){
286
298
  this.langBind("pagination|all", function(value){
287
299
  itemEl.innerHTML = value;
@@ -289,136 +301,180 @@ class Page extends Module{
289
301
  }else{
290
302
  itemEl.innerHTML = item;
291
303
  }
292
-
293
-
294
-
304
+
305
+
306
+
295
307
  this.pageSizeSelect.appendChild(itemEl);
296
308
  });
297
-
309
+
298
310
  this.pageSizeSelect.value = this.size;
299
311
  }
300
312
  }
301
-
302
- //setup pageination
313
+
314
+ initializePageCounter(){
315
+ var counter = this.table.options.paginationCounter,
316
+ pageCounter = null;
317
+
318
+ if(counter){
319
+ if(typeof counter === "function"){
320
+ pageCounter = counter;
321
+ }else{
322
+ pageCounter = Page.pageCounters[counter];
323
+ }
324
+
325
+ if(pageCounter){
326
+ this.pageCounter = pageCounter;
327
+
328
+ this.pageCounterElement = document.createElement("span");
329
+ this.pageCounterElement.classList.add("tabulator-page-counter");
330
+ }else{
331
+ console.warn("Pagination Error - No such page counter found: ", counter);
332
+ }
333
+ }
334
+ }
335
+
336
+ //setup pagination
303
337
  initializePaginator(hidden){
304
- var pageSelectLabel;
305
-
338
+ var pageSelectLabel, paginationCounterHolder;
339
+
306
340
  if(!hidden){
307
341
  //build pagination element
308
-
342
+
309
343
  //bind localizations
310
344
  this.langBind("pagination|first", (value) => {
311
345
  this.firstBut.innerHTML = value;
312
346
  });
313
-
347
+
314
348
  this.langBind("pagination|first_title", (value) => {
315
349
  this.firstBut.setAttribute("aria-label", value);
316
350
  this.firstBut.setAttribute("title", value);
317
351
  });
318
-
352
+
319
353
  this.langBind("pagination|prev", (value) => {
320
354
  this.prevBut.innerHTML = value;
321
355
  });
322
-
356
+
323
357
  this.langBind("pagination|prev_title", (value) => {
324
358
  this.prevBut.setAttribute("aria-label", value);
325
359
  this.prevBut.setAttribute("title", value);
326
360
  });
327
-
361
+
328
362
  this.langBind("pagination|next", (value) => {
329
363
  this.nextBut.innerHTML = value;
330
364
  });
331
-
365
+
332
366
  this.langBind("pagination|next_title", (value) => {
333
367
  this.nextBut.setAttribute("aria-label", value);
334
368
  this.nextBut.setAttribute("title", value);
335
369
  });
336
-
370
+
337
371
  this.langBind("pagination|last", (value) => {
338
372
  this.lastBut.innerHTML = value;
339
373
  });
340
-
374
+
341
375
  this.langBind("pagination|last_title", (value) => {
342
376
  this.lastBut.setAttribute("aria-label", value);
343
377
  this.lastBut.setAttribute("title", value);
344
378
  });
345
-
379
+
346
380
  //click bindings
347
381
  this.firstBut.addEventListener("click", () => {
348
382
  this.setPage(1)
349
383
  });
350
-
384
+
351
385
  this.prevBut.addEventListener("click", () => {
352
386
  this.previousPage()
353
387
  });
354
-
388
+
355
389
  this.nextBut.addEventListener("click", () => {
356
390
  this.nextPage()
357
391
  });
358
-
392
+
359
393
  this.lastBut.addEventListener("click", () => {
360
394
  this.setPage(this.max)
361
395
  });
362
-
396
+
363
397
  if(this.table.options.paginationElement){
364
398
  this.element = this.table.options.paginationElement;
365
399
  }
366
-
400
+
367
401
  if(this.pageSizeSelect){
368
402
  pageSelectLabel = document.createElement("label");
369
-
403
+
370
404
  this.langBind("pagination|page_size", (value) => {
371
405
  this.pageSizeSelect.setAttribute("aria-label", value);
372
406
  this.pageSizeSelect.setAttribute("title", value);
373
407
  pageSelectLabel.innerHTML = value;
374
408
  });
375
-
409
+
376
410
  this.element.appendChild(pageSelectLabel);
377
411
  this.element.appendChild(this.pageSizeSelect);
378
-
412
+
379
413
  this.pageSizeSelect.addEventListener("change", (e) => {
380
414
  this.setPageSize(this.pageSizeSelect.value == "true" ? true : this.pageSizeSelect.value);
381
415
  this.setPage(1)
382
416
  });
383
417
  }
384
-
418
+
385
419
  //append to DOM
386
420
  this.element.appendChild(this.firstBut);
387
421
  this.element.appendChild(this.prevBut);
388
422
  this.element.appendChild(this.pagesElement);
389
423
  this.element.appendChild(this.nextBut);
390
424
  this.element.appendChild(this.lastBut);
391
-
425
+
392
426
  if(!this.table.options.paginationElement && !hidden){
427
+ if(this.table.options.paginationCounter){
428
+
429
+ paginationCounterHolder
430
+
431
+ if(this.table.options.paginationCounterElement){
432
+ if(this.table.options.paginationCounterElement instanceof HTMLElement){
433
+ this.table.options.paginationCounterElement.appendChild(this.pageCounterElement);
434
+ }else if(typeof this.table.options.paginationCounterElement === "string"){
435
+ paginationCounterHolder = document.querySelector(this.table.options.paginationCounterElement);
436
+
437
+ if(paginationCounterHolder){
438
+ paginationCounterHolder.appendChild(this.pageCounterElement);
439
+ }else{
440
+ console.warn("Pagination Error - Unable to find element matching paginationCounterElement selector:", this.table.options.paginationCounterElement);
441
+ }
442
+ }
443
+ }else{
444
+ this.table.footerManager.append(this.pageCounterElement);
445
+ }
446
+
447
+ }
448
+
393
449
  this.table.footerManager.append(this.element, this);
394
450
  }
395
-
451
+
396
452
  this.page = this.table.options.paginationInitialPage;
397
453
  this.count = this.table.options.paginationButtonCount;
398
454
  }
399
-
455
+
400
456
  //set default values
401
457
  this.mode = this.table.options.paginationMode;
402
458
  }
403
-
459
+
404
460
  initializeProgressive(mode){
405
461
  this.initializePaginator(true);
406
462
  this.mode = "progressive_" + mode;
407
463
  this.progressiveLoad = true;
408
464
  }
409
-
465
+
410
466
  trackChanges(){
411
467
  this.dispatch("page-changed");
412
468
  }
413
-
469
+
414
470
  setDisplayIndex(index){
415
471
  this.displayIndex = index;
416
472
  }
417
-
473
+
418
474
  getDisplayIndex(){
419
475
  return this.displayIndex;
420
476
  }
421
-
477
+
422
478
  //calculate maximum page from number of rows
423
479
  setMaxRows(rowCount){
424
480
  if(!rowCount){
@@ -426,12 +482,12 @@ class Page extends Module{
426
482
  }else{
427
483
  this.max = this.size === true ? 1 : Math.ceil(rowCount/this.size);
428
484
  }
429
-
485
+
430
486
  if(this.page > this.max){
431
487
  this.page = this.max;
432
488
  }
433
489
  }
434
-
490
+
435
491
  //reset to first page without triggering action
436
492
  reset(force){
437
493
  if(!this.initialLoad){
@@ -440,95 +496,132 @@ class Page extends Module{
440
496
  }
441
497
  }
442
498
  }
443
-
499
+
444
500
  //set the maximum page
445
501
  setMaxPage(max){
446
-
502
+
447
503
  max = parseInt(max);
448
-
504
+
449
505
  this.max = max || 1;
450
-
506
+
451
507
  if(this.page > this.max){
452
508
  this.page = this.max;
453
509
  this.trigger();
454
510
  }
455
511
  }
456
-
512
+
457
513
  //set current page number
458
514
  setPage(page){
459
515
  switch(page){
460
516
  case "first":
461
517
  return this.setPage(1);
462
518
  break;
463
-
519
+
464
520
  case "prev":
465
521
  return this.previousPage();
466
522
  break;
467
-
523
+
468
524
  case "next":
469
525
  return this.nextPage();
470
526
  break;
471
-
527
+
472
528
  case "last":
473
529
  return this.setPage(this.max);
474
530
  break;
475
531
  }
476
-
477
-
532
+
478
533
  page = parseInt(page);
479
-
534
+
480
535
  if((page > 0 && page <= this.max) || this.mode !== "local"){
481
536
  this.page = page;
482
-
537
+
483
538
  this.trackChanges();
484
-
539
+
485
540
  return this.trigger();
486
541
  }else{
487
542
  console.warn("Pagination Error - Requested page is out of range of 1 - " + this.max + ":", page);
488
543
  return Promise.reject();
489
544
  }
490
545
  }
491
-
546
+
492
547
  setPageToRow(row){
493
548
  var rows = this.table.rowManager.getDisplayRows(this.displayIndex - 1);
494
549
  var index = rows.indexOf(row);
495
-
550
+
496
551
  if(index > -1){
497
552
  var page = this.size === true ? 1 : Math.ceil((index + 1) / this.size);
498
-
553
+
499
554
  return this.setPage(page)
500
555
  }else{
501
556
  console.warn("Pagination Error - Requested row is not visible");
502
557
  return Promise.reject();
503
558
  }
504
559
  }
505
-
560
+
506
561
  setPageSize(size){
507
562
  if(size !== true){
508
563
  size = parseInt(size);
509
564
  }
510
-
565
+
511
566
  if(size > 0){
512
567
  this.size = size;
513
568
  }
514
-
569
+
515
570
  if(this.pageSizeSelect){
516
571
  // this.pageSizeSelect.value = size;
517
572
  this.generatePageSizeSelectList();
518
573
  }
519
-
574
+
520
575
  this.trackChanges();
521
576
  }
577
+
578
+ _setPageCounter(totalRows){
579
+ var content, currentRow;
580
+
581
+ if(this.pageCounter){
582
+ currentRow = ((this.page - 1) * this.size) + 1;
583
+
584
+ if(this.mode === "remote"){
585
+ totalRows = this.remoteRowCountEstimate;
586
+ }
522
587
 
588
+ content = this.pageCounter.call(this, this.size, currentRow, this.page, totalRows, this.max);
589
+
590
+ switch(typeof content){
591
+ case "object":
592
+ if(content instanceof Node){
593
+
594
+ //clear previous cell contents
595
+ while(this.pageCounterElement.firstChild) this.pageCounterElement.removeChild(this.pageCounterElement.firstChild);
596
+
597
+ this.pageCounterElement.appendChild(content);
598
+ }else{
599
+ this.pageCounterElement.innerHTML = "";
600
+
601
+ if(content != null){
602
+ console.warn("Page Counter Error - Page Counter has returned a type of object, the only valid page counter object return is an instance of Node, the page counter returned:", content);
603
+ }
604
+ }
605
+ break;
606
+ case "undefined":
607
+ case "null":
608
+ this.pageCounterElement.innerHTML = "";
609
+ break;
610
+ default:
611
+ this.pageCounterElement.innerHTML = content;
612
+ }
613
+ }
614
+ }
615
+
523
616
  //setup the pagination buttons
524
617
  _setPageButtons(){
525
618
  let leftSize = Math.floor((this.count-1) / 2);
526
619
  let rightSize = Math.ceil((this.count-1) / 2);
527
620
  let min = this.max - this.page + leftSize + 1 < this.count ? this.max-this.count+1: Math.max(this.page-leftSize,1);
528
621
  let max = this.page <= rightSize? Math.min(this.count, this.max) :Math.min(this.page+rightSize, this.max);
529
-
622
+
530
623
  while(this.pagesElement.firstChild) this.pagesElement.removeChild(this.pagesElement.firstChild);
531
-
624
+
532
625
  if(this.page == 1){
533
626
  this.firstBut.disabled = true;
534
627
  this.prevBut.disabled = true;
@@ -536,7 +629,7 @@ class Page extends Module{
536
629
  this.firstBut.disabled = false;
537
630
  this.prevBut.disabled = false;
538
631
  }
539
-
632
+
540
633
  if(this.page == this.max){
541
634
  this.lastBut.disabled = true;
542
635
  this.nextBut.disabled = true;
@@ -544,66 +637,66 @@ class Page extends Module{
544
637
  this.lastBut.disabled = false;
545
638
  this.nextBut.disabled = false;
546
639
  }
547
-
640
+
548
641
  for(let i = min; i <= max; i++){
549
642
  if(i>0 && i <= this.max){
550
643
  this.pagesElement.appendChild(this._generatePageButton(i));
551
644
  }
552
645
  }
553
-
646
+
554
647
  this.footerRedraw();
555
648
  }
556
-
649
+
557
650
  _generatePageButton(page){
558
651
  var button = document.createElement("button");
559
-
652
+
560
653
  button.classList.add("tabulator-page");
561
654
  if(page == this.page){
562
655
  button.classList.add("active");
563
656
  }
564
-
657
+
565
658
  button.setAttribute("type", "button");
566
659
  button.setAttribute("role", "button");
567
-
660
+
568
661
  this.langBind("pagination|page_title", (value) => {
569
662
  button.setAttribute("aria-label", value + " " + page);
570
663
  button.setAttribute("title", value + " " + page);
571
664
  });
572
-
665
+
573
666
  button.setAttribute("data-page", page);
574
667
  button.textContent = page;
575
-
668
+
576
669
  button.addEventListener("click", (e) => {
577
670
  this.setPage(page)
578
671
  });
579
-
672
+
580
673
  return button;
581
674
  }
582
-
675
+
583
676
  //previous page
584
677
  previousPage(){
585
678
  if(this.page > 1){
586
679
  this.page--;
587
-
680
+
588
681
  this.trackChanges();
589
-
682
+
590
683
  return this.trigger()
591
-
684
+
592
685
  }else{
593
686
  console.warn("Pagination Error - Previous page would be less than page 1:", 0);
594
687
  return Promise.reject();
595
688
  }
596
689
  }
597
-
690
+
598
691
  //next page
599
692
  nextPage(){
600
693
  if(this.page < this.max){
601
694
  this.page++;
602
-
695
+
603
696
  this.trackChanges();
604
-
697
+
605
698
  return this.trigger();
606
-
699
+
607
700
  }else{
608
701
  if(!this.progressiveLoad){
609
702
  console.warn("Pagination Error - Next page would be greater than maximum page of " + this.max + ":", this.max + 1);
@@ -611,34 +704,34 @@ class Page extends Module{
611
704
  return Promise.reject();
612
705
  }
613
706
  }
614
-
707
+
615
708
  //return current page number
616
709
  getPage(){
617
710
  return this.page;
618
711
  }
619
-
712
+
620
713
  //return max page number
621
714
  getPageMax(){
622
715
  return this.max;
623
716
  }
624
-
717
+
625
718
  getPageSize(size){
626
719
  return this.size;
627
720
  }
628
-
721
+
629
722
  getMode(){
630
723
  return this.mode;
631
724
  }
632
-
725
+
633
726
  //return appropriate rows for current page
634
727
  getRows(data){
635
728
  var output, start, end;
636
-
729
+
637
730
  if(this.mode == "local"){
638
731
  output = [];
639
-
732
+
640
733
  this.setMaxRows(data.length);
641
-
734
+
642
735
  if(this.size === true){
643
736
  start = 0;
644
737
  end = data.length;
@@ -646,39 +739,42 @@ class Page extends Module{
646
739
  start = this.size * (this.page - 1);
647
740
  end = start + parseInt(this.size);
648
741
  }
649
-
650
-
742
+
743
+
651
744
  this._setPageButtons();
652
-
745
+
653
746
  for(let i = start; i < end; i++){
654
747
  if(data[i]){
655
748
  output.push(data[i]);
656
749
  }
657
750
  }
658
751
 
752
+ this._setPageCounter(data.length);
753
+
659
754
  return output;
660
755
  }else{
661
756
  this._setPageButtons();
662
-
757
+ this._setPageCounter(data.length);
758
+
663
759
  return data.slice(0);
664
760
  }
665
761
  }
666
-
762
+
667
763
  trigger(){
668
764
  var left;
669
-
765
+
670
766
  switch(this.mode){
671
767
  case "local":
672
768
  left = this.table.rowManager.scrollLeft;
673
-
769
+
674
770
  this.refreshData();
675
771
  this.table.rowManager.scrollHorizontal(left);
676
-
772
+
677
773
  this.dispatchExternal("pageLoaded", this.getPage());
678
-
774
+
679
775
  return Promise.resolve();
680
776
  break;
681
-
777
+
682
778
  case "remote":
683
779
  this.dataChanging = true;
684
780
  return this.reloadData(null)
@@ -686,60 +782,64 @@ class Page extends Module{
686
782
  this.dataChanging = false;
687
783
  })
688
784
  break;
689
-
785
+
690
786
  case "progressive_load":
691
787
  case "progressive_scroll":
692
788
  return this.reloadData(null, true);
693
789
  break;
694
-
790
+
695
791
  default:
696
792
  console.warn("Pagination Error - no such pagination mode:", this.mode);
697
793
  return Promise.reject();
698
794
  }
699
795
  }
700
-
796
+
701
797
  _parseRemoteData(data){
702
798
  var left, data, margin;
703
-
799
+
704
800
  if(typeof data.last_page === "undefined"){
705
801
  console.warn("Remote Pagination Error - Server response missing '" + (this.options("dataReceiveParams").last_page || "last_page") + "' property");
706
802
  }
707
-
803
+
708
804
  if(data.data){
709
805
  this.max = parseInt(data.last_page) || 1;
710
806
 
807
+ this.remoteRowCountEstimate = typeof data.last_row !== "undefined" ? data.last_row : (data.last_page * this.size - (this.page == data.last_page ? (this.size - data.data.length) : 0));
808
+
711
809
  if(this.progressiveLoad){
712
810
  switch(this.mode){
713
811
  case "progressive_load":
714
-
812
+
715
813
  if(this.page == 1){
716
814
  this.table.rowManager.setData(data.data, false, this.page == 1)
717
815
  }else{
718
816
  this.table.rowManager.addRows(data.data);
719
817
  }
720
-
818
+
721
819
  if(this.page < this.max){
722
820
  setTimeout(() => {
723
821
  this.nextPage();
724
822
  }, this.table.options.progressiveLoadDelay);
725
823
  }
726
824
  break;
727
-
825
+
728
826
  case "progressive_scroll":
729
827
  data = this.page === 1 ? data.data : this.table.rowManager.getData().concat(data.data);
730
-
828
+
731
829
  this.table.rowManager.setData(data, this.page !== 1, this.page == 1);
732
-
830
+
733
831
  margin = this.table.options.progressiveLoadScrollMargin || (this.table.rowManager.element.clientHeight * 2);
734
-
832
+
735
833
  if(this.table.rowManager.element.scrollHeight <= (this.table.rowManager.element.clientHeight + margin)){
736
- setTimeout(() => {
737
- this.nextPage();
738
- });
834
+ if(this.page < this.max){
835
+ setTimeout(() => {
836
+ this.nextPage();
837
+ });
838
+ }
739
839
  }
740
840
  break;
741
841
  }
742
-
842
+
743
843
  return false;
744
844
  }else{
745
845
  // left = this.table.rowManager.scrollLeft;
@@ -747,23 +847,23 @@ class Page extends Module{
747
847
  // this.table.rowManager.scrollHorizontal(left);
748
848
  // this.table.columnManager.scrollHorizontal(left);
749
849
  }
750
-
850
+
751
851
  }else{
752
852
  console.warn("Remote Pagination Error - Server response missing '" + (this.options("dataReceiveParams").data || "data") + "' property");
753
853
  }
754
-
854
+
755
855
  return data.data;
756
856
  }
757
-
857
+
758
858
  //handle the footer element being redrawn
759
859
  footerRedraw(){
760
860
  var footer = this.table.footerManager.element;
761
-
861
+
762
862
  if((Math.ceil(footer.clientWidth) - footer.scrollWidth) < 0){
763
863
  this.pagesElement.style.display = 'none';
764
864
  }else{
765
865
  this.pagesElement.style.display = '';
766
-
866
+
767
867
  if((Math.ceil(footer.clientWidth) - footer.scrollWidth) < 0){
768
868
  this.pagesElement.style.display = 'none';
769
869
  }
@@ -773,4 +873,7 @@ class Page extends Module{
773
873
 
774
874
  Page.moduleName = "page";
775
875
 
876
+ //load defaults
877
+ Page.pageCounters = defaultPageCounters;
878
+
776
879
  export default Page;