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
@@ -7,72 +7,91 @@ import RendererBasicVertical from './rendering/renderers/BasicVertical.js';
7
7
  import RendererVirtualDomVertical from './rendering/renderers/VirtualDomVertical.js';
8
8
 
9
9
  export default class RowManager extends CoreFeature{
10
-
10
+
11
11
  constructor(table){
12
12
  super(table);
13
-
13
+
14
14
  this.element = this.createHolderElement(); //containing element
15
15
  this.tableElement = this.createTableElement(); //table element
16
16
  this.heightFixer = this.createTableElement(); //table element
17
-
17
+ this.placeholder = null; //placeholder element
18
+ this.placeholderContents = null; //placeholder element
19
+
18
20
  this.firstRender = false; //handle first render
19
21
  this.renderMode = "virtual"; //current rendering mode
20
22
  this.fixedHeight = false; //current rendering mode
21
-
23
+
22
24
  this.rows = []; //hold row data objects
23
- this.activeRowsPipeline = []; //hold caluclation of active rows
25
+ this.activeRowsPipeline = []; //hold calculation of active rows
24
26
  this.activeRows = []; //rows currently available to on display in the table
25
27
  this.activeRowsCount = 0; //count of active rows
26
-
28
+
27
29
  this.displayRows = []; //rows currently on display in the table
28
30
  this.displayRowsCount = 0; //count of display rows
29
-
31
+
30
32
  this.scrollTop = 0;
31
33
  this.scrollLeft = 0;
32
-
34
+
33
35
  this.rowNumColumn = false; //hold column component for row number column
34
-
35
- this.redrawBlock = false; //prevent redraws to allow multiple data manipulations becore continuing
36
+
37
+ this.redrawBlock = false; //prevent redraws to allow multiple data manipulations before continuing
36
38
  this.redrawBlockRestoreConfig = false; //store latest redraw function calls for when redraw is needed
37
- this.redrawBlockRederInPosition = false; //store latest redraw function calls for when redraw is needed
38
-
39
+ this.redrawBlockRenderInPosition = false; //store latest redraw function calls for when redraw is needed
40
+
39
41
  this.dataPipeline = []; //hold data pipeline tasks
40
42
  this.displayPipeline = []; //hold data display pipeline tasks
41
-
43
+
42
44
  this.renderer = null;
43
45
  }
44
-
46
+
45
47
  //////////////// Setup Functions /////////////////
46
-
48
+
47
49
  createHolderElement (){
48
50
  var el = document.createElement("div");
49
-
51
+
50
52
  el.classList.add("tabulator-tableholder");
51
53
  el.setAttribute("tabindex", 0);
52
54
  el.setAttribute("role", "rowgroup");
53
-
55
+
54
56
  return el;
55
57
  }
56
-
58
+
57
59
  createTableElement (){
58
60
  var el = document.createElement("div");
59
-
61
+
60
62
  el.classList.add("tabulator-table");
61
63
  el.setAttribute("role", "rowgroup");
62
-
64
+
63
65
  return el;
64
66
  }
65
-
67
+
68
+ initializePlaceholder(){
69
+ //configure placeholder element
70
+ if(typeof this.table.options.placeholder == "string"){
71
+ let el = document.createElement("div");
72
+ el.classList.add("tabulator-placeholder");
73
+
74
+ let contents = document.createElement("div");
75
+ contents.classList.add("tabulator-placeholder-contents");
76
+ contents.innerHTML = this.table.options.placeholder;
77
+
78
+ el.appendChild(contents);
79
+
80
+ this.placeholderContents = contents;
81
+ this.placeholder = el;
82
+ }
83
+ }
84
+
66
85
  //return containing element
67
86
  getElement(){
68
87
  return this.element;
69
88
  }
70
-
89
+
71
90
  //return table element
72
91
  getTableElement(){
73
92
  return this.tableElement;
74
93
  }
75
-
94
+
76
95
  //return position of row in table
77
96
  getRowPosition(row, active){
78
97
  if(active){
@@ -81,42 +100,45 @@ export default class RowManager extends CoreFeature{
81
100
  return this.rows.indexOf(row);
82
101
  }
83
102
  }
84
-
103
+
85
104
  initialize(){
105
+ this.initializePlaceholder()
86
106
  this.initializeRenderer();
87
-
107
+
88
108
  //initialize manager
89
109
  this.element.appendChild(this.tableElement);
90
-
110
+
91
111
  this.firstRender = true;
92
-
112
+
93
113
  //scroll header along with table body
94
114
  this.element.addEventListener("scroll", () => {
95
115
  var left = this.element.scrollLeft,
96
116
  leftDir = this.scrollLeft > left,
97
117
  top = this.element.scrollTop,
98
118
  topDir = this.scrollTop > top;
99
-
119
+
100
120
  //handle horizontal scrolling
101
121
  if(this.scrollLeft != left){
102
122
  this.scrollLeft = left;
103
-
123
+
104
124
  this.dispatch("scroll-horizontal", left, leftDir);
105
125
  this.dispatchExternal("scrollHorizontal", left, leftDir);
106
- }
107
126
 
108
- //handle verical scrolling
127
+ this._positionPlaceholder();
128
+ }
129
+
130
+ //handle vertical scrolling
109
131
  if(this.scrollTop != top){
110
132
  this.scrollTop = top;
111
-
133
+
112
134
  this.renderer.scrollRows(top, topDir);
113
-
135
+
114
136
  this.dispatch("scroll-vertical", top, topDir);
115
137
  this.dispatchExternal("scrollVertical", top, topDir);
116
138
  }
117
139
  });
118
140
  }
119
-
141
+
120
142
  ////////////////// Row Manipulation //////////////////
121
143
  findRow(subject){
122
144
  if(typeof subject == "object"){
@@ -131,7 +153,7 @@ export default class RowManager extends CoreFeature{
131
153
  let match = this.rows.find((row) => {
132
154
  return row.getElement() === subject;
133
155
  });
134
-
156
+
135
157
  return match || false;
136
158
  }
137
159
  }else if(typeof subject == "undefined" || subject === null){
@@ -141,22 +163,22 @@ export default class RowManager extends CoreFeature{
141
163
  let match = this.rows.find((row) => {
142
164
  return row.data[this.table.options.index] == subject;
143
165
  });
144
-
166
+
145
167
  return match || false;
146
168
  }
147
-
169
+
148
170
  //catch all for any other type of input
149
171
  return false;
150
172
  }
151
-
173
+
152
174
  getRowFromDataObject(data){
153
175
  var match = this.rows.find((row) => {
154
176
  return row.data === data;
155
177
  });
156
-
178
+
157
179
  return match || false;
158
180
  }
159
-
181
+
160
182
  getRowFromPosition(position, active){
161
183
  if(active){
162
184
  return this.activeRows[position];
@@ -164,11 +186,11 @@ export default class RowManager extends CoreFeature{
164
186
  return this.rows[position];
165
187
  }
166
188
  }
167
-
189
+
168
190
  scrollToRow(row, position, ifVisible){
169
191
  return this.renderer.scrollToRowPosition(row, position, ifVisible);
170
192
  }
171
-
193
+
172
194
  ////////////////// Data Handling //////////////////
173
195
  setData(data, renderInPosition, columnsChanged){
174
196
  return new Promise((resolve, reject)=>{
@@ -185,22 +207,22 @@ export default class RowManager extends CoreFeature{
185
207
  this.table.columnManager.generateColumnsFromRowData(data);
186
208
  }
187
209
  this.resetScroll();
188
-
210
+
189
211
  this._setDataActual(data);
190
212
  }
191
-
213
+
192
214
  resolve();
193
215
  });
194
216
  }
195
-
217
+
196
218
  _setDataActual(data, renderInPosition){
197
219
  this.dispatchExternal("dataProcessing", data);
198
-
220
+
199
221
  this._wipeElements();
200
-
222
+
201
223
  if(Array.isArray(data)){
202
224
  this.dispatch("data-processing", data);
203
-
225
+
204
226
  data.forEach((def, i) => {
205
227
  if(def && typeof def === "object"){
206
228
  var row = new Row(def, this);
@@ -209,261 +231,258 @@ export default class RowManager extends CoreFeature{
209
231
  console.warn("Data Loading Warning - Invalid row data detected and ignored, expecting object but received:", def);
210
232
  }
211
233
  });
212
-
234
+
213
235
  this.refreshActiveData(false, false, renderInPosition);
214
-
236
+
215
237
  this.dispatch("data-processed", data);
216
238
  this.dispatchExternal("dataProcessed", data);
217
239
  }else{
218
240
  console.error("Data Loading Error - Unable to process data due to invalid data type \nExpecting: array \nReceived: ", typeof data, "\nData: ", data);
219
241
  }
220
242
  }
221
-
243
+
222
244
  _wipeElements(){
223
245
  this.dispatch("rows-wipe");
224
-
246
+
225
247
  this.rows.forEach((row) => {
226
248
  row.wipe();
227
249
  });
228
-
250
+
229
251
  this.rows = [];
230
252
  this.activeRows = [];
231
253
  this.activeRowsPipeline = [];
232
254
  this.activeRowsCount = 0;
233
255
  this.displayRows = [];
234
256
  this.displayRowsCount = 0;
235
-
257
+
236
258
  this.adjustTableSize();
237
259
  }
238
-
260
+
239
261
  deleteRow(row, blockRedraw){
240
262
  var allIndex = this.rows.indexOf(row),
241
263
  activeIndex = this.activeRows.indexOf(row);
242
-
264
+
243
265
  if(activeIndex > -1){
244
266
  this.activeRows.splice(activeIndex, 1);
245
267
  }
246
-
268
+
247
269
  if(allIndex > -1){
248
270
  this.rows.splice(allIndex, 1);
249
271
  }
250
-
272
+
251
273
  this.setActiveRows(this.activeRows);
252
-
274
+
253
275
  this.displayRowIterator((rows) => {
254
276
  var displayIndex = rows.indexOf(row);
255
-
277
+
256
278
  if(displayIndex > -1){
257
279
  rows.splice(displayIndex, 1);
258
280
  }
259
281
  });
260
-
282
+
261
283
  if(!blockRedraw){
262
284
  this.reRenderInPosition();
263
285
  }
264
-
286
+
265
287
  this.regenerateRowNumbers();
266
-
288
+
267
289
  this.dispatchExternal("rowDeleted", row.getComponent());
268
-
290
+
269
291
  if(!this.displayRowsCount){
270
292
  this._showPlaceholder();
271
293
  }
272
-
294
+
273
295
  if(this.subscribedExternal("dataChanged")){
274
296
  this.dispatchExternal("dataChanged", this.getData());
275
297
  }
276
298
  }
277
-
299
+
278
300
  addRow(data, pos, index, blockRedraw){
279
301
  var row = this.addRowActual(data, pos, index, blockRedraw);
280
-
281
- this.dispatch("row-added", row, data, pos, index);
282
-
283
302
  return row;
284
303
  }
285
-
304
+
286
305
  //add multiple rows
287
306
  addRows(data, pos, index){
288
307
  var length = 0,
289
308
  rows = [];
290
-
309
+
291
310
  return new Promise((resolve, reject) => {
292
311
  pos = this.findAddRowPos(pos);
293
-
312
+
294
313
  if(!Array.isArray(data)){
295
314
  data = [data];
296
315
  }
297
-
316
+
298
317
  length = data.length - 1;
299
-
318
+
300
319
  if((typeof index == "undefined" && pos) || (typeof index !== "undefined" && !pos)){
301
320
  data.reverse();
302
321
  }
303
-
322
+
304
323
  data.forEach((item, i) => {
305
324
  var row = this.addRow(item, pos, index, true);
306
325
  rows.push(row);
307
326
  this.dispatch("row-added", row, data, pos, index);
308
327
  });
309
-
328
+
310
329
  this.refreshActiveData(false, false, true);
311
-
330
+
312
331
  this.regenerateRowNumbers();
313
-
332
+
314
333
  if(rows.length){
315
334
  this._clearPlaceholder();
316
335
  }
317
-
336
+
318
337
  resolve(rows);
319
338
  });
320
339
  }
321
-
340
+
322
341
  findAddRowPos(pos){
323
342
  if(typeof pos === "undefined"){
324
343
  pos = this.table.options.addRowPos;
325
344
  }
326
-
345
+
327
346
  if(pos === "pos"){
328
347
  pos = true;
329
348
  }
330
-
349
+
331
350
  if(pos === "bottom"){
332
351
  pos = false;
333
352
  }
334
-
353
+
335
354
  return pos;
336
355
  }
337
-
356
+
338
357
  addRowActual(data, pos, index, blockRedraw){
339
358
  var row = data instanceof Row ? data : new Row(data || {}, this),
340
359
  top = this.findAddRowPos(pos),
341
360
  allIndex = -1,
342
361
  activeIndex, chainResult;
343
-
362
+
344
363
  if(!index){
345
364
  chainResult = this.chain("row-adding-position", [row, top], null, {index, top});
346
-
365
+
347
366
  index = chainResult.index;
348
367
  top = chainResult.top;
349
368
  }
350
-
369
+
351
370
  if(typeof index !== "undefined"){
352
371
  index = this.findRow(index);
353
372
  }
354
-
373
+
355
374
  index = this.chain("row-adding-index", [row, index, top], null, index);
356
-
375
+
357
376
  if(index){
358
377
  allIndex = this.rows.indexOf(index);
359
378
  }
360
-
379
+
361
380
  if(index && allIndex > -1){
362
381
  activeIndex = this.activeRows.indexOf(index);
363
-
382
+
364
383
  this.displayRowIterator(function(rows){
365
384
  var displayIndex = rows.indexOf(index);
366
-
385
+
367
386
  if(displayIndex > -1){
368
387
  rows.splice((top ? displayIndex : displayIndex + 1), 0, row);
369
388
  }
370
389
  });
371
-
390
+
372
391
  if(activeIndex > -1){
373
392
  this.activeRows.splice((top ? activeIndex : activeIndex + 1), 0, row);
374
393
  }
375
-
394
+
376
395
  this.rows.splice((top ? allIndex : allIndex + 1), 0, row);
377
-
396
+
378
397
  }else{
379
-
398
+
380
399
  if(top){
381
-
400
+
382
401
  this.displayRowIterator(function(rows){
383
402
  rows.unshift(row);
384
403
  });
385
-
404
+
386
405
  this.activeRows.unshift(row);
387
406
  this.rows.unshift(row);
388
407
  }else{
389
408
  this.displayRowIterator(function(rows){
390
409
  rows.push(row);
391
410
  });
392
-
411
+
393
412
  this.activeRows.push(row);
394
413
  this.rows.push(row);
395
414
  }
396
415
  }
397
-
416
+
398
417
  this.setActiveRows(this.activeRows);
399
-
418
+
400
419
  this.dispatchExternal("rowAdded", row.getComponent());
401
-
420
+
402
421
  if(this.subscribedExternal("dataChanged")){
403
422
  this.dispatchExternal("dataChanged", this.table.rowManager.getData());
404
423
  }
405
-
424
+
406
425
  if(!blockRedraw){
407
426
  this.reRenderInPosition();
408
427
  }
409
-
428
+
410
429
  return row;
411
430
  }
412
-
431
+
413
432
  moveRow(from, to, after){
414
433
  this.dispatch("row-move", from, to, after);
415
-
434
+
416
435
  this.moveRowActual(from, to, after);
417
-
436
+
418
437
  this.regenerateRowNumbers();
419
-
438
+
420
439
  this.dispatch("row-moved", from, to, after);
421
440
  this.dispatchExternal("rowMoved", from.getComponent());
422
441
  }
423
-
442
+
424
443
  moveRowActual(from, to, after){
425
444
  this.moveRowInArray(this.rows, from, to, after);
426
445
  this.moveRowInArray(this.activeRows, from, to, after);
427
-
446
+
428
447
  this.displayRowIterator((rows) => {
429
448
  this.moveRowInArray(rows, from, to, after);
430
449
  });
431
-
450
+
432
451
  this.dispatch("row-moving", from, to, after);
433
452
  }
434
-
453
+
435
454
  moveRowInArray(rows, from, to, after){
436
455
  var fromIndex, toIndex, start, end;
437
-
456
+
438
457
  if(from !== to){
439
-
458
+
440
459
  fromIndex = rows.indexOf(from);
441
-
460
+
442
461
  if (fromIndex > -1) {
443
-
462
+
444
463
  rows.splice(fromIndex, 1);
445
-
464
+
446
465
  toIndex = rows.indexOf(to);
447
-
466
+
448
467
  if (toIndex > -1) {
449
-
468
+
450
469
  if(after){
451
470
  rows.splice(toIndex+1, 0, from);
452
471
  }else{
453
472
  rows.splice(toIndex, 0, from);
454
473
  }
455
-
474
+
456
475
  }else{
457
476
  rows.splice(fromIndex, 0, from);
458
477
  }
459
478
  }
460
-
479
+
461
480
  //restyle rows
462
481
  if(rows === this.getDisplayRows()){
463
-
482
+
464
483
  start = fromIndex < toIndex ? fromIndex : toIndex;
465
484
  end = toIndex > fromIndex ? toIndex : fromIndex +1;
466
-
485
+
467
486
  for(let i = start; i <= end; i++){
468
487
  if(rows[i]){
469
488
  this.styleRow(rows[i], i);
@@ -472,104 +491,104 @@ export default class RowManager extends CoreFeature{
472
491
  }
473
492
  }
474
493
  }
475
-
494
+
476
495
  clearData(){
477
496
  this.setData([]);
478
497
  }
479
-
498
+
480
499
  getRowIndex(row){
481
500
  return this.findRowIndex(row, this.rows);
482
501
  }
483
-
502
+
484
503
  getDisplayRowIndex(row){
485
504
  var index = this.getDisplayRows().indexOf(row);
486
505
  return index > -1 ? index : false;
487
506
  }
488
-
507
+
489
508
  nextDisplayRow(row, rowOnly){
490
509
  var index = this.getDisplayRowIndex(row),
491
510
  nextRow = false;
492
-
493
-
511
+
512
+
494
513
  if(index !== false && index < this.displayRowsCount -1){
495
514
  nextRow = this.getDisplayRows()[index+1];
496
515
  }
497
-
516
+
498
517
  if(nextRow && (!(nextRow instanceof Row) || nextRow.type != "row")){
499
518
  return this.nextDisplayRow(nextRow, rowOnly);
500
519
  }
501
-
520
+
502
521
  return nextRow;
503
522
  }
504
-
523
+
505
524
  prevDisplayRow(row, rowOnly){
506
525
  var index = this.getDisplayRowIndex(row),
507
526
  prevRow = false;
508
-
527
+
509
528
  if(index){
510
529
  prevRow = this.getDisplayRows()[index-1];
511
530
  }
512
-
531
+
513
532
  if(rowOnly && prevRow && (!(prevRow instanceof Row) || prevRow.type != "row")){
514
533
  return this.prevDisplayRow(prevRow, rowOnly);
515
534
  }
516
-
535
+
517
536
  return prevRow;
518
537
  }
519
-
538
+
520
539
  findRowIndex(row, list){
521
540
  var rowIndex;
522
-
541
+
523
542
  row = this.findRow(row);
524
-
543
+
525
544
  if(row){
526
545
  rowIndex = list.indexOf(row);
527
-
546
+
528
547
  if(rowIndex > -1){
529
548
  return rowIndex;
530
549
  }
531
550
  }
532
-
551
+
533
552
  return false;
534
553
  }
535
-
554
+
536
555
  getData(active, transform){
537
556
  var output = [],
538
557
  rows = this.getRows(active);
539
-
558
+
540
559
  rows.forEach(function(row){
541
560
  if(row.type == "row"){
542
561
  output.push(row.getData(transform || "data"));
543
562
  }
544
563
  });
545
-
564
+
546
565
  return output;
547
566
  }
548
-
567
+
549
568
  getComponents(active){
550
569
  var output = [],
551
570
  rows = this.getRows(active);
552
-
571
+
553
572
  rows.forEach(function(row){
554
573
  output.push(row.getComponent());
555
574
  });
556
-
575
+
557
576
  return output;
558
577
  }
559
-
578
+
560
579
  getDataCount(active){
561
580
  var rows = this.getRows(active);
562
-
581
+
563
582
  return rows.length;
564
583
  }
565
-
584
+
566
585
  scrollHorizontal(left){
567
586
  this.scrollLeft = left;
568
587
  this.element.scrollLeft = left;
569
-
588
+
570
589
  this.dispatch("scroll-horizontal", left);
571
590
  }
572
-
591
+
573
592
  registerDataPipelineHandler(handler, priority){
574
593
  if(typeof priority !== "undefined"){
575
594
  this.dataPipeline.push({handler, priority})
@@ -580,7 +599,7 @@ export default class RowManager extends CoreFeature{
580
599
  console.error("Data pipeline handlers must have a priority in order to be registered")
581
600
  }
582
601
  }
583
-
602
+
584
603
  registerDisplayPipelineHandler(handler, priority){
585
604
  if(typeof priority !== "undefined"){
586
605
  this.displayPipeline.push({handler, priority})
@@ -591,7 +610,7 @@ export default class RowManager extends CoreFeature{
591
610
  console.error("Display pipeline handlers must have a priority in order to be registered")
592
611
  }
593
612
  }
594
-
613
+
595
614
  //set active data set
596
615
  refreshActiveData(handler, skipStage, renderInPosition){
597
616
  var table = this.table,
@@ -599,16 +618,16 @@ export default class RowManager extends CoreFeature{
599
618
  index = 0,
600
619
  cascadeOrder = ["all", "dataPipeline", "display", "displayPipeline", "end"],
601
620
  displayIndex;
602
-
603
-
621
+
622
+
604
623
  if(typeof handler === "function"){
605
624
  index = this.dataPipeline.findIndex((item) => {
606
625
  return item.handler === handler;
607
626
  });
608
-
627
+
609
628
  if(index > -1){
610
629
  stage = "dataPipeline";
611
-
630
+
612
631
  if(skipStage){
613
632
  if(index == this.dataPipeline.length - 1){
614
633
  stage = "display";
@@ -620,10 +639,10 @@ export default class RowManager extends CoreFeature{
620
639
  index = this.displayPipeline.findIndex((item) => {
621
640
  return item.handler === handler;
622
641
  });
623
-
642
+
624
643
  if(index > -1){
625
644
  stage = "displayPipeline";
626
-
645
+
627
646
  if(skipStage){
628
647
  if(index == this.displayPipeline.length - 1){
629
648
  stage = "end";
@@ -640,7 +659,7 @@ export default class RowManager extends CoreFeature{
640
659
  stage = handler || "all";
641
660
  index = 0;
642
661
  }
643
-
662
+
644
663
  if(this.redrawBlock){
645
664
  if(!this.redrawBlockRestoreConfig || (this.redrawBlockRestoreConfig && ((this.redrawBlockRestoreConfig.stage === stage && index < this.redrawBlockRestoreConfig.index) || (cascadeOrder.indexOf(stage) < cascadeOrder.indexOf(this.redrawBlockRestoreConfig.stage))))){
646
665
  this.redrawBlockRestoreConfig = {
@@ -651,104 +670,109 @@ export default class RowManager extends CoreFeature{
651
670
  index:index,
652
671
  };
653
672
  }
654
-
673
+
655
674
  return;
656
675
  }else{
657
- this.dispatch("data-refeshing");
658
-
659
- if(!handler){
660
- this.activeRowsPipeline[0] = this.rows.slice(0);
661
- }
662
-
663
- //cascade through data refresh stages
664
- switch(stage){
665
- case "all":
666
- //handle case where alldata needs refreshing
667
-
668
- case "dataPipeline":
669
-
670
- for(let i = index; i < this.dataPipeline.length; i++){
671
- let result = this.dataPipeline[i].handler(this.activeRowsPipeline[i].slice(0));
672
-
673
- this.activeRowsPipeline[i + 1] = result || this.activeRowsPipeline[i].slice(0);
674
- }
675
-
676
- this.setActiveRows(this.activeRowsPipeline[this.dataPipeline.length]);
677
-
678
- this.regenerateRowNumbers();
679
-
680
- case "display":
681
- index = 0;
682
- this.resetDisplayRows();
683
-
684
- case "displayPipeline":
685
- for(let i = index; i < this.displayPipeline.length; i++){
686
- let result = this.displayPipeline[i].handler((i ? this.getDisplayRows(i - 1) : this.activeRows).slice(0), renderInPosition);
687
-
688
- this.setDisplayRows(result || this.getDisplayRows(i - 1).slice(0), i);
689
- }
690
-
691
- case "end":
692
- //case to handle scenario when trying to skip past end stage
693
- }
694
-
695
676
  if(Helpers.elVisible(this.element)){
696
677
  if(renderInPosition){
697
- this.reRenderInPosition();
678
+ this.reRenderInPosition(this.refreshPipelines.bind(this, handler, stage, index, renderInPosition));
698
679
  }else{
699
-
680
+ this.refreshPipelines(handler, stage, index, renderInPosition);
681
+
700
682
  if(!handler){
701
683
  this.table.columnManager.renderer.renderColumns();
702
684
  }
703
-
685
+
704
686
  this.renderTable();
705
-
687
+
706
688
  if(table.options.layoutColumnsOnNewData){
707
689
  this.table.columnManager.redraw(true);
708
690
  }
709
691
  }
692
+ }else{
693
+ this.refreshPipelines(handler, stage, index, renderInPosition);
710
694
  }
711
-
712
- this.dispatch("data-refeshed");
695
+
696
+ this.dispatch("data-refreshed");
713
697
  }
714
698
  }
715
-
699
+
700
+ refreshPipelines(handler, stage, index, renderInPosition){
701
+ this.dispatch("data-refreshing");
702
+
703
+ if(!handler){
704
+ this.activeRowsPipeline[0] = this.rows.slice(0);
705
+ }
706
+
707
+ //cascade through data refresh stages
708
+ switch(stage){
709
+ case "all":
710
+ //handle case where alldata needs refreshing
711
+
712
+ case "dataPipeline":
713
+
714
+ for(let i = index; i < this.dataPipeline.length; i++){
715
+ let result = this.dataPipeline[i].handler(this.activeRowsPipeline[i].slice(0));
716
+
717
+ this.activeRowsPipeline[i + 1] = result || this.activeRowsPipeline[i].slice(0);
718
+ }
719
+
720
+ this.setActiveRows(this.activeRowsPipeline[this.dataPipeline.length]);
721
+
722
+ this.regenerateRowNumbers();
723
+
724
+ case "display":
725
+ index = 0;
726
+ this.resetDisplayRows();
727
+
728
+ case "displayPipeline":
729
+ for(let i = index; i < this.displayPipeline.length; i++){
730
+ let result = this.displayPipeline[i].handler((i ? this.getDisplayRows(i - 1) : this.activeRows).slice(0), renderInPosition);
731
+
732
+ this.setDisplayRows(result || this.getDisplayRows(i - 1).slice(0), i);
733
+ }
734
+
735
+ case "end":
736
+ //case to handle scenario when trying to skip past end stage
737
+ }
738
+ }
739
+
716
740
  //regenerate row numbers for row number formatter if in use
717
741
  regenerateRowNumbers(){
718
742
  if(this.rowNumColumn){
719
743
  this.activeRows.forEach((row) => {
720
744
  var cell = row.getCell(this.rowNumColumn);
721
-
745
+
722
746
  if(cell){
723
747
  cell._generateContents();
724
748
  }
725
749
  });
726
750
  }
727
751
  }
728
-
752
+
729
753
  setActiveRows(activeRows){
730
754
  this.activeRows = activeRows;
731
755
  this.activeRowsCount = this.activeRows.length;
732
756
  }
733
-
757
+
734
758
  //reset display rows array
735
759
  resetDisplayRows(){
736
760
  this.displayRows = [];
737
-
761
+
738
762
  this.displayRows.push(this.activeRows.slice(0));
739
-
763
+
740
764
  this.displayRowsCount = this.displayRows[0].length;
741
765
  }
742
-
766
+
743
767
  getNextDisplayIndex(){
744
768
  return this.displayRows.length;
745
769
  }
746
-
770
+
747
771
  //set display row pipeline data
748
772
  setDisplayRows(displayRows, index){
749
-
773
+
750
774
  var output = true;
751
-
775
+
752
776
  if(index && typeof this.displayRows[index] != "undefined"){
753
777
  this.displayRows[index] = displayRows;
754
778
  output = true;
@@ -756,14 +780,14 @@ export default class RowManager extends CoreFeature{
756
780
  this.displayRows.push(displayRows)
757
781
  output = index = this.displayRows.length -1;
758
782
  }
759
-
783
+
760
784
  if(index == this.displayRows.length -1){
761
785
  this.displayRowsCount = this.displayRows[this.displayRows.length -1].length;
762
786
  }
763
-
787
+
764
788
  return output;
765
789
  }
766
-
790
+
767
791
  getDisplayRows(index){
768
792
  if(typeof index == "undefined"){
769
793
  return this.displayRows.length ? this.displayRows[this.displayRows.length -1] : [];
@@ -771,49 +795,49 @@ export default class RowManager extends CoreFeature{
771
795
  return this.displayRows[index] || [];
772
796
  }
773
797
  }
774
-
798
+
775
799
  getVisibleRows(chain, viewable){
776
800
  var rows = Object.assign([], this.renderer.visibleRows(!viewable));
777
-
801
+
778
802
  if(chain){
779
803
  rows = this.chain("rows-visible", [viewable], rows, rows);
780
804
  }
781
-
805
+
782
806
  return rows;
783
807
  }
784
-
808
+
785
809
  //repeat action accross display rows
786
810
  displayRowIterator(callback){
787
811
  this.activeRowsPipeline.forEach(callback);
788
812
  this.displayRows.forEach(callback);
789
-
813
+
790
814
  this.displayRowsCount = this.displayRows[this.displayRows.length -1].length;
791
815
  }
792
-
816
+
793
817
  //return only actual rows (not group headers etc)
794
818
  getRows(type){
795
819
  var rows;
796
-
820
+
797
821
  switch(type){
798
822
  case "active":
799
823
  rows = this.activeRows;
800
824
  break;
801
-
825
+
802
826
  case "display":
803
827
  rows = this.table.rowManager.getDisplayRows();
804
828
  break;
805
-
829
+
806
830
  case "visible":
807
- rows = this.getVisibleRows(true);
831
+ rows = this.getVisibleRows(false, true);
808
832
  break;
809
-
833
+
810
834
  default:
811
835
  rows = this.chain("rows-retrieve", type, null, this.rows) || this.rows;
812
836
  }
813
-
837
+
814
838
  return rows;
815
839
  }
816
-
840
+
817
841
  ///////////////// Table Rendering /////////////////
818
842
  //trigger rerender of table in current position
819
843
  reRenderInPosition(callback){
@@ -821,31 +845,31 @@ export default class RowManager extends CoreFeature{
821
845
  if(callback){
822
846
  callback();
823
847
  }else{
824
- this.redrawBlockRederInPosition = true;
848
+ this.redrawBlockRenderInPosition = true;
825
849
  }
826
850
  }else{
827
851
  this.renderer.rerenderRows(callback);
828
852
  }
829
853
  }
830
-
854
+
831
855
  initializeRenderer(){
832
856
  var renderClass;
833
-
857
+
834
858
  var renderers = {
835
859
  "virtual": RendererVirtualDomVertical,
836
860
  "basic": RendererBasicVertical,
837
861
  };
838
-
862
+
839
863
  if(typeof this.table.options.renderVertical === "string"){
840
864
  renderClass = renderers[this.table.options.renderVertical];
841
865
  }else{
842
866
  renderClass = this.table.options.renderVertical;
843
867
  }
844
-
868
+
845
869
  if(renderClass){
846
870
  this.renderer = new renderClass(this.table, this.element, this.tableElement);
847
871
  this.renderer.initialize();
848
-
872
+
849
873
  if((this.table.element.clientHeight || this.table.options.height)){
850
874
  this.fixedHeight = true;
851
875
  }else{
@@ -855,21 +879,21 @@ export default class RowManager extends CoreFeature{
855
879
  console.error("Unable to find matching renderer:", table.options.renderVertical);
856
880
  }
857
881
  }
858
-
882
+
859
883
  getRenderMode(){
860
884
  return this.renderMode;
861
885
  }
862
-
886
+
863
887
  renderTable(){
864
888
  this.dispatchExternal("renderStarted");
865
-
889
+
866
890
  this.element.scrollTop = 0;
867
-
891
+
868
892
  this._clearTable();
869
-
893
+
870
894
  if(this.displayRowsCount){
871
895
  this.renderer.renderRows();
872
-
896
+
873
897
  if(this.firstRender){
874
898
  this.firstRender = false;
875
899
  this.layoutRefresh();
@@ -877,23 +901,23 @@ export default class RowManager extends CoreFeature{
877
901
  }else{
878
902
  this.renderEmptyScroll();
879
903
  }
880
-
904
+
881
905
  if(!this.fixedHeight){
882
906
  this.adjustTableSize();
883
907
  }
884
-
908
+
885
909
  this.dispatch("table-layout");
886
-
910
+
887
911
  if(!this.displayRowsCount){
888
912
  this._showPlaceholder();
889
913
  }
890
-
914
+
891
915
  this.dispatchExternal("renderComplete");
892
916
  }
893
-
917
+
894
918
  //show scrollbars on empty table div
895
919
  renderEmptyScroll(){
896
- if(this.table.options.placeholder){
920
+ if(this.placeholder){
897
921
  this.tableElement.style.display = "none";
898
922
  }else{
899
923
  this.tableElement.style.minWidth = this.table.columnManager.getWidth() + "px";
@@ -901,37 +925,44 @@ export default class RowManager extends CoreFeature{
901
925
  // this.tableElement.style.visibility = "hidden";
902
926
  }
903
927
  }
904
-
928
+
905
929
  _clearTable(){
906
930
  var element = this.tableElement;
907
-
931
+
908
932
  this._clearPlaceholder();
909
-
933
+
910
934
  this.scrollTop = 0;
911
935
  this.scrollLeft = 0;
912
-
936
+
913
937
  this.renderer.clearRows();
914
938
  }
915
-
939
+
916
940
  _showPlaceholder(){
917
- if(this.table.options.placeholder){
918
-
919
- this.table.options.placeholder.setAttribute("tabulator-render-mode", this.renderMode);
920
-
921
- this.getElement().appendChild(this.table.options.placeholder);
922
- this.table.options.placeholder.style.width = this.table.columnManager.getWidth() + "px";
941
+ if(this.placeholder){
942
+ this.placeholder.setAttribute("tabulator-render-mode", this.renderMode);
943
+
944
+ this.getElement().appendChild(this.placeholder);
945
+ this._positionPlaceholder();
923
946
  }
924
947
  }
925
-
948
+
926
949
  _clearPlaceholder(){
927
- if(this.table.options.placeholder && this.table.options.placeholder.parentNode){
928
- this.table.options.placeholder.parentNode.removeChild(this.table.options.placeholder);
950
+ if(this.placeholder && this.placeholder.parentNode){
951
+ this.placeholder.parentNode.removeChild(this.placeholder);
929
952
  }
930
953
  }
931
-
954
+
955
+ _positionPlaceholder(){
956
+ if(this.placeholder && this.placeholder.parentNode){
957
+ this.placeholder.style.width = this.table.columnManager.getWidth() + "px";
958
+ this.placeholderContents.style.width = this.table.rowManager.element.clientWidth + "px";
959
+ this.placeholderContents.style.marginLeft = this.scrollLeft + "px";
960
+ }
961
+ }
962
+
932
963
  styleRow(row, index){
933
964
  var rowEl = row.getElement();
934
-
965
+
935
966
  if(index % 2){
936
967
  rowEl.classList.add("tabulator-row-even");
937
968
  rowEl.classList.remove("tabulator-row-odd");
@@ -940,22 +971,22 @@ export default class RowManager extends CoreFeature{
940
971
  rowEl.classList.remove("tabulator-row-even");
941
972
  }
942
973
  }
943
-
974
+
944
975
  //normalize height of active rows
945
976
  normalizeHeight(){
946
977
  this.activeRows.forEach(function(row){
947
978
  row.normalizeHeight();
948
979
  });
949
980
  }
950
-
981
+
951
982
  //adjust the height of the table holder to fit in the Tabulator element
952
983
  adjustTableSize(){
953
984
  var initialHeight = this.element.clientHeight,
954
985
  modExists;
955
-
986
+
956
987
  if(this.renderer.verticalFillMode === "fill"){
957
988
  let otherHeight = Math.floor(this.table.columnManager.getElement().getBoundingClientRect().height + (this.table.footerManager && this.table.footerManager.active && !this.table.footerManager.external ? this.table.footerManager.getElement().getBoundingClientRect().height : 0));
958
-
989
+
959
990
  if(this.fixedHeight){
960
991
  this.element.style.minHeight = "calc(100% - " + otherHeight + "px)";
961
992
  this.element.style.height = "calc(100% - " + otherHeight + "px)";
@@ -965,9 +996,9 @@ export default class RowManager extends CoreFeature{
965
996
  this.element.style.height = (this.table.element.clientHeight - otherHeight) + "px";
966
997
  this.element.scrollTop = this.scrollTop;
967
998
  }
968
-
999
+
969
1000
  this.renderer.resize();
970
-
1001
+
971
1002
  //check if the table has changed size when dealing with variable height tables
972
1003
  if(!this.fixedHeight && initialHeight != this.element.clientHeight){
973
1004
  if(this.subscribed("table-resize")){
@@ -977,65 +1008,61 @@ export default class RowManager extends CoreFeature{
977
1008
  }
978
1009
  }
979
1010
  }
980
- }
981
1011
 
1012
+ this._positionPlaceholder();
1013
+ }
1014
+
982
1015
  //renitialize all rows
983
1016
  reinitialize(){
984
1017
  this.rows.forEach(function(row){
985
1018
  row.reinitialize(true);
986
1019
  });
987
1020
  }
988
-
1021
+
989
1022
  //prevent table from being redrawn
990
1023
  blockRedraw (){
991
1024
  this.redrawBlock = true;
992
1025
  this.redrawBlockRestoreConfig = false;
993
1026
  }
994
-
1027
+
995
1028
  //restore table redrawing
996
1029
  restoreRedraw (){
997
1030
  this.redrawBlock = false;
998
-
1031
+
999
1032
  if(this.redrawBlockRestoreConfig){
1000
1033
  this.refreshActiveData(this.redrawBlockRestoreConfig.handler, this.redrawBlockRestoreConfig.skipStage, this.redrawBlockRestoreConfig.renderInPosition)
1001
-
1034
+
1002
1035
  this.redrawBlockRestoreConfig = false;
1003
1036
  }else{
1004
- if(this.redrawBlockRederInPosition){
1037
+ if(this.redrawBlockRenderInPosition){
1005
1038
  this.reRenderInPosition();
1006
1039
  }
1007
1040
  }
1008
-
1009
- this.redrawBlockRederInPosition = false;
1041
+
1042
+ this.redrawBlockRenderInPosition = false;
1010
1043
  }
1011
-
1044
+
1012
1045
  //redraw table
1013
1046
  redraw (force){
1014
1047
  var pos = 0,
1015
1048
  left = this.scrollLeft;
1016
-
1049
+
1017
1050
  this.adjustTableSize();
1018
-
1051
+
1019
1052
  this.table.tableWidth = this.table.element.clientWidth;
1020
-
1053
+
1021
1054
  if(!force){
1022
1055
  this.reRenderInPosition();
1023
1056
  this.scrollHorizontal(left);
1024
-
1025
- if(!this.displayRowsCount){
1026
- if(this.table.options.placeholder){
1027
- this.getElement().appendChild(this.table.options.placeholder);
1028
- }
1029
- }
1030
1057
  }else{
1031
1058
  this.renderTable();
1032
1059
  }
1033
1060
  }
1034
-
1061
+
1035
1062
  resetScroll(){
1036
1063
  this.element.scrollLeft = 0;
1037
1064
  this.element.scrollTop = 0;
1038
-
1065
+
1039
1066
  if(this.table.browser === "ie"){
1040
1067
  var event = document.createEvent("Event");
1041
1068
  event.initEvent("scroll", false, true);