tabulator-tables 5.0.8 → 5.1.1

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