tabulator-tables 5.3.4 → 5.4.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 (86) hide show
  1. package/bower.json +1 -1
  2. package/build/Bundler.js +64 -38
  3. package/dist/css/tabulator.css +69 -19
  4. package/dist/css/tabulator.css.map +1 -1
  5. package/dist/css/tabulator.min.css +1 -1
  6. package/dist/css/tabulator.min.css.map +1 -1
  7. package/dist/css/tabulator_bootstrap3.css +69 -19
  8. package/dist/css/tabulator_bootstrap3.css.map +1 -1
  9. package/dist/css/tabulator_bootstrap3.min.css +1 -1
  10. package/dist/css/tabulator_bootstrap3.min.css.map +1 -1
  11. package/dist/css/tabulator_bootstrap4.css +69 -19
  12. package/dist/css/tabulator_bootstrap4.css.map +1 -1
  13. package/dist/css/tabulator_bootstrap4.min.css +1 -1
  14. package/dist/css/tabulator_bootstrap4.min.css.map +1 -1
  15. package/dist/css/tabulator_bootstrap5.css +69 -19
  16. package/dist/css/tabulator_bootstrap5.css.map +1 -1
  17. package/dist/css/tabulator_bootstrap5.min.css +1 -1
  18. package/dist/css/tabulator_bootstrap5.min.css.map +1 -1
  19. package/dist/css/tabulator_bulma.css +69 -19
  20. package/dist/css/tabulator_bulma.css.map +1 -1
  21. package/dist/css/tabulator_bulma.min.css +1 -1
  22. package/dist/css/tabulator_bulma.min.css.map +1 -1
  23. package/dist/css/tabulator_materialize.css +69 -19
  24. package/dist/css/tabulator_materialize.css.map +1 -1
  25. package/dist/css/tabulator_materialize.min.css +1 -1
  26. package/dist/css/tabulator_materialize.min.css.map +1 -1
  27. package/dist/css/tabulator_midnight.css +69 -19
  28. package/dist/css/tabulator_midnight.css.map +1 -1
  29. package/dist/css/tabulator_midnight.min.css +1 -1
  30. package/dist/css/tabulator_midnight.min.css.map +1 -1
  31. package/dist/css/tabulator_modern.css +69 -19
  32. package/dist/css/tabulator_modern.css.map +1 -1
  33. package/dist/css/tabulator_modern.min.css +1 -1
  34. package/dist/css/tabulator_modern.min.css.map +1 -1
  35. package/dist/css/tabulator_semanticui.css +69 -19
  36. package/dist/css/tabulator_semanticui.css.map +1 -1
  37. package/dist/css/tabulator_semanticui.min.css +1 -1
  38. package/dist/css/tabulator_semanticui.min.css.map +1 -1
  39. package/dist/css/tabulator_simple.css +69 -19
  40. package/dist/css/tabulator_simple.css.map +1 -1
  41. package/dist/css/tabulator_simple.min.css +1 -1
  42. package/dist/css/tabulator_simple.min.css.map +1 -1
  43. package/dist/css/tabulator_site.css +69 -19
  44. package/dist/css/tabulator_site.css.map +1 -1
  45. package/dist/css/tabulator_site.min.css +1 -1
  46. package/dist/css/tabulator_site.min.css.map +1 -1
  47. package/dist/js/tabulator.js +25853 -27494
  48. package/dist/js/tabulator.js.map +1 -1
  49. package/dist/js/tabulator.min.js +2 -2
  50. package/dist/js/tabulator.min.js.map +1 -1
  51. package/dist/js/tabulator_esm.js +738 -506
  52. package/dist/js/tabulator_esm.js.map +1 -1
  53. package/dist/js/tabulator_esm.min.js +2 -2
  54. package/dist/js/tabulator_esm.min.js.map +1 -1
  55. package/package.json +3 -6
  56. package/src/js/core/ColumnManager.js +30 -15
  57. package/src/js/core/RowManager.js +26 -0
  58. package/src/js/core/column/Column.js +4 -0
  59. package/src/js/core/column/defaults/options.js +1 -0
  60. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +100 -77
  61. package/src/js/core/row/Row.js +1 -1
  62. package/src/js/core/tools/InteractionMonitor.js +2 -0
  63. package/src/js/core/tools/Popup.js +98 -76
  64. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +185 -146
  65. package/src/js/modules/Download/defaults/downloaders/xlsx.js +2 -1
  66. package/src/js/modules/Edit/Edit.js +13 -2
  67. package/src/js/modules/Edit/List.js +1 -0
  68. package/src/js/modules/Filter/Filter.js +2 -2
  69. package/src/js/modules/Format/Format.js +46 -40
  70. package/src/js/modules/Format/defaults/formatters/responsiveCollapse.js +9 -1
  71. package/src/js/modules/FrozenColumns/FrozenColumns.js +24 -57
  72. package/src/js/modules/FrozenRows/FrozenRows.js +1 -1
  73. package/src/js/modules/GroupRows/Group.js +20 -28
  74. package/src/js/modules/GroupRows/GroupComponent.js +1 -1
  75. package/src/js/modules/GroupRows/GroupRows.js +8 -0
  76. package/src/js/modules/Interaction/Interaction.js +12 -0
  77. package/src/js/modules/Menu/Menu.js +31 -7
  78. package/src/js/modules/MoveColumns/MoveColumns.js +3 -3
  79. package/src/js/modules/Page/Page.js +1 -0
  80. package/src/js/modules/Persistence/Persistence.js +1 -0
  81. package/src/js/modules/Popup/Popup.js +42 -4
  82. package/src/js/modules/ResizeColumns/ResizeColumns.js +25 -6
  83. package/src/js/modules/ResizeTable/ResizeTable.js +7 -8
  84. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +21 -21
  85. package/src/js/modules/Sort/Sort.js +14 -2
  86. package/src/scss/tabulator.scss +92 -31
