tabulator-tables 5.0.7 → 5.1.0

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