@@ -1,4 +1,4 @@
1
- /* Tabulator v5.3.4 (c) Oliver Folkerd 2022 */
1
+ /* Tabulator v5.4.1 (c) Oliver Folkerd 2022 */
2
2
  class CoreFeature{
3
3
 
4
4
  constructor(table){
@@ -190,60 +190,61 @@ class Helpers{
190
190
  class Popup extends CoreFeature{
191
191
  constructor(table, element, parent){
192
192
  super(table);
193
-
193
+
194
194
  this.element = element;
195
195
  this.container = this._lookupContainer();
196
-
196
+
197
197
  this.parent = parent;
198
-
198
+
199
199
  this.reversedX = false;
200
200
  this.childPopup = null;
201
201
  this.blurable = false;
202
202
  this.blurCallback = null;
203
+ this.blurEventsBound = false;
203
204
  this.renderedCallback = null;
204
-
205
+
205
206
  this.visible = false;
206
207
  this.hideable = true;
207
-
208
+
208
209
  this.element.classList.add("tabulator-popup-container");
209
-
210
+
210
211
  this.blurEvent = this.hide.bind(this, false);
211
212
  this.escEvent = this._escapeCheck.bind(this);
212
-
213
+
213
214
  this.destroyBinding = this.tableDestroyed;
214
215
  this.destroyed = false;
215
216
  }
216
-
217
+
217
218
  tableDestroyed(){
218
219
  this.destroyed = true;
219
220
  this.hide(true);
220
221
  }
221
-
222
+
222
223
  _lookupContainer(){
223
224
  var container = this.table.options.popupContainer;
224
-
225
+
225
226
  if(typeof container === "string"){
226
227
  container = document.querySelector(container);
227
-
228
+
228
229
  if(!container){
229
230
  console.warn("Menu Error - no container element found matching selector:", this.table.options.popupContainer , "(defaulting to document body)");
230
231
  }
231
232
  }else if (container === true){
232
233
  container = this.table.element;
233
234
  }
234
-
235
+
235
236
  if(container && !this._checkContainerIsParent(container)){
236
237
  container = false;
237
238
  console.warn("Menu Error - container element does not contain this table:", this.table.options.popupContainer , "(defaulting to document body)");
238
239
  }
239
-
240
+
240
241
  if(!container){
241
242
  container = document.body;
242
243
  }
243
-
244
+
244
245
  return container;
245
246
  }
246
-
247
+
247
248
  _checkContainerIsParent(container, element = this.table.element){
248
249
  if(container === element){
249
250
  return true;
@@ -251,119 +252,135 @@ class Popup extends CoreFeature{
251
252
  return element.parentNode ? this._checkContainerIsParent(container, element.parentNode) : false;
252
253
  }
253
254
  }
254
-
255
+
255
256
  renderCallback(callback){
256
257
  this.renderedCallback = callback;
257
258
  }
258
-
259
+
259
260
  containerEventCoords(e){
260
261
  var touch = !(e instanceof MouseEvent);
261
-
262
+
262
263
  var x = touch ? e.touches[0].pageX : e.pageX;
263
264
  var y = touch ? e.touches[0].pageY : e.pageY;
264
-
265
+
265
266
  if(this.container !== document.body){
266
267
  let parentOffset = Helpers.elOffset(this.container);
267
-
268
+
268
269
  x -= parentOffset.left;
269
270
  y -= parentOffset.top;
270
271
  }
271
-
272
+
272
273
  return {x, y};
273
274
  }
274
-
275
+
275
276
  elementPositionCoords(element, position = "right"){
276
277
  var offset = Helpers.elOffset(element),
277
278
  containerOffset, x, y;
278
-
279
+
279
280
  if(this.container !== document.body){
280
281
  containerOffset = Helpers.elOffset(this.container);
281
-
282
+
282
283
  offset.left -= containerOffset.left;
283
284
  offset.top -= containerOffset.top;
284
285
  }
285
-
286
+
286
287
  switch(position){
287
288
  case "right":
288
289
  x = offset.left + element.offsetWidth;
289
290
  y = offset.top - 1;
290
291
  break;
291
-
292
+
292
293
  case "bottom":
293
294
  x = offset.left;
294
295
  y = offset.top + element.offsetHeight;
295
296
  break;
297
+
298
+ case "left":
299
+ x = offset.left;
300
+ y = offset.top - 1;
301
+ break;
302
+
303
+ case "top":
304
+ x = offset.left;
305
+ y = offset.top;
306
+ break;
307
+
308
+ case "center":
309
+ x = offset.left + (element.offsetWidth / 2);
310
+ y = offset.top + (element.offsetHeight / 2);
311
+ break;
312
+
296
313
  }
297
-
314
+
298
315
  return {x, y, offset};
299
316
  }
300
-
317
+
301
318
  show(origin, position){
302
319
  var x, y, parentEl, parentOffset, coords;
303
-
320
+
304
321
  if(this.destroyed || this.table.destroyed){
305
322
  return this;
306
323
  }
307
-
324
+
308
325
  if(origin instanceof HTMLElement){
309
326
  parentEl = origin;
310
327
  coords = this.elementPositionCoords(origin, position);
311
-
328
+
312
329
  parentOffset = coords.offset;
313
330
  x = coords.x;
314
331
  y = coords.y;
315
-
332
+
316
333
  }else if(typeof origin === "number"){
317
334
  parentOffset = {top:0, left:0};
318
335
  x = origin;
319
336
  y = position;
320
337
  }else {
321
338
  coords = this.containerEventCoords(origin);
322
-
339
+
323
340
  x = coords.x;
324
341
  y = coords.y;
325
-
342
+
326
343
  this.reversedX = false;
327
344
  }
328
-
345
+
329
346
  this.element.style.top = y + "px";
330
347
  this.element.style.left = x + "px";
331
-
348
+
332
349
  this.container.appendChild(this.element);
333
-
350
+
334
351
  if(typeof this.renderedCallback === "function"){
335
352
  this.renderedCallback();
336
353
  }
337
-
354
+
338
355
  this._fitToScreen(x, y, parentEl, parentOffset, position);
339
-
356
+
340
357
  this.visible = true;
341
-
358
+
342
359
  this.subscribe("table-destroy", this.destroyBinding);
343
-
360
+
344
361
  this.element.addEventListener("mousedown", (e) => {
345
362
  e.stopPropagation();
346
363
  });
347
-
364
+
348
365
  return this;
349
366
  }
350
-
367
+
351
368
  _fitToScreen(x, y, parentEl, parentOffset, position){
352
369
  var scrollTop = this.container === document.body ? document.documentElement.scrollTop : this.container.scrollTop;
353
-
370
+
354
371
  //move menu to start on right edge if it is too close to the edge of the screen
355
372
  if((x + this.element.offsetWidth) >= this.container.offsetWidth || this.reversedX){
356
373
  this.element.style.left = "";
357
-
374
+
358
375
  if(parentEl){
359
376
  this.element.style.right = (this.container.offsetWidth - parentOffset.left) + "px";
360
377
  }else {
361
378
  this.element.style.right = (this.container.offsetWidth - x) + "px";
362
379
  }
363
-
380
+
364
381
  this.reversedX = true;
365
382
  }
366
-
383
+
367
384
  //move menu to start on bottom edge if it is too close to the edge of the screen
368
385
  if((y + this.element.offsetHeight) > Math.max(this.container.offsetHeight, scrollTop ? this.container.scrollHeight : 0)) {
369
386
  if(parentEl){
@@ -371,59 +388,62 @@ class Popup extends CoreFeature{
371
388
  case "bottom":
372
389
  this.element.style.top = (parseInt(this.element.style.top) - this.element.offsetHeight - parentEl.offsetHeight - 1) + "px";
373
390
  break;
374
-
391
+
375
392
  default:
376
393
  this.element.style.top = (parseInt(this.element.style.top) - this.element.offsetHeight + parentEl.offsetHeight + 1) + "px";
377
394
  }
378
-
395
+
379
396
  }else {
380
397
  this.element.style.top = (parseInt(this.element.style.top) - this.element.offsetHeight) + "px";
381
398
  }
382
399
  }
383
400
  }
384
-
401
+
385
402
  isVisible(){
386
403
  return this.visible;
387
404
  }
388
-
405
+
389
406
  hideOnBlur(callback){
390
407
  this.blurable = true;
391
-
408
+
392
409
  if(this.visible){
393
410
  setTimeout(() => {
394
- this.table.rowManager.element.addEventListener("scroll", this.blurEvent);
395
- this.subscribe("cell-editing", this.blurEvent);
396
- document.body.addEventListener("click", this.blurEvent);
397
- document.body.addEventListener("contextmenu", this.blurEvent);
398
- document.body.addEventListener("mousedown", this.blurEvent);
399
- window.addEventListener("resize", this.blurEvent);
400
- document.body.addEventListener("keydown", this.escEvent);
411
+ if(this.visible){
412
+ this.table.rowManager.element.addEventListener("scroll", this.blurEvent);
413
+ this.subscribe("cell-editing", this.blurEvent);
414
+ document.body.addEventListener("click", this.blurEvent);
415
+ document.body.addEventListener("contextmenu", this.blurEvent);
416
+ document.body.addEventListener("mousedown", this.blurEvent);
417
+ window.addEventListener("resize", this.blurEvent);
418
+ document.body.addEventListener("keydown", this.escEvent);
401
419
 
420
+ this.blurEventsBound = true;
421
+ }
402
422
  }, 100);
403
-
423
+
404
424
  this.blurCallback = callback;
405
425
  }
406
-
426
+
407
427
  return this;
408
428
  }
409
-
429
+
410
430
  _escapeCheck(e){
411
431
  if(e.keyCode == 27){
412
432
  this.hide();
413
433
  }
414
434
  }
415
-
435
+
416
436
  blockHide(){
417
437
  this.hideable = false;
418
438
  }
419
-
439
+
420
440
  restoreHide(){
421
441
  this.hideable = true;
422
442
  }
423
-
443
+
424
444
  hide(silent = false){
425
445
  if(this.visible && this.hideable){
426
- if(this.blurable){
446
+ if(this.blurable && this.blurEventsBound){
427
447
  document.body.removeEventListener("keydown", this.escEvent);
428
448
  document.body.removeEventListener("click", this.blurEvent);
429
449
  document.body.removeEventListener("contextmenu", this.blurEvent);
@@ -431,39 +451,41 @@ class Popup extends CoreFeature{
431
451
  window.removeEventListener("resize", this.blurEvent);
432
452
  this.table.rowManager.element.removeEventListener("scroll", this.blurEvent);
433
453
  this.unsubscribe("cell-editing", this.blurEvent);
454
+
455
+ this.blurEventsBound = false;
434
456
  }
435
-
457
+
436
458
  if(this.childPopup){
437
459
  this.childPopup.hide();
438
460
  }
439
-
461
+
440
462
  if(this.parent){
441
463
  this.parent.childPopup = null;
442
464
  }
443
-
465
+
444
466
  if(this.element.parentNode){
445
467
  this.element.parentNode.removeChild(this.element);
446
468
  }
447
-
469
+
448
470
  this.visible = false;
449
-
471
+
450
472
  if(this.blurCallback && !silent){
451
473
  this.blurCallback();
452
474
  }
453
-
475
+
454
476
  this.unsubscribe("table-destroy", this.destroyBinding);
455
477
  }
456
-
478
+
457
479
  return this;
458
480
  }
459
-
481
+
460
482
  child(element){
461
483
  if(this.childPopup){
462
484
  this.childPopup.hide();
463
485
  }
464
-
486
+
465
487
  this.childPopup = new Popup(this.table, element, this);
466
-
488
+
467
489
  return this.childPopup;
468
490
  }
469
491
  }
@@ -1984,6 +2006,7 @@ var defaultColumnOptions = {
1984
2006
  "variableHeight": undefined,
1985
2007
  "headerVertical": undefined,
1986
2008
  "headerHozAlign": undefined,
2009
+ "headerWordWrap": false,
1987
2010
  "editableTitle": undefined,
1988
2011
  };
1989
2012
 
@@ -2226,6 +2249,10 @@ class Column extends CoreFeature{
2226
2249
 
2227
2250
  var titleHolderElement = document.createElement("div");
2228
2251
  titleHolderElement.classList.add("tabulator-col-title");
2252
+
2253
+ if(def.headerWordWrap){
2254
+ titleHolderElement.classList.add("tabulator-col-title-wrap");
2255
+ }
2229
2256
 
2230
2257
  if(def.editableTitle){
2231
2258
  var titleElement = document.createElement("input");
@@ -3272,7 +3299,7 @@ class Row extends CoreFeature{
3272
3299
 
3273
3300
  if(cell){
3274
3301
  let value = column.getFieldValue(newRowData);
3275
- if(cell.getValue() != value){
3302
+ if(cell.getValue() !== value){
3276
3303
  cell.setValueProcessData(value);
3277
3304
 
3278
3305
  if(visible){
@@ -3552,10 +3579,10 @@ var defaultCalculations = {
3552
3579
  };
3553
3580
 
3554
3581
  class ColumnCalcs extends Module{
3555
-
3582
+
3556
3583
  constructor(table){
3557
3584
  super(table);
3558
-
3585
+
3559
3586
  this.topCalcs = [];
3560
3587
  this.botCalcs = [];
3561
3588
  this.genColumn = false;
@@ -3565,9 +3592,12 @@ class ColumnCalcs extends Module{
3565
3592
  this.botRow = false;
3566
3593
  this.topInitialized = false;
3567
3594
  this.botInitialized = false;
3568
-
3595
+
3596
+ this.blocked = false;
3597
+ this.recalcAfterBlock = false;
3598
+
3569
3599
  this.registerTableOption("columnCalcs", true);
3570
-
3600
+
3571
3601
  this.registerColumnOption("topCalc");
3572
3602
  this.registerColumnOption("topCalcParams");
3573
3603
  this.registerColumnOption("topCalcFormatter");
@@ -3577,16 +3607,16 @@ class ColumnCalcs extends Module{
3577
3607
  this.registerColumnOption("bottomCalcFormatter");
3578
3608
  this.registerColumnOption("bottomCalcFormatterParams");
3579
3609
  }
3580
-
3610
+
3581
3611
  createElement (){
3582
3612
  var el = document.createElement("div");
3583
3613
  el.classList.add("tabulator-calcs-holder");
3584
3614
  return el;
3585
3615
  }
3586
-
3616
+
3587
3617
  initialize(){
3588
3618
  this.genColumn = new Column({field:"value"}, this);
3589
-
3619
+
3590
3620
  this.subscribe("cell-value-changed", this.cellValueChanged.bind(this));
3591
3621
  this.subscribe("column-init", this.initializeColumnCheck.bind(this));
3592
3622
  this.subscribe("row-deleted", this.rowsUpdated.bind(this));
@@ -3597,43 +3627,69 @@ class ColumnCalcs extends Module{
3597
3627
  this.subscribe("data-refreshed", this.recalcActiveRowsRefresh.bind(this));
3598
3628
  this.subscribe("table-redraw", this.tableRedraw.bind(this));
3599
3629
  this.subscribe("rows-visible", this.visibleRows.bind(this));
3600
-
3630
+ this.subscribe("scrollbar-vertical", this.adjustForScrollbar.bind(this));
3631
+
3632
+ this.subscribe("redraw-blocked", this.blockRedraw.bind(this));
3633
+ this.subscribe("redraw-restored", this.restoreRedraw.bind(this));
3634
+
3601
3635
  this.registerTableFunction("getCalcResults", this.getResults.bind(this));
3602
3636
  this.registerTableFunction("recalc", this.userRecalc.bind(this));
3603
3637
  }
3604
-
3638
+
3605
3639
  tableRedraw(force){
3606
3640
  this.recalc(this.table.rowManager.activeRows);
3607
-
3641
+
3608
3642
  if(force){
3609
3643
  this.redraw();
3610
3644
  }
3611
3645
  }
3612
-
3613
-
3646
+
3647
+ blockRedraw(){
3648
+ this.blocked = true;
3649
+ this.recalcAfterBlock = false;
3650
+ }
3651
+
3652
+
3653
+ restoreRedraw(){
3654
+ this.blocked = false;
3655
+
3656
+ if(this.recalcAfterBlock){
3657
+ this.recalcAfterBlock = false;
3658
+ this.recalcActiveRowsRefresh();
3659
+ }
3660
+ }
3661
+
3614
3662
  ///////////////////////////////////
3615
3663
  ///////// Table Functions /////////
3616
3664
  ///////////////////////////////////
3617
3665
  userRecalc(){
3618
3666
  this.recalc(this.table.rowManager.activeRows);
3619
3667
  }
3620
-
3668
+
3621
3669
  ///////////////////////////////////
3622
3670
  ///////// Internal Logic //////////
3623
3671
  ///////////////////////////////////
3624
-
3672
+
3673
+ blockCheck(){
3674
+ if(this.blocked){
3675
+ this.recalcAfterBlock = true;
3676
+ }
3677
+
3678
+ return this.blocked;
3679
+ }
3680
+
3625
3681
  visibleRows(viewable, rows){
3626
3682
  if(this.topRow){
3627
3683
  rows.unshift(this.topRow);
3628
3684
  }
3629
-
3685
+
3630
3686
  if(this.botRow){
3631
3687
  rows.push(this.botRow);
3632
3688
  }
3633
-
3689
+
3634
3690
  return rows;
3635
3691
  }
3636
-
3692
+
3637
3693
  rowsUpdated(row){
3638
3694
  if(this.table.options.groupBy){
3639
3695
  this.recalcRowGroup(row);
@@ -3641,7 +3697,7 @@ class ColumnCalcs extends Module{
3641
3697
  this.recalcActiveRows();
3642
3698
  }
3643
3699
  }
3644
-
3700
+
3645
3701
  recalcActiveRowsRefresh(){
3646
3702
  if(this.table.options.groupBy && this.table.options.dataTreeStartExpanded && this.table.options.dataTree){
3647
3703
  this.recalcAll();
@@ -3649,18 +3705,18 @@ class ColumnCalcs extends Module{
3649
3705
  this.recalcActiveRows();
3650
3706
  }
3651
3707
  }
3652
-
3708
+
3653
3709
  recalcActiveRows(){
3654
3710
  this.recalc(this.table.rowManager.activeRows);
3655
3711
  }
3656
-
3712
+
3657
3713
  cellValueChanged(cell){
3658
3714
  if(cell.column.definition.topCalc || cell.column.definition.bottomCalc){
3659
3715
  if(this.table.options.groupBy){
3660
3716
  if(this.table.options.columnCalcs == "table" || this.table.options.columnCalcs == "both"){
3661
3717
  this.recalcActiveRows();
3662
3718
  }
3663
-
3719
+
3664
3720
  if(this.table.options.columnCalcs != "table"){
3665
3721
  this.recalcRowGroup(cell.row);
3666
3722
  }
@@ -3669,24 +3725,24 @@ class ColumnCalcs extends Module{
3669
3725
  }
3670
3726
  }
3671
3727
  }
3672
-
3728
+
3673
3729
  initializeColumnCheck(column){
3674
3730
  if(column.definition.topCalc || column.definition.bottomCalc){
3675
3731
  this.initializeColumn(column);
3676
3732
  }
3677
3733
  }
3678
-
3734
+
3679
3735
  //initialize column calcs
3680
3736
  initializeColumn(column){
3681
3737
  var def = column.definition;
3682
-
3738
+
3683
3739
  var config = {
3684
3740
  topCalcParams:def.topCalcParams || {},
3685
3741
  botCalcParams:def.bottomCalcParams || {},
3686
3742
  };
3687
-
3743
+
3688
3744
  if(def.topCalc){
3689
-
3745
+
3690
3746
  switch(typeof def.topCalc){
3691
3747
  case "string":
3692
3748
  if(ColumnCalcs.calculations[def.topCalc]){
@@ -3695,24 +3751,24 @@ class ColumnCalcs extends Module{
3695
3751
  console.warn("Column Calc Error - No such calculation found, ignoring: ", def.topCalc);
3696
3752
  }
3697
3753
  break;
3698
-
3754
+
3699
3755
  case "function":
3700
3756
  config.topCalc = def.topCalc;
3701
3757
  break;
3702
-
3758
+
3703
3759
  }
3704
-
3760
+
3705
3761
  if(config.topCalc){
3706
3762
  column.modules.columnCalcs = config;
3707
3763
  this.topCalcs.push(column);
3708
-
3764
+
3709
3765
  if(this.table.options.columnCalcs != "group"){
3710
3766
  this.initializeTopRow();
3711
3767
  }
3712
3768
  }
3713
-
3769
+
3714
3770
  }
3715
-
3771
+
3716
3772
  if(def.bottomCalc){
3717
3773
  switch(typeof def.bottomCalc){
3718
3774
  case "string":
@@ -3722,156 +3778,156 @@ class ColumnCalcs extends Module{
3722
3778
  console.warn("Column Calc Error - No such calculation found, ignoring: ", def.bottomCalc);
3723
3779
  }
3724
3780
  break;
3725
-
3781
+
3726
3782
  case "function":
3727
3783
  config.botCalc = def.bottomCalc;
3728
3784
  break;
3729
-
3785
+
3730
3786
  }
3731
-
3787
+
3732
3788
  if(config.botCalc){
3733
3789
  column.modules.columnCalcs = config;
3734
3790
  this.botCalcs.push(column);
3735
-
3791
+
3736
3792
  if(this.table.options.columnCalcs != "group"){
3737
3793
  this.initializeBottomRow();
3738
3794
  }
3739
3795
  }
3740
3796
  }
3741
-
3797
+
3742
3798
  }
3743
-
3799
+
3744
3800
  //dummy functions to handle being mock column manager
3745
3801
  registerColumnField(){}
3746
-
3802
+
3747
3803
  removeCalcs(){
3748
3804
  var changed = false;
3749
-
3805
+
3750
3806
  if(this.topInitialized){
3751
3807
  this.topInitialized = false;
3752
3808
  this.topElement.parentNode.removeChild(this.topElement);
3753
3809
  changed = true;
3754
3810
  }
3755
-
3811
+
3756
3812
  if(this.botInitialized){
3757
3813
  this.botInitialized = false;
3758
3814
  this.footerRemove(this.botElement);
3759
3815
  changed = true;
3760
3816
  }
3761
-
3817
+
3762
3818
  if(changed){
3763
3819
  this.table.rowManager.adjustTableSize();
3764
3820
  }
3765
3821
  }
3766
-
3822
+
3767
3823
  initializeTopRow(){
3768
3824
  if(!this.topInitialized){
3769
- this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
3825
+ this.table.columnManager.getContentsElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
3770
3826
  this.topInitialized = true;
3771
3827
  }
3772
3828
  }
3773
-
3829
+
3774
3830
  initializeBottomRow(){
3775
3831
  if(!this.botInitialized){
3776
3832
  this.footerPrepend(this.botElement);
3777
3833
  this.botInitialized = true;
3778
3834
  }
3779
3835
  }
3780
-
3836
+
3781
3837
  scrollHorizontal(left){
3782
3838
  if(this.botInitialized && this.botRow){
3783
- if(this.table.rtl){
3784
- this.botRow.getElement().style.marginRight = (left) + "px";
3785
- }else {
3786
- this.botRow.getElement().style.marginLeft = (-left) + "px";
3787
- }
3839
+ this.botElement.scrollLeft = left;
3788
3840
  }
3789
3841
  }
3790
-
3842
+
3791
3843
  recalc(rows){
3792
3844
  var data, row;
3793
-
3794
- if(this.topInitialized || this.botInitialized){
3795
- data = this.rowsToData(rows);
3796
-
3797
- if(this.topInitialized){
3798
- if(this.topRow){
3799
- this.topRow.deleteCells();
3845
+
3846
+ if(!this.blockCheck()){
3847
+ if(this.topInitialized || this.botInitialized){
3848
+ data = this.rowsToData(rows);
3849
+
3850
+ if(this.topInitialized){
3851
+ if(this.topRow){
3852
+ this.topRow.deleteCells();
3853
+ }
3854
+
3855
+ row = this.generateRow("top", data);
3856
+ this.topRow = row;
3857
+ while(this.topElement.firstChild) this.topElement.removeChild(this.topElement.firstChild);
3858
+ this.topElement.appendChild(row.getElement());
3859
+ row.initialize(true);
3800
3860
  }
3801
-
3802
- row = this.generateRow("top", data);
3803
- this.topRow = row;
3804
- while(this.topElement.firstChild) this.topElement.removeChild(this.topElement.firstChild);
3805
- this.topElement.appendChild(row.getElement());
3806
- row.initialize(true);
3807
- }
3808
-
3809
- if(this.botInitialized){
3810
- if(this.botRow){
3811
- this.botRow.deleteCells();
3861
+
3862
+ if(this.botInitialized){
3863
+ if(this.botRow){
3864
+ this.botRow.deleteCells();
3865
+ }
3866
+
3867
+ row = this.generateRow("bottom", data);
3868
+ this.botRow = row;
3869
+ while(this.botElement.firstChild) this.botElement.removeChild(this.botElement.firstChild);
3870
+ this.botElement.appendChild(row.getElement());
3871
+ row.initialize(true);
3872
+ }
3873
+
3874
+ this.table.rowManager.adjustTableSize();
3875
+
3876
+ //set resizable handles
3877
+ if(this.table.modExists("frozenColumns")){
3878
+ this.table.modules.frozenColumns.layout();
3812
3879
  }
3813
-
3814
- row = this.generateRow("bottom", data);
3815
- this.botRow = row;
3816
- while(this.botElement.firstChild) this.botElement.removeChild(this.botElement.firstChild);
3817
- this.botElement.appendChild(row.getElement());
3818
- row.initialize(true);
3819
- }
3820
-
3821
- this.table.rowManager.adjustTableSize();
3822
-
3823
- //set resizable handles
3824
- if(this.table.modExists("frozenColumns")){
3825
- this.table.modules.frozenColumns.layout();
3826
3880
  }
3827
3881
  }
3828
3882
  }
3829
-
3883
+
3830
3884
  recalcRowGroup(row){
3831
3885
  this.recalcGroup(this.table.modules.groupRows.getRowGroup(row));
3832
3886
  }
3833
-
3887
+
3834
3888
  recalcAll(){
3835
3889
  if(this.topCalcs.length || this.botCalcs.length){
3836
3890
  if(this.table.options.columnCalcs !== "group"){
3837
3891
  this.recalcActiveRows();
3838
3892
  }
3839
-
3893
+
3840
3894
  if(this.table.options.groupBy && this.table.options.columnCalcs !== "table"){
3841
-
3895
+
3842
3896
  var groups = this.table.modules.groupRows.getChildGroups();
3843
-
3897
+
3844
3898
  groups.forEach((group) => {
3845
3899
  this.recalcGroup(group);
3846
3900
  });
3847
3901
  }
3848
3902
  }
3849
3903
  }
3850
-
3904
+
3851
3905
  recalcGroup(group){
3852
3906
  var data, rowData;
3853
-
3854
- if(group){
3855
- if(group.calcs){
3856
- if(group.calcs.bottom){
3857
- data = this.rowsToData(group.rows);
3858
- rowData = this.generateRowData("bottom", data);
3859
-
3860
- group.calcs.bottom.updateData(rowData);
3861
- group.calcs.bottom.reinitialize();
3862
- }
3863
-
3864
- if(group.calcs.top){
3865
- data = this.rowsToData(group.rows);
3866
- rowData = this.generateRowData("top", data);
3867
-
3868
- group.calcs.top.updateData(rowData);
3869
- group.calcs.top.reinitialize();
3907
+
3908
+ if(!this.blockCheck()){
3909
+ if(group){
3910
+ if(group.calcs){
3911
+ if(group.calcs.bottom){
3912
+ data = this.rowsToData(group.rows);
3913
+ rowData = this.generateRowData("bottom", data);
3914
+
3915
+ group.calcs.bottom.updateData(rowData);
3916
+ group.calcs.bottom.reinitialize();
3917
+ }
3918
+
3919
+ if(group.calcs.top){
3920
+ data = this.rowsToData(group.rows);
3921
+ rowData = this.generateRowData("top", data);
3922
+
3923
+ group.calcs.top.updateData(rowData);
3924
+ group.calcs.top.reinitialize();
3925
+ }
3870
3926
  }
3871
3927
  }
3872
3928
  }
3873
3929
  }
3874
-
3930
+
3875
3931
  //generate top stats row
3876
3932
  generateTopRow(rows){
3877
3933
  return this.generateRow("top", this.rowsToData(rows));
@@ -3880,13 +3936,13 @@ class ColumnCalcs extends Module{
3880
3936
  generateBottomRow(rows){
3881
3937
  return this.generateRow("bottom", this.rowsToData(rows));
3882
3938
  }
3883
-
3939
+
3884
3940
  rowsToData(rows){
3885
3941
  var data = [];
3886
3942
 
3887
3943
  rows.forEach((row) => {
3888
3944
  data.push(row.getData());
3889
-
3945
+
3890
3946
  if(this.table.options.dataTree && this.table.options.dataTreeChildColumnCalcs){
3891
3947
  if(row.modules.dataTree && row.modules.dataTree.open){
3892
3948
  var children = this.rowsToData(this.table.modules.dataTree.getFilteredTreeChildren(row));
@@ -3894,47 +3950,47 @@ class ColumnCalcs extends Module{
3894
3950
  }
3895
3951
  }
3896
3952
  });
3897
-
3953
+
3898
3954
  return data;
3899
3955
  }
3900
-
3956
+
3901
3957
  //generate stats row
3902
3958
  generateRow(pos, data){
3903
3959
  var rowData = this.generateRowData(pos, data),
3904
3960
  row;
3905
-
3961
+
3906
3962
  if(this.table.modExists("mutator")){
3907
3963
  this.table.modules.mutator.disable();
3908
3964
  }
3909
-
3965
+
3910
3966
  row = new Row(rowData, this, "calc");
3911
-
3967
+
3912
3968
  if(this.table.modExists("mutator")){
3913
3969
  this.table.modules.mutator.enable();
3914
3970
  }
3915
-
3971
+
3916
3972
  row.getElement().classList.add("tabulator-calcs", "tabulator-calcs-" + pos);
3917
-
3973
+
3918
3974
  row.component = false;
3919
-
3975
+
3920
3976
  row.getComponent = () => {
3921
3977
  if(!row.component){
3922
3978
  row.component = new CalcComponent(row);
3923
3979
  }
3924
-
3980
+
3925
3981
  return row.component;
3926
3982
  };
3927
-
3983
+
3928
3984
  row.generateCells = () => {
3929
-
3985
+
3930
3986
  var cells = [];
3931
-
3987
+
3932
3988
  this.table.columnManager.columnsByIndex.forEach((column) => {
3933
-
3989
+
3934
3990
  //set field name of mock column
3935
3991
  this.genColumn.setField(column.getField());
3936
3992
  this.genColumn.hozAlign = column.hozAlign;
3937
-
3993
+
3938
3994
  if(column.definition[pos + "CalcFormatter"] && this.table.modExists("format")){
3939
3995
  this.genColumn.modules.format = {
3940
3996
  formatter: this.table.modules.format.getFormatter(column.definition[pos + "CalcFormatter"]),
@@ -3946,63 +4002,63 @@ class ColumnCalcs extends Module{
3946
4002
  params:{}
3947
4003
  };
3948
4004
  }
3949
-
4005
+
3950
4006
  //ensure css class definition is replicated to calculation cell
3951
4007
  this.genColumn.definition.cssClass = column.definition.cssClass;
3952
-
4008
+
3953
4009
  //generate cell and assign to correct column
3954
4010
  var cell = new Cell(this.genColumn, row);
3955
4011
  cell.getElement();
3956
4012
  cell.column = column;
3957
4013
  cell.setWidth();
3958
-
4014
+
3959
4015
  column.cells.push(cell);
3960
4016
  cells.push(cell);
3961
-
4017
+
3962
4018
  if(!column.visible){
3963
4019
  cell.hide();
3964
4020
  }
3965
4021
  });
3966
-
4022
+
3967
4023
  row.cells = cells;
3968
4024
  };
3969
-
4025
+
3970
4026
  return row;
3971
4027
  }
3972
-
4028
+
3973
4029
  //generate stats row
3974
4030
  generateRowData(pos, data){
3975
4031
  var rowData = {},
3976
4032
  calcs = pos == "top" ? this.topCalcs : this.botCalcs,
3977
4033
  type = pos == "top" ? "topCalc" : "botCalc",
3978
4034
  params, paramKey;
3979
-
4035
+
3980
4036
  calcs.forEach(function(column){
3981
4037
  var values = [];
3982
-
4038
+
3983
4039
  if(column.modules.columnCalcs && column.modules.columnCalcs[type]){
3984
4040
  data.forEach(function(item){
3985
4041
  values.push(column.getFieldValue(item));
3986
4042
  });
3987
-
4043
+
3988
4044
  paramKey = type + "Params";
3989
4045
  params = typeof column.modules.columnCalcs[paramKey] === "function" ? column.modules.columnCalcs[paramKey](values, data) : column.modules.columnCalcs[paramKey];
3990
-
4046
+
3991
4047
  column.setFieldValue(rowData, column.modules.columnCalcs[type](values, data, params));
3992
4048
  }
3993
4049
  });
3994
-
4050
+
3995
4051
  return rowData;
3996
4052
  }
3997
-
4053
+
3998
4054
  hasTopCalcs(){
3999
4055
  return !!(this.topCalcs.length);
4000
4056
  }
4001
-
4057
+
4002
4058
  hasBottomCalcs(){
4003
4059
  return !!(this.botCalcs.length);
4004
4060
  }
4005
-
4061
+
4006
4062
  //handle table redraw
4007
4063
  redraw(){
4008
4064
  if(this.topRow){
@@ -4012,15 +4068,15 @@ class ColumnCalcs extends Module{
4012
4068
  this.botRow.normalizeHeight(true);
4013
4069
  }
4014
4070
  }
4015
-
4071
+
4016
4072
  //return the calculated
4017
4073
  getResults(){
4018
4074
  var results = {},
4019
4075
  groups;
4020
-
4076
+
4021
4077
  if(this.table.options.groupBy && this.table.modExists("groupRows")){
4022
4078
  groups = this.table.modules.groupRows.getGroups(true);
4023
-
4079
+
4024
4080
  groups.forEach((group) => {
4025
4081
  results[group.getKey()] = this.getGroupResults(group);
4026
4082
  });
@@ -4030,29 +4086,39 @@ class ColumnCalcs extends Module{
4030
4086
  bottom: this.botRow ? this.botRow.getData() : {},
4031
4087
  };
4032
4088
  }
4033
-
4089
+
4034
4090
  return results;
4035
4091
  }
4036
-
4092
+
4037
4093
  //get results from a group
4038
4094
  getGroupResults(group){
4039
4095
  var groupObj = group._getSelf(),
4040
4096
  subGroups = group.getSubGroups(),
4041
4097
  subGroupResults = {},
4042
4098
  results = {};
4043
-
4099
+
4044
4100
  subGroups.forEach((subgroup) => {
4045
4101
  subGroupResults[subgroup.getKey()] = this.getGroupResults(subgroup);
4046
4102
  });
4047
-
4103
+
4048
4104
  results = {
4049
4105
  top: groupObj.calcs.top ? groupObj.calcs.top.getData() : {},
4050
4106
  bottom: groupObj.calcs.bottom ? groupObj.calcs.bottom.getData() : {},
4051
4107
  groups: subGroupResults,
4052
4108
  };
4053
-
4109
+
4054
4110
  return results;
4055
4111
  }
4112
+
4113
+ adjustForScrollbar(width){
4114
+ if(this.botRow){
4115
+ if(this.table.rtl){
4116
+ this.botElement.style.paddingLeft = width + "px";
4117
+ }else {
4118
+ this.botElement.style.paddingRight = width + "px";
4119
+ }
4120
+ }
4121
+ }
4056
4122
  }
4057
4123
 
4058
4124
  ColumnCalcs.moduleName = "columnCalcs";
@@ -4871,6 +4937,7 @@ function xlsx(list, options, setFileContents){
4871
4937
  sheetName = options.sheetName || "Sheet1",
4872
4938
  workbook = XLSX.utils.book_new(),
4873
4939
  tableFeatures = new CoreFeature(this),
4940
+ compression = 'compress' in options ? options.compress : true,
4874
4941
  output;
4875
4942
 
4876
4943
  workbook.SheetNames = [];
@@ -4958,7 +5025,7 @@ function xlsx(list, options, setFileContents){
4958
5025
  return buf;
4959
5026
  }
4960
5027
 
4961
- output = XLSX.write(workbook, {bookType:'xlsx', bookSST:true, type: 'binary'});
5028
+ output = XLSX.write(workbook, {bookType:'xlsx', bookSST:true, type: 'binary', compression });
4962
5029
 
4963
5030
  setFileContents(s2ab(output), "application/octet-stream");
4964
5031
  }
@@ -5948,6 +6015,7 @@ class Edit{
5948
6015
  this.listIteration = 0;
5949
6016
 
5950
6017
  this.lastAction="";
6018
+ this.filterTerm="";
5951
6019
 
5952
6020
  this.blurable = true;
5953
6021
 
@@ -7414,6 +7482,7 @@ class Edit$1 extends Module{
7414
7482
  this.subscribe("column-layout", this.initializeColumnCheck.bind(this));
7415
7483
  this.subscribe("column-delete", this.columnDeleteCheck.bind(this));
7416
7484
  this.subscribe("row-deleting", this.rowDeleteCheck.bind(this));
7485
+ this.subscribe("row-layout", this.rowEditableCheck.bind(this));
7417
7486
  this.subscribe("data-refreshing", this.cancelEdit.bind(this));
7418
7487
 
7419
7488
  this.subscribe("keybinding-nav-prev", this.navigatePrev.bind(this, undefined));
@@ -7518,7 +7587,7 @@ class Edit$1 extends Module{
7518
7587
  prevRow = this.table.rowManager.prevDisplayRow(cell.row, true);
7519
7588
 
7520
7589
  if(prevRow){
7521
- nextCell = this.findNextEditableCell(prevRow, prevRow.cells.length);
7590
+ nextCell = this.findPrevEditableCell(prevRow, prevRow.cells.length);
7522
7591
 
7523
7592
  if(nextCell){
7524
7593
  nextCell.getComponent().edit();
@@ -7708,6 +7777,14 @@ class Edit$1 extends Module{
7708
7777
  this.cancelEdit();
7709
7778
  }
7710
7779
  }
7780
+
7781
+ rowEditableCheck(row){
7782
+ row.getCells().forEach((cell) => {
7783
+ if(cell.column.modules.edit && typeof cell.column.modules.edit.check === "function"){
7784
+ this.updateCellClass(cell);
7785
+ }
7786
+ });
7787
+ }
7711
7788
 
7712
7789
  //initialize column editor
7713
7790
  initializeColumn(column){
@@ -7892,7 +7969,9 @@ class Edit$1 extends Module{
7892
7969
  if(cell.column.modules.edit){
7893
7970
  switch(typeof cell.column.modules.edit.check){
7894
7971
  case "function":
7895
- check = cell.column.modules.edit.check(cell.getComponent());
7972
+ if(cell.row.initialized){
7973
+ check = cell.column.modules.edit.check(cell.getComponent());
7974
+ }
7896
7975
  break;
7897
7976
 
7898
7977
  case "string":
@@ -9228,9 +9307,9 @@ class Filter extends Module{
9228
9307
  });
9229
9308
 
9230
9309
  editorElement.addEventListener("focus", (e) => {
9231
- var left = this.table.columnManager.element.scrollLeft;
9310
+ var left = this.table.columnManager.contentsElement.scrollLeft;
9232
9311
 
9233
- var headerPos = this.table.rowManager.element.scrollLeft + parseInt(this.table.columnManager.element.style.marginLeft);
9312
+ var headerPos = this.table.rowManager.element.scrollLeft;
9234
9313
 
9235
9314
  if(left !== headerPos){
9236
9315
  this.table.rowManager.scrollHorizontal(left);
@@ -10240,7 +10319,15 @@ function responsiveCollapse(cell, formatterParams, onRendered){
10240
10319
  config = cell.getRow()._row.modules.responsiveLayout;
10241
10320
 
10242
10321
  el.classList.add("tabulator-responsive-collapse-toggle");
10243
- el.innerHTML = "<span class='tabulator-responsive-collapse-toggle-open'>+</span><span class='tabulator-responsive-collapse-toggle-close'>-</span>";
10322
+
10323
+ el.innerHTML = `<svg class='tabulator-responsive-collapse-toggle-open' viewbox="0 0 24 24">
10324
+ <line x1="7" y1="12" x2="17" y2="12" fill="none" stroke-width="3" stroke-linecap="round" />
10325
+ <line y1="7" x1="12" y2="17" x2="12" fill="none" stroke-width="3" stroke-linecap="round" />
10326
+ </svg>
10327
+
10328
+ <svg class='tabulator-responsive-collapse-toggle-close' viewbox="0 0 24 24">
10329
+ <line x1="7" y1="12" x2="17" y2="12" fill="none" stroke-width="3" stroke-linecap="round" />
10330
+ </svg>`;
10244
10331
 
10245
10332
  cell.getElement().classList.add("tabulator-row-handle");
10246
10333
 
@@ -10355,13 +10442,13 @@ var defaultFormatters = {
10355
10442
  };
10356
10443
 
10357
10444
  class Format extends Module{
10358
-
10445
+
10359
10446
  constructor(table){
10360
10447
  super(table);
10361
-
10448
+
10362
10449
  this.registerColumnOption("formatter");
10363
10450
  this.registerColumnOption("formatterParams");
10364
-
10451
+
10365
10452
  this.registerColumnOption("formatterPrint");
10366
10453
  this.registerColumnOption("formatterPrintParams");
10367
10454
  this.registerColumnOption("formatterClipboard");
@@ -10371,35 +10458,35 @@ class Format extends Module{
10371
10458
  this.registerColumnOption("titleFormatter");
10372
10459
  this.registerColumnOption("titleFormatterParams");
10373
10460
  }
10374
-
10461
+
10375
10462
  initialize(){
10376
10463
  this.subscribe("cell-format", this.formatValue.bind(this));
10377
10464
  this.subscribe("cell-rendered", this.cellRendered.bind(this));
10378
10465
  this.subscribe("column-layout", this.initializeColumn.bind(this));
10379
10466
  this.subscribe("column-format", this.formatHeader.bind(this));
10380
10467
  }
10381
-
10468
+
10382
10469
  //initialize column formatter
10383
10470
  initializeColumn(column){
10384
10471
  column.modules.format = this.lookupFormatter(column, "");
10385
-
10472
+
10386
10473
  if(typeof column.definition.formatterPrint !== "undefined"){
10387
10474
  column.modules.format.print = this.lookupFormatter(column, "Print");
10388
10475
  }
10389
-
10476
+
10390
10477
  if(typeof column.definition.formatterClipboard !== "undefined"){
10391
10478
  column.modules.format.clipboard = this.lookupFormatter(column, "Clipboard");
10392
10479
  }
10393
-
10480
+
10394
10481
  if(typeof column.definition.formatterHtmlOutput !== "undefined"){
10395
10482
  column.modules.format.htmlOutput = this.lookupFormatter(column, "HtmlOutput");
10396
10483
  }
10397
10484
  }
10398
-
10485
+
10399
10486
  lookupFormatter(column, type){
10400
10487
  var config = {params:column.definition["formatter" + type + "Params"] || {}},
10401
10488
  formatter = column.definition["formatter" + type];
10402
-
10489
+
10403
10490
  //set column formatter
10404
10491
  switch(typeof formatter){
10405
10492
  case "string":
@@ -10410,97 +10497,103 @@ class Format extends Module{
10410
10497
  config.formatter = Format.formatters.plaintext;
10411
10498
  }
10412
10499
  break;
10413
-
10500
+
10414
10501
  case "function":
10415
10502
  config.formatter = formatter;
10416
10503
  break;
10417
-
10504
+
10418
10505
  default:
10419
10506
  config.formatter = Format.formatters.plaintext;
10420
10507
  break;
10421
10508
  }
10422
-
10509
+
10423
10510
  return config;
10424
10511
  }
10425
-
10512
+
10426
10513
  cellRendered(cell){
10427
10514
  if(cell.modules.format && cell.modules.format.renderedCallback && !cell.modules.format.rendered){
10428
10515
  cell.modules.format.renderedCallback();
10429
10516
  cell.modules.format.rendered = true;
10430
10517
  }
10431
10518
  }
10432
-
10519
+
10433
10520
  //return a formatted value for a column header
10434
10521
  formatHeader(column, title, el){
10435
10522
  var formatter, params, onRendered, mockCell;
10436
-
10523
+
10437
10524
  if(column.definition.titleFormatter){
10438
10525
  formatter = this.getFormatter(column.definition.titleFormatter);
10439
-
10526
+
10440
10527
  onRendered = (callback) => {
10441
10528
  column.titleFormatterRendered = callback;
10442
10529
  };
10443
-
10530
+
10444
10531
  mockCell = {
10445
10532
  getValue:function(){
10446
10533
  return title;
10447
10534
  },
10448
10535
  getElement:function(){
10449
10536
  return el;
10537
+ },
10538
+ getColumn:function(){
10539
+ return column.getComponent();
10540
+ },
10541
+ getTable:() => {
10542
+ return this.table;
10450
10543
  }
10451
10544
  };
10452
-
10545
+
10453
10546
  params = column.definition.titleFormatterParams || {};
10454
-
10547
+
10455
10548
  params = typeof params === "function" ? params() : params;
10456
-
10549
+
10457
10550
  return formatter.call(this, mockCell, params, onRendered);
10458
10551
  }else {
10459
10552
  return title;
10460
10553
  }
10461
10554
  }
10462
-
10463
-
10555
+
10556
+
10464
10557
  //return a formatted value for a cell
10465
10558
  formatValue(cell){
10466
10559
  var component = cell.getComponent(),
10467
10560
  params = typeof cell.column.modules.format.params === "function" ? cell.column.modules.format.params(component) : cell.column.modules.format.params;
10468
-
10561
+
10469
10562
  function onRendered(callback){
10470
10563
  if(!cell.modules.format){
10471
10564
  cell.modules.format = {};
10472
10565
  }
10473
-
10566
+
10474
10567
  cell.modules.format.renderedCallback = callback;
10475
10568
  cell.modules.format.rendered = false;
10476
10569
  }
10477
-
10570
+
10478
10571
  return cell.column.modules.format.formatter.call(this, component, params, onRendered);
10479
10572
  }
10480
-
10573
+
10481
10574
  formatExportValue(cell, type){
10482
10575
  var formatter = cell.column.modules.format[type],
10483
10576
  params;
10484
-
10577
+
10485
10578
  if(formatter){
10486
10579
  params = typeof formatter.params === "function" ? formatter.params(cell.getComponent()) : formatter.params;
10487
-
10580
+
10488
10581
  function onRendered(callback){
10489
10582
  if(!cell.modules.format){
10490
10583
  cell.modules.format = {};
10491
10584
  }
10492
-
10585
+
10493
10586
  cell.modules.format.renderedCallback = callback;
10494
10587
  cell.modules.format.rendered = false;
10495
10588
  }
10496
-
10589
+
10497
10590
  return formatter.formatter.call(this, cell.getComponent(), params, onRendered);
10498
-
10591
+
10499
10592
  }else {
10500
10593
  return this.formatValue(cell);
10501
10594
  }
10502
10595
  }
10503
-
10596
+
10504
10597
  sanitizeHTML(value){
10505
10598
  if(value){
10506
10599
  var entityMap = {
@@ -10513,7 +10606,7 @@ class Format extends Module{
10513
10606
  '`': '&#x60;',
10514
10607
  '=': '&#x3D;'
10515
10608
  };
10516
-
10609
+
10517
10610
  return String(value).replace(/[&<>"'`=/]/g, function (s) {
10518
10611
  return entityMap[s];
10519
10612
  });
@@ -10521,11 +10614,11 @@ class Format extends Module{
10521
10614
  return value;
10522
10615
  }
10523
10616
  }
10524
-
10617
+
10525
10618
  emptyToSpace(value){
10526
10619
  return value === null || typeof value === "undefined" || value === "" ? "&nbsp;" : value;
10527
10620
  }
10528
-
10621
+
10529
10622
  //get formatter for cell
10530
10623
  getFormatter(formatter){
10531
10624
  switch(typeof formatter){
@@ -10537,16 +10630,16 @@ class Format extends Module{
10537
10630
  formatter = Format.formatters.plaintext;
10538
10631
  }
10539
10632
  break;
10540
-
10633
+
10541
10634
  case "function":
10542
- //Custom formatter Function, do nothing
10635
+ //Custom formatter Function, do nothing
10543
10636
  break;
10544
-
10637
+
10545
10638
  default:
10546
10639
  formatter = Format.formatters.plaintext;
10547
10640
  break;
10548
10641
  }
10549
-
10642
+
10550
10643
  return formatter;
10551
10644
  }
10552
10645
  }
@@ -10563,9 +10656,6 @@ class FrozenColumns extends Module{
10563
10656
 
10564
10657
  this.leftColumns = [];
10565
10658
  this.rightColumns = [];
10566
- this.leftMargin = 0;
10567
- this.rightMargin = 0;
10568
- this.rightPadding = 0;
10569
10659
  this.initializationMode = "left";
10570
10660
  this.active = false;
10571
10661
  this.blocked = true;
@@ -10578,13 +10668,7 @@ class FrozenColumns extends Module{
10578
10668
  this.initializationMode = "left";
10579
10669
  this.leftColumns = [];
10580
10670
  this.rightColumns = [];
10581
- this.leftMargin = 0;
10582
- this.rightMargin = 0;
10583
- this.rightMargin = 0;
10584
10671
  this.active = false;
10585
-
10586
- this.table.columnManager.headersElement.style.marginLeft = 0;
10587
- this.table.columnManager.element.style.paddingRight = 0;
10588
10672
  }
10589
10673
 
10590
10674
  initialize(){
@@ -10593,8 +10677,6 @@ class FrozenColumns extends Module{
10593
10677
  this.subscribe("column-width", this.layout.bind(this));
10594
10678
  this.subscribe("row-layout-after", this.layoutRow.bind(this));
10595
10679
  this.subscribe("table-layout", this.layout.bind(this));
10596
- this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this));
10597
- this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this));
10598
10680
  this.subscribe("columns-loading", this.reset.bind(this));
10599
10681
 
10600
10682
  this.subscribe("column-add", this.reinitializeColumns.bind(this));
@@ -10603,6 +10685,7 @@ class FrozenColumns extends Module{
10603
10685
  this.subscribe("table-redraw", this.layout.bind(this));
10604
10686
  this.subscribe("layout-refreshing", this.blockLayout.bind(this));
10605
10687
  this.subscribe("layout-refreshed", this.unblockLayout.bind(this));
10688
+ this.subscribe("scrollbar-vertical", this.adjustForScrollbar.bind(this));
10606
10689
  }
10607
10690
 
10608
10691
  blockLayout(){
@@ -10652,40 +10735,14 @@ class FrozenColumns extends Module{
10652
10735
 
10653
10736
  frozenCheck(column){
10654
10737
  if(column.parent.isGroup && column.definition.frozen){
10655
- console.warn("Frozen Column Error - Parent column group must be frozen, not individual columns or sub column groups");
10656
- }
10657
-
10658
- if(column.parent.isGroup){
10659
- return this.frozenCheck(column.parent);
10660
- }else {
10661
- return column.definition.frozen;
10662
- }
10663
- }
10664
-
10665
- //quick layout to smooth horizontal scrolling
10666
- scrollHorizontal(){
10667
- if(this.active){
10668
- this.calcMargins(true);
10669
-
10670
- this.layoutColumnPosition();
10671
-
10672
- this.layoutCalcRows();
10673
-
10674
- this.reinitializeRows();
10675
- }
10676
- }
10677
-
10678
- //calculate margins for rows
10679
- calcMargins(scroll){
10680
-
10681
- if(!scroll){
10682
- this.leftMargin = this._calcSpace(this.leftColumns, this.leftColumns.length) + "px";
10683
- this.rightMargin = this._calcSpace(this.rightColumns, this.rightColumns.length) + "px";
10684
- this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
10738
+ console.warn("Frozen Column Error - Parent column group must be frozen, not individual columns or sub column groups");
10685
10739
  }
10686
10740
 
10687
- //calculate right frozen columns
10688
- this.rightPadding = this.table.rowManager.element.clientWidth + this.table.columnManager.scrollLeft;
10741
+ if(column.parent.isGroup){
10742
+ return this.frozenCheck(column.parent);
10743
+ }else {
10744
+ return column.definition.frozen;
10745
+ }
10689
10746
  }
10690
10747
 
10691
10748
  //layout calculation rows
@@ -10728,11 +10785,8 @@ class FrozenColumns extends Module{
10728
10785
  var leftMargin = 0;
10729
10786
  var rightMargin = 0;
10730
10787
 
10731
- this.table.columnManager.headersElement.style.marginLeft = this.leftMargin;
10732
- this.table.columnManager.element.style.paddingRight = this.rightMargin;
10733
-
10734
10788
  this.leftColumns.forEach((column, i) => {
10735
- column.modules.frozen.marginValue = leftMargin + this.table.columnManager.scrollLeft;
10789
+ column.modules.frozen.marginValue = leftMargin;
10736
10790
  column.modules.frozen.margin = column.modules.frozen.marginValue + "px";
10737
10791
 
10738
10792
  if(column.visible){
@@ -10768,20 +10822,19 @@ class FrozenColumns extends Module{
10768
10822
 
10769
10823
  this.rightColumns.forEach((column, i) => {
10770
10824
 
10825
+ column.modules.frozen.marginValue = rightMargin;
10826
+ column.modules.frozen.margin = column.modules.frozen.marginValue + "px";
10827
+
10771
10828
  if(column.visible){
10772
10829
  rightMargin += column.getWidth();
10773
10830
  }
10774
10831
 
10775
- column.modules.frozen.marginValue = this.rightPadding - rightMargin;
10776
- column.modules.frozen.margin = column.modules.frozen.marginValue + "px";
10777
-
10778
10832
  if(i == this.rightColumns.length - 1){
10779
10833
  column.modules.frozen.edge = true;
10780
10834
  }else {
10781
10835
  column.modules.frozen.edge = false;
10782
10836
  }
10783
10837
 
10784
-
10785
10838
  if(column.parent.isGroup){
10786
10839
  this.layoutElement(this.getColGroupParentElement(column), column);
10787
10840
  }else {
@@ -10803,12 +10856,10 @@ class FrozenColumns extends Module{
10803
10856
  //layout columns appropriately
10804
10857
  layout(){
10805
10858
  if(this.active && !this.blocked){
10806
- //calculate row padding
10807
- this.calcMargins();
10808
-
10859
+
10809
10860
  //calculate left columns
10810
10861
  this.layoutColumnPosition();
10811
-
10862
+
10812
10863
  this.reinitializeRows();
10813
10864
 
10814
10865
  this.layoutCalcRows();
@@ -10831,11 +10882,6 @@ class FrozenColumns extends Module{
10831
10882
  }
10832
10883
 
10833
10884
  layoutRow(row){
10834
- // console.trace("row")
10835
- var rowEl = row.getElement();
10836
-
10837
- rowEl.style.paddingLeft = this.leftMargin;
10838
-
10839
10885
  if(this.table.options.layout === "fitDataFill" && this.rightColumns.length){
10840
10886
  this.table.rowManager.getTableElement().style.minWidth = "calc(100% - " + this.rightMargin + ")";
10841
10887
  }
@@ -10858,11 +10904,19 @@ class FrozenColumns extends Module{
10858
10904
  }
10859
10905
 
10860
10906
  layoutElement(element, column){
10907
+ var position;
10861
10908
 
10862
10909
  if(column.modules.frozen){
10863
- element.style.position = "absolute";
10864
- element.style.left = column.modules.frozen.margin;
10865
-
10910
+ element.style.position = "sticky";
10911
+
10912
+ if(this.table.rtl){
10913
+ position = column.modules.frozen.position === "left" ? "right" : "left";
10914
+ }else {
10915
+ position = column.modules.frozen.position;
10916
+ }
10917
+
10918
+ element.style[position] = column.modules.frozen.margin;
10919
+
10866
10920
  element.classList.add("tabulator-frozen");
10867
10921
 
10868
10922
  if(column.modules.frozen.edge){
@@ -10870,6 +10924,12 @@ class FrozenColumns extends Module{
10870
10924
  }
10871
10925
  }
10872
10926
  }
10927
+
10928
+ adjustForScrollbar(width){
10929
+ if(this.rightColumns.length){
10930
+ this.table.columnManager.getContentsElement().style.width = "calc(100% - " + width + "px)";
10931
+ }
10932
+ }
10873
10933
 
10874
10934
  _calcSpace(columns, index){
10875
10935
  var width = 0;
@@ -10910,7 +10970,7 @@ class FrozenRows extends Module{
10910
10970
  this.topElement.classList.add("tabulator-frozen-rows-holder");
10911
10971
 
10912
10972
  // this.table.columnManager.element.append(this.topElement);
10913
- this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
10973
+ this.table.columnManager.getContentsElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
10914
10974
 
10915
10975
  this.subscribe("row-deleting", this.detachRow.bind(this));
10916
10976
  this.subscribe("rows-visible", this.visibleRows.bind(this));
@@ -11085,7 +11145,7 @@ class GroupComponent {
11085
11145
  }
11086
11146
 
11087
11147
  isVisible(){
11088
- return this._group._visible;
11148
+ return this._group.visible;
11089
11149
  }
11090
11150
 
11091
11151
  show(){
@@ -11356,38 +11416,41 @@ class Group{
11356
11416
  }
11357
11417
  }
11358
11418
 
11359
- getHeadersAndRows(noCalc){
11419
+ getHeadersAndRows(){
11360
11420
  var output = [];
11361
11421
 
11362
11422
  output.push(this);
11363
11423
 
11364
11424
  this._visSet();
11365
11425
 
11426
+
11427
+ if(this.calcs.top){
11428
+ this.calcs.top.detachElement();
11429
+ this.calcs.top.deleteCells();
11430
+ }
11431
+
11432
+ if(this.calcs.bottom){
11433
+ this.calcs.bottom.detachElement();
11434
+ this.calcs.bottom.deleteCells();
11435
+ }
11436
+
11437
+
11438
+
11366
11439
  if(this.visible){
11367
11440
  if(this.groupList.length){
11368
11441
  this.groupList.forEach(function(group){
11369
- output = output.concat(group.getHeadersAndRows(noCalc));
11442
+ output = output.concat(group.getHeadersAndRows());
11370
11443
  });
11371
11444
 
11372
11445
  }else {
11373
- if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11374
- if(this.calcs.top){
11375
- this.calcs.top.detachElement();
11376
- this.calcs.top.deleteCells();
11377
- }
11378
-
11446
+ if(this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11379
11447
  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
11380
11448
  output.push(this.calcs.top);
11381
11449
  }
11382
11450
 
11383
11451
  output = output.concat(this.rows);
11384
11452
 
11385
- if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11386
- if(this.calcs.bottom){
11387
- this.calcs.bottom.detachElement();
11388
- this.calcs.bottom.deleteCells();
11389
- }
11390
-
11453
+ if(this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11391
11454
  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
11392
11455
  output.push(this.calcs.bottom);
11393
11456
  }
@@ -11396,25 +11459,14 @@ class Group{
11396
11459
  if(!this.groupList.length && this.groupManager.table.options.columnCalcs != "table"){
11397
11460
 
11398
11461
  if(this.groupManager.table.modExists("columnCalcs")){
11399
-
11400
- if(!noCalc && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11401
- if(this.calcs.top){
11402
- this.calcs.top.detachElement();
11403
- this.calcs.top.deleteCells();
11404
- }
11405
-
11462
+ if(this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11406
11463
  if(this.groupManager.table.options.groupClosedShowCalcs){
11407
11464
  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
11408
11465
  output.push(this.calcs.top);
11409
11466
  }
11410
11467
  }
11411
11468
 
11412
- if(!noCalc && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11413
- if(this.calcs.bottom){
11414
- this.calcs.bottom.detachElement();
11415
- this.calcs.bottom.deleteCells();
11416
- }
11417
-
11469
+ if(this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11418
11470
  if(this.groupManager.table.options.groupClosedShowCalcs){
11419
11471
  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
11420
11472
  output.push(this.calcs.bottom);
@@ -11525,7 +11577,7 @@ class Group{
11525
11577
  prev = rowEl;
11526
11578
  });
11527
11579
  }
11528
-
11580
+
11529
11581
  this.groupManager.updateGroupRows(true);
11530
11582
  }else {
11531
11583
  this.groupManager.updateGroupRows(true);
@@ -12092,6 +12144,9 @@ class GroupRows extends Module{
12092
12144
  this.groupList.forEach(function(group){
12093
12145
  group.wipe();
12094
12146
  });
12147
+
12148
+ this.groupList = [];
12149
+ this.groups = {};
12095
12150
  }
12096
12151
  }
12097
12152
 
@@ -12178,8 +12233,13 @@ class GroupRows extends Module{
12178
12233
  this.assignRowToGroup(row, oldGroups);
12179
12234
  });
12180
12235
  }
12236
+
12237
+ Object.values(oldGroups).forEach((group) => {
12238
+ group.wipe();
12239
+ });
12181
12240
  }
12182
12241
 
12242
+
12183
12243
  createGroup(groupID, level, oldGroups){
12184
12244
  var groupKey = level + "_" + groupID,
12185
12245
  group;
@@ -12993,6 +13053,8 @@ class Interaction extends Module{
12993
13053
  rowMouseOver:"row-mouseover",
12994
13054
  rowMouseOut:"row-mouseout",
12995
13055
  rowMouseMove:"row-mousemove",
13056
+ rowMouseDown:"row-mousedown",
13057
+ rowMouseUp:"row-mouseup",
12996
13058
  rowTap:"row",
12997
13059
  rowDblTap:"row",
12998
13060
  rowTapHold:"row",
@@ -13006,6 +13068,8 @@ class Interaction extends Module{
13006
13068
  cellMouseOver:"cell-mouseover",
13007
13069
  cellMouseOut:"cell-mouseout",
13008
13070
  cellMouseMove:"cell-mousemove",
13071
+ cellMouseDown:"cell-mousedown",
13072
+ cellMouseUp:"cell-mouseup",
13009
13073
  cellTap:"cell",
13010
13074
  cellDblTap:"cell",
13011
13075
  cellTapHold:"cell",
@@ -13019,6 +13083,8 @@ class Interaction extends Module{
13019
13083
  headerMouseOver:"column-mouseover",
13020
13084
  headerMouseOut:"column-mouseout",
13021
13085
  headerMouseMove:"column-mousemove",
13086
+ headerMouseDown:"column-mousedown",
13087
+ headerMouseUp:"column-mouseup",
13022
13088
  headerTap:"column",
13023
13089
  headerDblTap:"column",
13024
13090
  headerTapHold:"column",
@@ -13032,6 +13098,8 @@ class Interaction extends Module{
13032
13098
  groupMouseOver:"group-mouseover",
13033
13099
  groupMouseOut:"group-mouseout",
13034
13100
  groupMouseMove:"group-mousemove",
13101
+ groupMouseDown:"group-mousedown",
13102
+ groupMouseUp:"group-mouseup",
13035
13103
  groupTap:"group",
13036
13104
  groupDblTap:"group",
13037
13105
  groupTapHold:"group",
@@ -13074,6 +13142,8 @@ class Interaction extends Module{
13074
13142
  this.registerColumnOption("headerMouseOver");
13075
13143
  this.registerColumnOption("headerMouseOut");
13076
13144
  this.registerColumnOption("headerMouseMove");
13145
+ this.registerColumnOption("headerMouseDown");
13146
+ this.registerColumnOption("headerMouseUp");
13077
13147
  this.registerColumnOption("headerTap");
13078
13148
  this.registerColumnOption("headerDblTap");
13079
13149
  this.registerColumnOption("headerTapHold");
@@ -13086,6 +13156,8 @@ class Interaction extends Module{
13086
13156
  this.registerColumnOption("cellMouseOver");
13087
13157
  this.registerColumnOption("cellMouseOut");
13088
13158
  this.registerColumnOption("cellMouseMove");
13159
+ this.registerColumnOption("cellMouseDown");
13160
+ this.registerColumnOption("cellMouseUp");
13089
13161
  this.registerColumnOption("cellTap");
13090
13162
  this.registerColumnOption("cellDblTap");
13091
13163
  this.registerColumnOption("cellTapHold");
@@ -13600,18 +13672,22 @@ class Menu extends Module{
13600
13672
  this.columnSubscribers = {};
13601
13673
 
13602
13674
  this.registerTableOption("menuContainer", undefined); //deprecated
13603
-
13675
+
13604
13676
  this.registerTableOption("rowContextMenu", false);
13605
13677
  this.registerTableOption("rowClickMenu", false);
13678
+ this.registerTableOption("rowDblClickMenu", false);
13606
13679
  this.registerTableOption("groupContextMenu", false);
13607
13680
  this.registerTableOption("groupClickMenu", false);
13681
+ this.registerTableOption("groupDblClickMenu", false);
13608
13682
 
13609
13683
  this.registerColumnOption("headerContextMenu");
13610
13684
  this.registerColumnOption("headerClickMenu");
13685
+ this.registerColumnOption("headerDblClickMenu");
13611
13686
  this.registerColumnOption("headerMenu");
13612
13687
  this.registerColumnOption("headerMenuIcon");
13613
13688
  this.registerColumnOption("contextMenu");
13614
13689
  this.registerColumnOption("clickMenu");
13690
+ this.registerColumnOption("dblClickMenu");
13615
13691
 
13616
13692
  }
13617
13693
 
@@ -13622,7 +13698,7 @@ class Menu extends Module{
13622
13698
 
13623
13699
  this.subscribe("column-init", this.initializeColumn.bind(this));
13624
13700
  }
13625
-
13701
+
13626
13702
  deprecatedOptionsCheck(){
13627
13703
  if(!this.deprecationCheck("menuContainer", "popupContainer")){
13628
13704
  this.table.options.popupContainer = this.table.options.menuContainer;
@@ -13638,6 +13714,10 @@ class Menu extends Module{
13638
13714
  if(this.table.options.rowClickMenu){
13639
13715
  this.subscribe("row-click", this.loadMenuEvent.bind(this, this.table.options.rowClickMenu));
13640
13716
  }
13717
+
13718
+ if(this.table.options.rowDblClickMenu){
13719
+ this.subscribe("row-dblclick", this.loadMenuEvent.bind(this, this.table.options.rowDblClickMenu));
13720
+ }
13641
13721
  }
13642
13722
 
13643
13723
  initializeGroupWatchers(){
@@ -13649,6 +13729,10 @@ class Menu extends Module{
13649
13729
  if(this.table.options.groupClickMenu){
13650
13730
  this.subscribe("group-click", this.loadMenuEvent.bind(this, this.table.options.groupClickMenu));
13651
13731
  }
13732
+
13733
+ if(this.table.options.groupDblClickMenu){
13734
+ this.subscribe("group-dblclick", this.loadMenuEvent.bind(this, this.table.options.groupDblClickMenu));
13735
+ }
13652
13736
  }
13653
13737
 
13654
13738
  initializeColumn(column){
@@ -13666,6 +13750,11 @@ class Menu extends Module{
13666
13750
  this.subscribe("column-click", this.columnSubscribers.headerClickMenu);
13667
13751
  }
13668
13752
 
13753
+ if(def.headerDblClickMenu && !this.columnSubscribers.headerDblClickMenu){
13754
+ this.columnSubscribers.headerDblClickMenu = this.loadMenuTableColumnEvent.bind(this, "headerDblClickMenu");
13755
+ this.subscribe("column-dblclick", this.columnSubscribers.headerDblClickMenu);
13756
+ }
13757
+
13669
13758
  if(def.headerMenu){
13670
13759
  this.initializeColumnHeaderMenu(column);
13671
13760
  }
@@ -13681,6 +13770,11 @@ class Menu extends Module{
13681
13770
  this.columnSubscribers.clickMenu = this.loadMenuTableCellEvent.bind(this, "clickMenu");
13682
13771
  this.subscribe("cell-click", this.columnSubscribers.clickMenu);
13683
13772
  }
13773
+
13774
+ if(def.dblClickMenu && !this.columnSubscribers.dblClickMenu){
13775
+ this.columnSubscribers.dblClickMenu = this.loadMenuTableCellEvent.bind(this, "dblClickMenu");
13776
+ this.subscribe("cell-dblclick", this.columnSubscribers.dblClickMenu);
13777
+ }
13684
13778
  }
13685
13779
 
13686
13780
  initializeColumnHeaderMenu(column){
@@ -13689,12 +13783,12 @@ class Menu extends Module{
13689
13783
 
13690
13784
  headerMenuEl = document.createElement("span");
13691
13785
  headerMenuEl.classList.add("tabulator-header-popup-button");
13692
-
13786
+
13693
13787
  if(icon){
13694
13788
  if(typeof icon === "function"){
13695
13789
  icon = icon(column.getComponent());
13696
13790
  }
13697
-
13791
+
13698
13792
  if(icon instanceof HTMLElement){
13699
13793
  headerMenuEl.appendChild(icon);
13700
13794
  }else {
@@ -13837,7 +13931,9 @@ class Menu extends Module{
13837
13931
  });
13838
13932
 
13839
13933
  menuEl.addEventListener("click", (e) => {
13840
- this.rootPopup.hide();
13934
+ if(this.rootPopup){
13935
+ this.rootPopup.hide();
13936
+ }
13841
13937
  });
13842
13938
 
13843
13939
  popup.show(parentEl || e);
@@ -13851,9 +13947,9 @@ class Menu extends Module{
13851
13947
  this.currentComponent = null;
13852
13948
  }
13853
13949
  });
13854
-
13950
+
13855
13951
  this.currentComponent = component;
13856
-
13952
+
13857
13953
  this.dispatchExternal("menuOpened", component.getComponent());
13858
13954
  }
13859
13955
  }
@@ -14024,7 +14120,7 @@ class MoveColumns extends Module{
14024
14120
 
14025
14121
  startMove(e, column){
14026
14122
  var element = column.getElement(),
14027
- headerElement = this.table.columnManager.getElement(),
14123
+ headerElement = this.table.columnManager.getContentsElement(),
14028
14124
  headersElement = this.table.columnManager.getHeadersElement();
14029
14125
 
14030
14126
  this.moving = column;
@@ -14043,7 +14139,7 @@ class MoveColumns extends Module{
14043
14139
  this.hoverElement = element.cloneNode(true);
14044
14140
  this.hoverElement.classList.add("tabulator-moving");
14045
14141
 
14046
- this.table.columnManager.getElement().appendChild(this.hoverElement);
14142
+ headerElement.appendChild(this.hoverElement);
14047
14143
 
14048
14144
  this.hoverElement.style.left = "0";
14049
14145
  this.hoverElement.style.bottom = (headerElement.clientHeight - headersElement.offsetHeight) + "px";
@@ -14125,7 +14221,7 @@ class MoveColumns extends Module{
14125
14221
  }
14126
14222
 
14127
14223
  moveHover(e){
14128
- var columnHolder = this.table.columnManager.getElement(),
14224
+ var columnHolder = this.table.columnManager.getContentsElement(),
14129
14225
  scrollLeft = columnHolder.scrollLeft,
14130
14226
  xPos = ((this.touchMove ? e.touches[0].pageX : e.pageX) - Helpers.elOffset(columnHolder).left) + scrollLeft,
14131
14227
  scrollPos;
@@ -15509,6 +15605,7 @@ class Page extends Module{
15509
15605
  if(!this.initialLoad){
15510
15606
  if(this.mode == "local" || force){
15511
15607
  this.page = 1;
15608
+ this.trackChanges();
15512
15609
  }
15513
15610
  }
15514
15611
  }
@@ -16083,6 +16180,7 @@ class Persistence extends Module{
16083
16180
  this.subscribe("group-changed", this.eventSave.bind(this, "group"));
16084
16181
  this.subscribe("page-changed", this.eventSave.bind(this, "page"));
16085
16182
  this.subscribe("column-resized", this.eventSave.bind(this, "columns"));
16183
+ this.subscribe("column-width", this.eventSave.bind(this, "columns"));
16086
16184
  this.subscribe("layout-refreshed", this.eventSave.bind(this, "columns"));
16087
16185
  }
16088
16186
 
@@ -16405,15 +16503,24 @@ class Popup$1 extends Module{
16405
16503
 
16406
16504
  this.registerTableOption("rowContextPopup", false);
16407
16505
  this.registerTableOption("rowClickPopup", false);
16506
+ this.registerTableOption("rowDblClickPopup", false);
16408
16507
  this.registerTableOption("groupContextPopup", false);
16409
16508
  this.registerTableOption("groupClickPopup", false);
16509
+ this.registerTableOption("groupDblClickPopup", false);
16410
16510
 
16411
16511
  this.registerColumnOption("headerContextPopup");
16412
16512
  this.registerColumnOption("headerClickPopup");
16513
+ this.registerColumnOption("headerDblClickPopup");
16413
16514
  this.registerColumnOption("headerPopup");
16414
16515
  this.registerColumnOption("headerPopupIcon");
16415
16516
  this.registerColumnOption("contextPopup");
16416
16517
  this.registerColumnOption("clickPopup");
16518
+ this.registerColumnOption("dblClickPopup");
16519
+
16520
+ this.registerComponentFunction("cell", "popup", this._componentPopupCall.bind(this));
16521
+ this.registerComponentFunction("column", "popup", this._componentPopupCall.bind(this));
16522
+ this.registerComponentFunction("row", "popup", this._componentPopupCall.bind(this));
16523
+ this.registerComponentFunction("group", "popup", this._componentPopupCall.bind(this));
16417
16524
 
16418
16525
  }
16419
16526
 
@@ -16423,6 +16530,10 @@ class Popup$1 extends Module{
16423
16530
 
16424
16531
  this.subscribe("column-init", this.initializeColumn.bind(this));
16425
16532
  }
16533
+
16534
+ _componentPopupCall(component, contents, position){
16535
+ this.loadPopupEvent(contents, null, component, position);
16536
+ }
16426
16537
 
16427
16538
  initializeRowWatchers(){
16428
16539
  if(this.table.options.rowContextPopup){
@@ -16433,6 +16544,10 @@ class Popup$1 extends Module{
16433
16544
  if(this.table.options.rowClickPopup){
16434
16545
  this.subscribe("row-click", this.loadPopupEvent.bind(this, this.table.options.rowClickPopup));
16435
16546
  }
16547
+
16548
+ if(this.table.options.rowDblClickPopup){
16549
+ this.subscribe("row-dblclick", this.loadPopupEvent.bind(this, this.table.options.rowDblClickPopup));
16550
+ }
16436
16551
  }
16437
16552
 
16438
16553
  initializeGroupWatchers(){
@@ -16444,6 +16559,10 @@ class Popup$1 extends Module{
16444
16559
  if(this.table.options.groupClickPopup){
16445
16560
  this.subscribe("group-click", this.loadPopupEvent.bind(this, this.table.options.groupClickPopup));
16446
16561
  }
16562
+
16563
+ if(this.table.options.groupDblClickPopup){
16564
+ this.subscribe("group-dblclick", this.loadPopupEvent.bind(this, this.table.options.groupDblClickPopup));
16565
+ }
16447
16566
  }
16448
16567
 
16449
16568
  initializeColumn(column){
@@ -16459,6 +16578,11 @@ class Popup$1 extends Module{
16459
16578
  if(def.headerClickPopup && !this.columnSubscribers.headerClickPopup){
16460
16579
  this.columnSubscribers.headerClickPopup = this.loadPopupTableColumnEvent.bind(this, "headerClickPopup");
16461
16580
  this.subscribe("column-click", this.columnSubscribers.headerClickPopup);
16581
+
16582
+
16583
+ }if(def.headerDblClickPopup && !this.columnSubscribers.headerDblClickPopup){
16584
+ this.columnSubscribers.headerDblClickPopup = this.loadPopupTableColumnEvent.bind(this, "headerDblClickPopup");
16585
+ this.subscribe("column-dblclick", this.columnSubscribers.headerDblClickPopup);
16462
16586
  }
16463
16587
 
16464
16588
  if(def.headerPopup){
@@ -16476,6 +16600,11 @@ class Popup$1 extends Module{
16476
16600
  this.columnSubscribers.clickPopup = this.loadPopupTableCellEvent.bind(this, "clickPopup");
16477
16601
  this.subscribe("cell-click", this.columnSubscribers.clickPopup);
16478
16602
  }
16603
+
16604
+ if(def.dblClickPopup && !this.columnSubscribers.dblClickPopup){
16605
+ this.columnSubscribers.dblClickPopup = this.loadPopupTableCellEvent.bind(this, "dblClickPopup");
16606
+ this.subscribe("cell-click", this.columnSubscribers.dblClickPopup);
16607
+ }
16479
16608
  }
16480
16609
 
16481
16610
  initializeColumnHeaderPopup(column){
@@ -16529,7 +16658,7 @@ class Popup$1 extends Module{
16529
16658
  }
16530
16659
  }
16531
16660
 
16532
- loadPopupEvent(contents, e, component){
16661
+ loadPopupEvent(contents, e, component, position){
16533
16662
  var renderedCallback;
16534
16663
 
16535
16664
  function onRendered(callback){
@@ -16544,10 +16673,10 @@ class Popup$1 extends Module{
16544
16673
 
16545
16674
  contents = typeof contents == "function" ? contents.call(this.table, e, component.getComponent(), onRendered) : contents;
16546
16675
 
16547
- this.loadPopup(e, component, contents, renderedCallback);
16676
+ this.loadPopup(e, component, contents, renderedCallback, position);
16548
16677
  }
16549
16678
 
16550
- loadPopup(e, component, contents, renderedCallback){
16679
+ loadPopup(e, component, contents, renderedCallback, position){
16551
16680
  var touch = !(e instanceof MouseEvent),
16552
16681
  contentsEl, popup;
16553
16682
 
@@ -16573,8 +16702,15 @@ class Popup$1 extends Module{
16573
16702
  if(typeof renderedCallback === "function"){
16574
16703
  popup.renderCallback(renderedCallback);
16575
16704
  }
16705
+
16706
+ if(e){
16707
+ popup.show(e);
16708
+ }else {
16709
+ popup.show(component.getElement(), position || "center");
16710
+ }
16711
+
16576
16712
 
16577
- popup.show(e).hideOnBlur(() => {
16713
+ popup.hideOnBlur(() => {
16578
16714
  this.dispatchExternal("popupClosed", component.getComponent());
16579
16715
  });
16580
16716
 
@@ -17191,15 +17327,32 @@ class ResizeColumns extends Module{
17191
17327
  }
17192
17328
  }
17193
17329
  }
17330
+
17331
+ frozenColumnOffset(column){
17332
+ var offset = false;
17333
+
17334
+ if(column.modules.frozen){
17335
+ offset = column.modules.frozen.marginValue;
17336
+
17337
+ if(column.modules.frozen.position === "left"){
17338
+ offset += column.getWidth() - 3;
17339
+ }else {
17340
+ if(offset){
17341
+ offset -= 3;
17342
+ }
17343
+ }
17344
+ }
17345
+
17346
+ return offset !== false ? offset + "px" : false;
17347
+ }
17194
17348
 
17195
17349
  reinitializeColumn(column){
17196
- var frozenOffset = column.modules.frozen ? (column.modules.frozen.marginValue + column.getWidth() + "px") : false;
17197
-
17350
+ var frozenOffset = this.frozenColumnOffset(column);
17198
17351
 
17199
17352
  column.cells.forEach((cell) => {
17200
17353
  if(cell.modules.resize && cell.modules.resize.handleEl){
17201
17354
  if(frozenOffset){
17202
- cell.modules.resize.handleEl.style.left = frozenOffset;
17355
+ cell.modules.resize.handleEl.style[column.modules.frozen.position] = frozenOffset;
17203
17356
  }
17204
17357
 
17205
17358
  cell.element.after(cell.modules.resize.handleEl);
@@ -17208,7 +17361,7 @@ class ResizeColumns extends Module{
17208
17361
 
17209
17362
  if(column.modules.resize && column.modules.resize.handleEl){
17210
17363
  if(frozenOffset){
17211
- column.modules.resize.handleEl.style.left = frozenOffset;
17364
+ column.modules.resize.handleEl.style[column.modules.frozen.position] = frozenOffset;
17212
17365
  }
17213
17366
 
17214
17367
  column.element.after(column.modules.resize.handleEl);
@@ -17260,8 +17413,8 @@ class ResizeColumns extends Module{
17260
17413
  });
17261
17414
 
17262
17415
  if(column.modules.frozen){
17263
- handle.style.position = "absolute";
17264
- handle.style.left = column.modules.frozen.marginValue + column.getWidth() + "px";
17416
+ handle.style.position = "sticky";
17417
+ handle.style[column.modules.frozen.position] = this.frozenColumnOffset(column);
17265
17418
  }
17266
17419
 
17267
17420
  config.handleEl = handle;
@@ -17373,6 +17526,8 @@ class ResizeColumns extends Module{
17373
17526
  self.table.element.classList.remove("tabulator-block-select");
17374
17527
 
17375
17528
  if(self.startWidth !== column.getWidth()){
17529
+ self.table.columnManager.verticalAlignHeaders();
17530
+
17376
17531
  self.dispatch("column-resized", column);
17377
17532
  self.table.externalEvents.dispatch("columnResized", column.getComponent());
17378
17533
  }
@@ -17565,7 +17720,7 @@ class ResizeTable extends Module{
17565
17720
  this.containerHeight = table.element.parentNode.clientHeight;
17566
17721
  this.containerWidth = table.element.parentNode.clientWidth;
17567
17722
  }
17568
-
17723
+
17569
17724
  this.redrawTable();
17570
17725
  }
17571
17726
  }
@@ -17617,17 +17772,16 @@ class ResizeTable extends Module{
17617
17772
  initializeVisibilityObserver(){
17618
17773
  this.visibilityObserver = new IntersectionObserver((entries) => {
17619
17774
  this.visible = entries[0].isIntersecting;
17620
-
17775
+
17621
17776
  if(!this.initialized){
17622
17777
  this.initialized = true;
17623
17778
  this.initialRedraw = !this.visible;
17779
+ }else {
17780
+ if(this.visible){
17781
+ this.redrawTable(this.initialRedraw);
17782
+ this.initialRedraw = false;
17783
+ }
17624
17784
  }
17625
-
17626
- if(this.visible){
17627
- this.redrawTable(this.initialRedraw);
17628
- this.initialRedraw = false;
17629
- }
17630
-
17631
17785
  });
17632
17786
 
17633
17787
  this.visibilityObserver.observe(this.table.element);
@@ -17848,22 +18002,21 @@ class ResponsiveLayout extends Module{
17848
18002
 
17849
18003
  //redraw columns to fit space
17850
18004
  update(){
17851
- var self = this,
17852
- working = true;
18005
+ var working = true;
17853
18006
 
17854
18007
  while(working){
17855
18008
 
17856
- let width = self.table.modules.layout.getMode() == "fitColumns" ? self.table.columnManager.getFlexBaseWidth() : self.table.columnManager.getWidth();
18009
+ let width = this.table.modules.layout.getMode() == "fitColumns" ? this.table.columnManager.getFlexBaseWidth() : this.table.columnManager.getWidth();
17857
18010
 
17858
- let diff = (self.table.options.headerVisible ? self.table.columnManager.element.clientWidth : self.table.element.clientWidth) - width;
18011
+ let diff = (this.table.options.headerVisible ? this.table.columnManager.element.clientWidth : this.table.element.clientWidth) - width;
17859
18012
 
17860
18013
  if(diff < 0){
17861
18014
  //table is too wide
17862
- let column = self.columns[self.index];
18015
+ let column = this.columns[this.index];
17863
18016
 
17864
18017
  if(column){
17865
- self.hideColumn(column);
17866
- self.index ++;
18018
+ this.hideColumn(column);
18019
+ this.index ++;
17867
18020
  }else {
17868
18021
  working = false;
17869
18022
  }
@@ -17871,13 +18024,13 @@ class ResponsiveLayout extends Module{
17871
18024
  }else {
17872
18025
 
17873
18026
  //table has spare space
17874
- let column = self.columns[self.index -1];
18027
+ let column = this.columns[this.index -1];
17875
18028
 
17876
18029
  if(column){
17877
18030
  if(diff > 0){
17878
18031
  if(diff >= column.getWidth()){
17879
- self.showColumn(column);
17880
- self.index --;
18032
+ this.showColumn(column);
18033
+ this.index --;
17881
18034
  }else {
17882
18035
  working = false;
17883
18036
  }
@@ -17889,18 +18042,17 @@ class ResponsiveLayout extends Module{
17889
18042
  }
17890
18043
  }
17891
18044
 
17892
- if(!self.table.rowManager.activeRowsCount){
17893
- self.table.rowManager.renderEmptyScroll();
18045
+ if(!this.table.rowManager.activeRowsCount){
18046
+ this.table.rowManager.renderEmptyScroll();
17894
18047
  }
17895
18048
  }
17896
18049
  }
17897
18050
 
17898
18051
  generateCollapsedContent(){
17899
- var self = this,
17900
- rows = this.table.rowManager.getDisplayRows();
18052
+ var rows = this.table.rowManager.getDisplayRows();
17901
18053
 
17902
- rows.forEach(function(row){
17903
- self.generateCollapsedRowContent(row);
18054
+ rows.forEach((row) => {
18055
+ this.generateCollapsedRowContent(row);
17904
18056
  });
17905
18057
  }
17906
18058
 
@@ -17920,16 +18072,15 @@ class ResponsiveLayout extends Module{
17920
18072
  }
17921
18073
 
17922
18074
  generateCollapsedRowData(row){
17923
- var self = this,
17924
- data = row.getData(),
18075
+ var data = row.getData(),
17925
18076
  output = [],
17926
18077
  mockCellComponent;
17927
18078
 
17928
- this.hiddenColumns.forEach(function(column){
18079
+ this.hiddenColumns.forEach((column) => {
17929
18080
  var value = column.getFieldValue(data);
17930
18081
 
17931
18082
  if(column.definition.title && column.field){
17932
- if(column.modules.format && self.table.options.responsiveLayoutCollapseUseFormatters){
18083
+ if(column.modules.format && this.table.options.responsiveLayoutCollapseUseFormatters){
17933
18084
 
17934
18085
  mockCellComponent = {
17935
18086
  value:false,
@@ -17949,6 +18100,9 @@ class ResponsiveLayout extends Module{
17949
18100
  getColumn:function(){
17950
18101
  return column.getComponent();
17951
18102
  },
18103
+ getTable:() => {
18104
+ return this.table;
18105
+ },
17952
18106
  };
17953
18107
 
17954
18108
  function onRendered(callback){
@@ -17958,7 +18112,7 @@ class ResponsiveLayout extends Module{
17958
18112
  output.push({
17959
18113
  field: column.field,
17960
18114
  title: column.definition.title,
17961
- value: column.modules.format.formatter.call(self.table.modules.format, mockCellComponent, column.modules.format.params, onRendered)
18115
+ value: column.modules.format.formatter.call(this.table.modules.format, mockCellComponent, column.modules.format.params, onRendered)
17962
18116
  });
17963
18117
  }else {
17964
18118
  output.push({
@@ -18722,6 +18876,7 @@ class Sort extends Module{
18722
18876
  this.registerTableOption("columnHeaderSortMulti", true); //multiple or single column sorting
18723
18877
  this.registerTableOption("sortOrderReverse", false); //reverse internal sort ordering
18724
18878
  this.registerTableOption("headerSortElement", "<div class='tabulator-arrow'></div>"); //header sort element
18879
+ this.registerTableOption("headerSortClickElement", "header"); //element which triggers sort when clicked
18725
18880
 
18726
18881
  this.registerColumnOption("sorter");
18727
18882
  this.registerColumnOption("sorterParams");
@@ -18819,10 +18974,21 @@ class Sort extends Module{
18819
18974
 
18820
18975
  colEl.classList.add("tabulator-sortable");
18821
18976
 
18822
-
18823
18977
  arrowEl = document.createElement("div");
18824
18978
  arrowEl.classList.add("tabulator-col-sorter");
18825
18979
 
18980
+ switch(this.table.options.headerSortClickElement){
18981
+ case "icon":
18982
+ arrowEl.classList.add("tabulator-col-sorter-element");
18983
+ break;
18984
+ case "header":
18985
+ colEl.classList.add("tabulator-col-sorter-element");
18986
+ break;
18987
+ default:
18988
+ colEl.classList.add("tabulator-col-sorter-element");
18989
+ break;
18990
+ }
18991
+
18826
18992
  switch(this.table.options.headerSortElement){
18827
18993
  case "function":
18828
18994
  //do nothing
@@ -18844,7 +19010,7 @@ class Sort extends Module{
18844
19010
  this.setColumnHeaderSortIcon(column, "none");
18845
19011
 
18846
19012
  //sort on click
18847
- colEl.addEventListener("click", (e) => {
19013
+ (this.table.options.headerSortClickElement === "icon" ? arrowEl : colEl).addEventListener("click", (e) => {
18848
19014
  var dir = "",
18849
19015
  sorters=[],
18850
19016
  match = false;
@@ -20115,7 +20281,7 @@ class VirtualDomHorizontal extends Renderer{
20115
20281
  this.windowBuffer = 200; //pixel margin to make column visible before it is shown on screen
20116
20282
 
20117
20283
  this.visibleRows = null;
20118
-
20284
+
20119
20285
  this.initialized = false;
20120
20286
  this.isFitData = false;
20121
20287
 
@@ -20128,53 +20294,29 @@ class VirtualDomHorizontal extends Renderer{
20128
20294
  this.vertScrollListen();
20129
20295
  }
20130
20296
 
20131
- compatibilityCheck(){
20132
- var columns = this.options("columns"),
20133
- frozen = false,
20134
- ok = true;
20135
-
20297
+ compatibilityCheck(){
20136
20298
  if(this.options("layout") == "fitDataTable"){
20137
20299
  console.warn("Horizontal Virtual DOM is not compatible with fitDataTable layout mode");
20138
- ok = false;
20139
20300
  }
20140
20301
 
20141
20302
  if(this.options("responsiveLayout")){
20142
20303
  console.warn("Horizontal Virtual DOM is not compatible with responsive columns");
20143
- ok = false;
20144
20304
  }
20145
20305
 
20146
20306
  if(this.options("rtl")){
20147
20307
  console.warn("Horizontal Virtual DOM is not currently compatible with RTL text direction");
20148
- ok = false;
20149
- }
20150
-
20151
- if(columns){
20152
- frozen = columns.find((col) => {
20153
- return col.frozen;
20154
- });
20155
-
20156
- if(frozen){
20157
- console.warn("Horizontal Virtual DOM is not compatible with frozen columns");
20158
- ok = false;
20159
- }
20160
20308
  }
20161
-
20162
- // if(!ok){
20163
- // options.virtualDomHoz = false;
20164
- // }
20165
-
20166
- return ok;
20167
20309
  }
20168
20310
 
20169
20311
  layoutCheck(){
20170
20312
  this.isFitData = this.options("layout").startsWith('fitData');
20171
20313
  }
20172
-
20314
+
20173
20315
  vertScrollListen(){
20174
20316
  this.subscribe("scroll-vertical", this.clearVisRowCache.bind(this));
20175
20317
  this.subscribe("data-refreshed", this.clearVisRowCache.bind(this));
20176
20318
  }
20177
-
20319
+
20178
20320
  clearVisRowCache(){
20179
20321
  this.visibleRows = null;
20180
20322
  }
@@ -20186,7 +20328,7 @@ class VirtualDomHorizontal extends Renderer{
20186
20328
  renderColumns(row, force){
20187
20329
  this.dataChange();
20188
20330
  }
20189
-
20331
+
20190
20332
 
20191
20333
  scrollColumns(left, dir){
20192
20334
  if(this.scrollLeft != left){
@@ -20220,7 +20362,6 @@ class VirtualDomHorizontal extends Renderer{
20220
20362
  },
20221
20363
  colPos = 0;
20222
20364
 
20223
-
20224
20365
  if(update && !this.initialized){
20225
20366
  return;
20226
20367
  }
@@ -20235,41 +20376,44 @@ class VirtualDomHorizontal extends Renderer{
20235
20376
  this.vDomScrollPosRight = this.scrollLeft + this.elementVertical.clientWidth + this.windowBuffer;
20236
20377
 
20237
20378
  this.table.columnManager.columnsByIndex.forEach((column) => {
20238
- var config = {};
20379
+ var config = {},
20380
+ width;
20239
20381
 
20240
20382
  if(column.visible){
20241
- var width = column.getWidth();
20242
-
20243
- config.leftPos = colPos;
20244
- config.rightPos = colPos + width;
20245
-
20246
- config.width = width;
20247
-
20248
- if (this.isFitData) {
20249
- config.fitDataCheck = column.modules.vdomHoz ? column.modules.vdomHoz.fitDataCheck : true;
20250
- }
20251
-
20252
- if((colPos + width > this.vDomScrollPosLeft) && (colPos < this.vDomScrollPosRight)){
20253
- //column is visible
20383
+ if(!column.modules.frozen){
20384
+ width = column.getWidth();
20385
+
20386
+ config.leftPos = colPos;
20387
+ config.rightPos = colPos + width;
20254
20388
 
20255
- if(this.leftCol == -1){
20256
- this.leftCol = this.columns.length;
20257
- this.vDomPadLeft = colPos;
20389
+ config.width = width;
20390
+
20391
+ if (this.isFitData) {
20392
+ config.fitDataCheck = column.modules.vdomHoz ? column.modules.vdomHoz.fitDataCheck : true;
20258
20393
  }
20259
20394
 
20260
- this.rightCol = this.columns.length;
20261
- }else {
20262
- // column is hidden
20263
- if(this.leftCol !== -1){
20264
- this.vDomPadRight += width;
20395
+ if((colPos + width > this.vDomScrollPosLeft) && (colPos < this.vDomScrollPosRight)){
20396
+ //column is visible
20397
+
20398
+ if(this.leftCol == -1){
20399
+ this.leftCol = this.columns.length;
20400
+ this.vDomPadLeft = colPos;
20401
+ }
20402
+
20403
+ this.rightCol = this.columns.length;
20404
+ }else {
20405
+ // column is hidden
20406
+ if(this.leftCol !== -1){
20407
+ this.vDomPadRight += width;
20408
+ }
20265
20409
  }
20410
+
20411
+ this.columns.push(column);
20412
+
20413
+ column.modules.vdomHoz = config;
20414
+
20415
+ colPos += width;
20266
20416
  }
20267
-
20268
- this.columns.push(column);
20269
-
20270
- column.modules.vdomHoz = config;
20271
-
20272
- colPos += width;
20273
20417
  }
20274
20418
  });
20275
20419
 
@@ -20361,7 +20505,7 @@ class VirtualDomHorizontal extends Renderer{
20361
20505
  }
20362
20506
 
20363
20507
  rowEl.parentNode.removeChild(rowEl);
20364
-
20508
+
20365
20509
  this.rerenderColumns(false, true);
20366
20510
  }
20367
20511
  }
@@ -20390,24 +20534,30 @@ class VirtualDomHorizontal extends Renderer{
20390
20534
  }
20391
20535
 
20392
20536
  reinitializeRows(){
20393
- var rows = this.getVisibleRows();
20394
- rows.forEach((row) => {
20537
+ var visibleRows = this.getVisibleRows(),
20538
+ otherRows = this.table.rowManager.getRows().filter(row => !visibleRows.includes(row));
20539
+
20540
+ visibleRows.forEach((row) => {
20395
20541
  this.reinitializeRow(row, true);
20396
20542
  });
20543
+
20544
+ otherRows.forEach((row) =>{
20545
+ row.deinitialize();
20546
+ });
20397
20547
  }
20398
20548
 
20399
20549
  getVisibleRows(){
20400
20550
  if (!this.visibleRows){
20401
20551
  this.visibleRows = this.table.rowManager.getVisibleRows();
20402
20552
  }
20403
-
20553
+
20404
20554
  return this.visibleRows;
20405
20555
  }
20406
20556
 
20407
20557
  scroll(diff){
20408
20558
  this.vDomScrollPosLeft += diff;
20409
20559
  this.vDomScrollPosRight += diff;
20410
-
20560
+
20411
20561
  if(Math.abs(diff) > (this.windowBuffer / 2)){
20412
20562
  this.rerenderColumns();
20413
20563
  }else {
@@ -20437,7 +20587,7 @@ class VirtualDomHorizontal extends Renderer{
20437
20587
  working = true;
20438
20588
 
20439
20589
  while(working){
20440
-
20590
+
20441
20591
  let column = this.columns[this.rightCol + 1];
20442
20592
 
20443
20593
  if(column){
@@ -20447,7 +20597,7 @@ class VirtualDomHorizontal extends Renderer{
20447
20597
  this.getVisibleRows().forEach((row) => {
20448
20598
  if(row.type !== "group"){
20449
20599
  var cell = row.getCell(column);
20450
- row.getElement().appendChild(cell.getElement());
20600
+ row.getElement().insertBefore(cell.getElement(), row.getCell(this.columns[this.rightCol]).getElement().nextSibling);
20451
20601
  cell.cellRendered();
20452
20602
  }
20453
20603
  });
@@ -20455,6 +20605,12 @@ class VirtualDomHorizontal extends Renderer{
20455
20605
  this.fitDataColActualWidthCheck(column);
20456
20606
 
20457
20607
  this.rightCol++; // Don't move this below the >= check below
20608
+
20609
+ this.getVisibleRows().forEach((row) => {
20610
+ if(row.type !== "group"){
20611
+ row.modules.vdomHoz.rightCol = this.rightCol;
20612
+ }
20613
+ });
20458
20614
 
20459
20615
  if(this.rightCol >= (this.columns.length - 1)){
20460
20616
  this.vDomPadRight = 0;
@@ -20488,12 +20644,18 @@ class VirtualDomHorizontal extends Renderer{
20488
20644
  this.getVisibleRows().forEach((row) => {
20489
20645
  if(row.type !== "group"){
20490
20646
  var cell = row.getCell(column);
20491
- row.getElement().prepend(cell.getElement());
20647
+ row.getElement().insertBefore(cell.getElement(), row.getCell(this.columns[this.leftCol]).getElement());
20492
20648
  cell.cellRendered();
20493
20649
  }
20494
20650
  });
20495
20651
 
20496
20652
  this.leftCol--; // don't move this below the <= check below
20653
+
20654
+ this.getVisibleRows().forEach((row) => {
20655
+ if(row.type !== "group"){
20656
+ row.modules.vdomHoz.leftCol = this.leftCol;
20657
+ }
20658
+ });
20497
20659
 
20498
20660
  if(this.leftCol <= 0){ // replicating logic in addColRight
20499
20661
  this.vDomPadLeft = 0;
@@ -20546,6 +20708,12 @@ class VirtualDomHorizontal extends Renderer{
20546
20708
 
20547
20709
  this.vDomPadRight += column.getWidth();
20548
20710
  this.rightCol --;
20711
+
20712
+ this.getVisibleRows().forEach((row) => {
20713
+ if(row.type !== "group"){
20714
+ row.modules.vdomHoz.rightCol = this.rightCol;
20715
+ }
20716
+ });
20549
20717
  }else {
20550
20718
  working = false;
20551
20719
  }
@@ -20562,7 +20730,7 @@ class VirtualDomHorizontal extends Renderer{
20562
20730
  removeColLeft(){
20563
20731
  var changes = false,
20564
20732
  working = true;
20565
-
20733
+
20566
20734
  while(working){
20567
20735
  let column = this.columns[this.leftCol];
20568
20736
 
@@ -20584,6 +20752,12 @@ class VirtualDomHorizontal extends Renderer{
20584
20752
 
20585
20753
  this.vDomPadLeft += column.getWidth();
20586
20754
  this.leftCol ++;
20755
+
20756
+ this.getVisibleRows().forEach((row) => {
20757
+ if(row.type !== "group"){
20758
+ row.modules.vdomHoz.leftCol = this.leftCol;
20759
+ }
20760
+ });
20587
20761
  }else {
20588
20762
  working = false;
20589
20763
  }
@@ -20624,26 +20798,41 @@ class VirtualDomHorizontal extends Renderer{
20624
20798
  leftCol:this.leftCol,
20625
20799
  rightCol:this.rightCol,
20626
20800
  };
20627
-
20801
+
20802
+ if(this.table.modules.frozenColumns){
20803
+ this.table.modules.frozenColumns.leftColumns.forEach((column) => {
20804
+ this.appendCell(row, column);
20805
+ });
20806
+ }
20807
+
20628
20808
  for(let i = this.leftCol; i <= this.rightCol; i++){
20629
- let column = this.columns[i];
20630
-
20631
- if(column && column.visible){
20632
- let cell = row.getCell(column);
20633
-
20634
- row.getElement().appendChild(cell.getElement());
20635
- cell.cellRendered();
20636
- }
20809
+ this.appendCell(row, this.columns[i]);
20810
+ }
20811
+
20812
+ if(this.table.modules.frozenColumns){
20813
+ this.table.modules.frozenColumns.rightColumns.forEach((column) => {
20814
+ this.appendCell(row, column);
20815
+ });
20637
20816
  }
20638
20817
  }
20639
20818
  }
20640
20819
 
20820
+ appendCell(row, column){
20821
+ if(column && column.visible){
20822
+ let cell = row.getCell(column);
20823
+
20824
+ row.getElement().appendChild(cell.getElement());
20825
+ cell.cellRendered();
20826
+ }
20827
+ }
20828
+
20641
20829
  reinitializeRow(row, force){
20642
20830
  if(row.type !== "group"){
20643
20831
  if(force || !row.modules.vdomHoz || row.modules.vdomHoz.leftCol !== this.leftCol || row.modules.vdomHoz.rightCol !== this.rightCol){
20832
+
20644
20833
  var rowEl = row.getElement();
20645
20834
  while(rowEl.firstChild) rowEl.removeChild(rowEl.firstChild);
20646
-
20835
+
20647
20836
  this.initializeRow(row);
20648
20837
  }
20649
20838
  }
@@ -20657,6 +20846,7 @@ class ColumnManager extends CoreFeature {
20657
20846
 
20658
20847
  this.blockHozScrollEvent = false;
20659
20848
  this.headersElement = null;
20849
+ this.contentsElement = null;
20660
20850
  this.element = null ; //containing element
20661
20851
  this.columns = []; // column definition object
20662
20852
  this.columnsByIndex = []; //columns by index
@@ -20676,11 +20866,22 @@ class ColumnManager extends CoreFeature {
20676
20866
  this.initializeRenderer();
20677
20867
 
20678
20868
  this.headersElement = this.createHeadersElement();
20869
+ this.contentsElement = this.createHeaderContentsElement();
20679
20870
  this.element = this.createHeaderElement();
20680
20871
 
20681
- this.element.insertBefore(this.headersElement, this.element.firstChild);
20872
+ this.contentsElement.insertBefore(this.headersElement, this.contentsElement.firstChild);
20873
+ this.element.insertBefore(this.contentsElement, this.element.firstChild);
20682
20874
 
20683
20875
  this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this));
20876
+ this.subscribe("scrollbar-vertical", this.padVerticalScrollbar.bind(this));
20877
+ }
20878
+
20879
+ padVerticalScrollbar(width){
20880
+ if(this.table.rtl){
20881
+ this.headersElement.style.marginLeft = width + "px";
20882
+ }else {
20883
+ this.headersElement.style.marginRight = width + "px";
20884
+ }
20684
20885
  }
20685
20886
 
20686
20887
  initializeRenderer(){
@@ -20714,6 +20915,15 @@ class ColumnManager extends CoreFeature {
20714
20915
 
20715
20916
  return el;
20716
20917
  }
20918
+
20919
+ createHeaderContentsElement (){
20920
+ var el = document.createElement("div");
20921
+
20922
+ el.classList.add("tabulator-header-contents");
20923
+ el.setAttribute("role", "rowgroup");
20924
+
20925
+ return el;
20926
+ }
20717
20927
 
20718
20928
  createHeaderElement (){
20719
20929
  var el = document.createElement("div");
@@ -20732,6 +20942,12 @@ class ColumnManager extends CoreFeature {
20732
20942
  getElement(){
20733
20943
  return this.element;
20734
20944
  }
20945
+
20946
+ //return containing contents element
20947
+ getContentsElement(){
20948
+ return this.contentsElement;
20949
+ }
20950
+
20735
20951
 
20736
20952
  //return header containing element
20737
20953
  getHeadersElement(){
@@ -20740,20 +20956,8 @@ class ColumnManager extends CoreFeature {
20740
20956
 
20741
20957
  //scroll horizontally to match table body
20742
20958
  scrollHorizontal(left){
20743
- var hozAdjust = 0,
20744
- scrollWidth = this.element.scrollWidth - this.table.element.clientWidth;
20745
-
20746
- // this.tempScrollBlock();
20747
- this.element.scrollLeft = left;
20748
-
20749
- //adjust for vertical scrollbar moving table when present
20750
- if(left > scrollWidth){
20751
- hozAdjust = left - scrollWidth;
20752
- this.element.style.marginLeft = (-(hozAdjust)) + "px";
20753
- }else {
20754
- this.element.style.marginLeft = 0;
20755
- }
20756
-
20959
+ this.contentsElement.scrollLeft = left;
20960
+
20757
20961
  this.scrollLeft = left;
20758
20962
 
20759
20963
  this.renderer.scrollColumns(left);
@@ -22045,6 +22249,8 @@ class RowManager extends CoreFeature{
22045
22249
 
22046
22250
  this.dataPipeline = []; //hold data pipeline tasks
22047
22251
  this.displayPipeline = []; //hold data display pipeline tasks
22252
+
22253
+ this.scrollbarWidth = 0;
22048
22254
 
22049
22255
  this.renderer = null;
22050
22256
  }
@@ -22727,6 +22933,10 @@ class RowManager extends CoreFeature{
22727
22933
  //case to handle scenario when trying to skip past end stage
22728
22934
  this.regenerateRowPositions();
22729
22935
  }
22936
+
22937
+ if(this.getDisplayRows().length){
22938
+ this._clearPlaceholder();
22939
+ }
22730
22940
  }
22731
22941
 
22732
22942
  //regenerate row positions
@@ -22833,10 +23043,26 @@ class RowManager extends CoreFeature{
22833
23043
  if(!this.fixedHeight){
22834
23044
  this.adjustTableSize();
22835
23045
  }
23046
+
23047
+ this.scrollBarCheck();
22836
23048
 
22837
23049
  this.dispatchExternal("renderComplete");
22838
23050
  }
22839
23051
  }
23052
+
23053
+ scrollBarCheck(){
23054
+ var scrollbarWidth = 0;
23055
+
23056
+ //adjust for vertical scrollbar moving table when present
23057
+ if(this.element.scrollHeight > this.element.clientHeight){
23058
+ scrollbarWidth = this.element.offsetWidth - this.element.clientWidth;
23059
+ }
23060
+
23061
+ if(scrollbarWidth !== this.scrollbarWidth){
23062
+ this.scrollbarWidth = scrollbarWidth;
23063
+ this.dispatch("scrollbar-vertical", scrollbarWidth);
23064
+ }
23065
+ }
22840
23066
 
22841
23067
  initializeRenderer(){
22842
23068
  var renderClass;
@@ -22899,6 +23125,8 @@ class RowManager extends CoreFeature{
22899
23125
  if(!this.displayRowsCount){
22900
23126
  this._showPlaceholder();
22901
23127
  }
23128
+
23129
+ this.scrollBarCheck();
22902
23130
 
22903
23131
  this.dispatchExternal("renderComplete");
22904
23132
  }
@@ -22997,6 +23225,8 @@ class RowManager extends CoreFeature{
22997
23225
  this.redraw();
22998
23226
  }
22999
23227
  }
23228
+
23229
+ this.scrollBarCheck();
23000
23230
  }
23001
23231
 
23002
23232
  this._positionPlaceholder();
@@ -23183,6 +23413,8 @@ class InteractionManager extends CoreFeature {
23183
23413
  "mouseover",
23184
23414
  "mouseout",
23185
23415
  "mousemove",
23416
+ "mouseup",
23417
+ "mousedown",
23186
23418
  "touchstart",
23187
23419
  "touchend",
23188
23420
  ];