tabulator-tables 5.3.3 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) 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 +25819 -27493
  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 +706 -508
  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 +32 -17
  57. package/src/js/core/RowManager.js +30 -4
  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 +76 -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/Format/Format.js +46 -40
  68. package/src/js/modules/Format/defaults/formatters/responsiveCollapse.js +9 -1
  69. package/src/js/modules/FrozenColumns/FrozenColumns.js +24 -57
  70. package/src/js/modules/FrozenRows/FrozenRows.js +4 -3
  71. package/src/js/modules/GroupRows/Group.js +20 -28
  72. package/src/js/modules/GroupRows/GroupComponent.js +1 -1
  73. package/src/js/modules/GroupRows/GroupRows.js +1 -2
  74. package/src/js/modules/Interaction/Interaction.js +12 -0
  75. package/src/js/modules/Menu/Menu.js +31 -7
  76. package/src/js/modules/MoveColumns/MoveColumns.js +3 -3
  77. package/src/js/modules/Persistence/Persistence.js +1 -0
  78. package/src/js/modules/Popup/Popup.js +42 -4
  79. package/src/js/modules/ResizeColumns/ResizeColumns.js +25 -6
  80. package/src/js/modules/ResizeTable/ResizeTable.js +7 -8
  81. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +21 -21
  82. package/src/js/modules/Sort/Sort.js +14 -2
  83. package/src/scss/tabulator.scss +92 -31
@@ -1,4 +1,4 @@
1
- /* Tabulator v5.3.3 (c) Oliver Folkerd 2022 */
1
+ /* Tabulator v5.4.0 (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
  }
@@ -7414,6 +7481,7 @@ class Edit$1 extends Module{
7414
7481
  this.subscribe("column-layout", this.initializeColumnCheck.bind(this));
7415
7482
  this.subscribe("column-delete", this.columnDeleteCheck.bind(this));
7416
7483
  this.subscribe("row-deleting", this.rowDeleteCheck.bind(this));
7484
+ this.subscribe("row-layout", this.rowEditableCheck.bind(this));
7417
7485
  this.subscribe("data-refreshing", this.cancelEdit.bind(this));
7418
7486
 
7419
7487
  this.subscribe("keybinding-nav-prev", this.navigatePrev.bind(this, undefined));
@@ -7518,7 +7586,7 @@ class Edit$1 extends Module{
7518
7586
  prevRow = this.table.rowManager.prevDisplayRow(cell.row, true);
7519
7587
 
7520
7588
  if(prevRow){
7521
- nextCell = this.findNextEditableCell(prevRow, prevRow.cells.length);
7589
+ nextCell = this.findPrevEditableCell(prevRow, prevRow.cells.length);
7522
7590
 
7523
7591
  if(nextCell){
7524
7592
  nextCell.getComponent().edit();
@@ -7708,6 +7776,14 @@ class Edit$1 extends Module{
7708
7776
  this.cancelEdit();
7709
7777
  }
7710
7778
  }
7779
+
7780
+ rowEditableCheck(row){
7781
+ row.getCells().forEach((cell) => {
7782
+ if(cell.column.modules.edit && typeof cell.column.modules.edit.check === "function"){
7783
+ this.updateCellClass(cell);
7784
+ }
7785
+ });
7786
+ }
7711
7787
 
7712
7788
  //initialize column editor
7713
7789
  initializeColumn(column){
@@ -7892,7 +7968,9 @@ class Edit$1 extends Module{
7892
7968
  if(cell.column.modules.edit){
7893
7969
  switch(typeof cell.column.modules.edit.check){
7894
7970
  case "function":
7895
- check = cell.column.modules.edit.check(cell.getComponent());
7971
+ if(cell.row.initialized){
7972
+ check = cell.column.modules.edit.check(cell.getComponent());
7973
+ }
7896
7974
  break;
7897
7975
 
7898
7976
  case "string":
@@ -10240,7 +10318,15 @@ function responsiveCollapse(cell, formatterParams, onRendered){
10240
10318
  config = cell.getRow()._row.modules.responsiveLayout;
10241
10319
 
10242
10320
  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>";
10321
+
10322
+ el.innerHTML = `<svg class='tabulator-responsive-collapse-toggle-open' viewbox="0 0 24 24">
10323
+ <line x1="7" y1="12" x2="17" y2="12" fill="none" stroke-width="3" stroke-linecap="round" />
10324
+ <line y1="7" x1="12" y2="17" x2="12" fill="none" stroke-width="3" stroke-linecap="round" />
10325
+ </svg>
10326
+
10327
+ <svg class='tabulator-responsive-collapse-toggle-close' viewbox="0 0 24 24">
10328
+ <line x1="7" y1="12" x2="17" y2="12" fill="none" stroke-width="3" stroke-linecap="round" />
10329
+ </svg>`;
10244
10330
 
10245
10331
  cell.getElement().classList.add("tabulator-row-handle");
10246
10332
 
@@ -10355,13 +10441,13 @@ var defaultFormatters = {
10355
10441
  };
10356
10442
 
10357
10443
  class Format extends Module{
10358
-
10444
+
10359
10445
  constructor(table){
10360
10446
  super(table);
10361
-
10447
+
10362
10448
  this.registerColumnOption("formatter");
10363
10449
  this.registerColumnOption("formatterParams");
10364
-
10450
+
10365
10451
  this.registerColumnOption("formatterPrint");
10366
10452
  this.registerColumnOption("formatterPrintParams");
10367
10453
  this.registerColumnOption("formatterClipboard");
@@ -10371,35 +10457,35 @@ class Format extends Module{
10371
10457
  this.registerColumnOption("titleFormatter");
10372
10458
  this.registerColumnOption("titleFormatterParams");
10373
10459
  }
10374
-
10460
+
10375
10461
  initialize(){
10376
10462
  this.subscribe("cell-format", this.formatValue.bind(this));
10377
10463
  this.subscribe("cell-rendered", this.cellRendered.bind(this));
10378
10464
  this.subscribe("column-layout", this.initializeColumn.bind(this));
10379
10465
  this.subscribe("column-format", this.formatHeader.bind(this));
10380
10466
  }
10381
-
10467
+
10382
10468
  //initialize column formatter
10383
10469
  initializeColumn(column){
10384
10470
  column.modules.format = this.lookupFormatter(column, "");
10385
-
10471
+
10386
10472
  if(typeof column.definition.formatterPrint !== "undefined"){
10387
10473
  column.modules.format.print = this.lookupFormatter(column, "Print");
10388
10474
  }
10389
-
10475
+
10390
10476
  if(typeof column.definition.formatterClipboard !== "undefined"){
10391
10477
  column.modules.format.clipboard = this.lookupFormatter(column, "Clipboard");
10392
10478
  }
10393
-
10479
+
10394
10480
  if(typeof column.definition.formatterHtmlOutput !== "undefined"){
10395
10481
  column.modules.format.htmlOutput = this.lookupFormatter(column, "HtmlOutput");
10396
10482
  }
10397
10483
  }
10398
-
10484
+
10399
10485
  lookupFormatter(column, type){
10400
10486
  var config = {params:column.definition["formatter" + type + "Params"] || {}},
10401
10487
  formatter = column.definition["formatter" + type];
10402
-
10488
+
10403
10489
  //set column formatter
10404
10490
  switch(typeof formatter){
10405
10491
  case "string":
@@ -10410,97 +10496,103 @@ class Format extends Module{
10410
10496
  config.formatter = Format.formatters.plaintext;
10411
10497
  }
10412
10498
  break;
10413
-
10499
+
10414
10500
  case "function":
10415
10501
  config.formatter = formatter;
10416
10502
  break;
10417
-
10503
+
10418
10504
  default:
10419
10505
  config.formatter = Format.formatters.plaintext;
10420
10506
  break;
10421
10507
  }
10422
-
10508
+
10423
10509
  return config;
10424
10510
  }
10425
-
10511
+
10426
10512
  cellRendered(cell){
10427
10513
  if(cell.modules.format && cell.modules.format.renderedCallback && !cell.modules.format.rendered){
10428
10514
  cell.modules.format.renderedCallback();
10429
10515
  cell.modules.format.rendered = true;
10430
10516
  }
10431
10517
  }
10432
-
10518
+
10433
10519
  //return a formatted value for a column header
10434
10520
  formatHeader(column, title, el){
10435
10521
  var formatter, params, onRendered, mockCell;
10436
-
10522
+
10437
10523
  if(column.definition.titleFormatter){
10438
10524
  formatter = this.getFormatter(column.definition.titleFormatter);
10439
-
10525
+
10440
10526
  onRendered = (callback) => {
10441
10527
  column.titleFormatterRendered = callback;
10442
10528
  };
10443
-
10529
+
10444
10530
  mockCell = {
10445
10531
  getValue:function(){
10446
10532
  return title;
10447
10533
  },
10448
10534
  getElement:function(){
10449
10535
  return el;
10536
+ },
10537
+ getColumn:function(){
10538
+ return column.getComponent();
10539
+ },
10540
+ getTable:() => {
10541
+ return this.table;
10450
10542
  }
10451
10543
  };
10452
-
10544
+
10453
10545
  params = column.definition.titleFormatterParams || {};
10454
-
10546
+
10455
10547
  params = typeof params === "function" ? params() : params;
10456
-
10548
+
10457
10549
  return formatter.call(this, mockCell, params, onRendered);
10458
10550
  }else {
10459
10551
  return title;
10460
10552
  }
10461
10553
  }
10462
-
10463
-
10554
+
10555
+
10464
10556
  //return a formatted value for a cell
10465
10557
  formatValue(cell){
10466
10558
  var component = cell.getComponent(),
10467
10559
  params = typeof cell.column.modules.format.params === "function" ? cell.column.modules.format.params(component) : cell.column.modules.format.params;
10468
-
10560
+
10469
10561
  function onRendered(callback){
10470
10562
  if(!cell.modules.format){
10471
10563
  cell.modules.format = {};
10472
10564
  }
10473
-
10565
+
10474
10566
  cell.modules.format.renderedCallback = callback;
10475
10567
  cell.modules.format.rendered = false;
10476
10568
  }
10477
-
10569
+
10478
10570
  return cell.column.modules.format.formatter.call(this, component, params, onRendered);
10479
10571
  }
10480
-
10572
+
10481
10573
  formatExportValue(cell, type){
10482
10574
  var formatter = cell.column.modules.format[type],
10483
10575
  params;
10484
-
10576
+
10485
10577
  if(formatter){
10486
10578
  params = typeof formatter.params === "function" ? formatter.params(cell.getComponent()) : formatter.params;
10487
-
10579
+
10488
10580
  function onRendered(callback){
10489
10581
  if(!cell.modules.format){
10490
10582
  cell.modules.format = {};
10491
10583
  }
10492
-
10584
+
10493
10585
  cell.modules.format.renderedCallback = callback;
10494
10586
  cell.modules.format.rendered = false;
10495
10587
  }
10496
-
10588
+
10497
10589
  return formatter.formatter.call(this, cell.getComponent(), params, onRendered);
10498
-
10590
+
10499
10591
  }else {
10500
10592
  return this.formatValue(cell);
10501
10593
  }
10502
10594
  }
10503
-
10595
+
10504
10596
  sanitizeHTML(value){
10505
10597
  if(value){
10506
10598
  var entityMap = {
@@ -10513,7 +10605,7 @@ class Format extends Module{
10513
10605
  '`': '&#x60;',
10514
10606
  '=': '&#x3D;'
10515
10607
  };
10516
-
10608
+
10517
10609
  return String(value).replace(/[&<>"'`=/]/g, function (s) {
10518
10610
  return entityMap[s];
10519
10611
  });
@@ -10521,11 +10613,11 @@ class Format extends Module{
10521
10613
  return value;
10522
10614
  }
10523
10615
  }
10524
-
10616
+
10525
10617
  emptyToSpace(value){
10526
10618
  return value === null || typeof value === "undefined" || value === "" ? "&nbsp;" : value;
10527
10619
  }
10528
-
10620
+
10529
10621
  //get formatter for cell
10530
10622
  getFormatter(formatter){
10531
10623
  switch(typeof formatter){
@@ -10537,16 +10629,16 @@ class Format extends Module{
10537
10629
  formatter = Format.formatters.plaintext;
10538
10630
  }
10539
10631
  break;
10540
-
10632
+
10541
10633
  case "function":
10542
- //Custom formatter Function, do nothing
10634
+ //Custom formatter Function, do nothing
10543
10635
  break;
10544
-
10636
+
10545
10637
  default:
10546
10638
  formatter = Format.formatters.plaintext;
10547
10639
  break;
10548
10640
  }
10549
-
10641
+
10550
10642
  return formatter;
10551
10643
  }
10552
10644
  }
@@ -10563,9 +10655,6 @@ class FrozenColumns extends Module{
10563
10655
 
10564
10656
  this.leftColumns = [];
10565
10657
  this.rightColumns = [];
10566
- this.leftMargin = 0;
10567
- this.rightMargin = 0;
10568
- this.rightPadding = 0;
10569
10658
  this.initializationMode = "left";
10570
10659
  this.active = false;
10571
10660
  this.blocked = true;
@@ -10578,13 +10667,7 @@ class FrozenColumns extends Module{
10578
10667
  this.initializationMode = "left";
10579
10668
  this.leftColumns = [];
10580
10669
  this.rightColumns = [];
10581
- this.leftMargin = 0;
10582
- this.rightMargin = 0;
10583
- this.rightMargin = 0;
10584
10670
  this.active = false;
10585
-
10586
- this.table.columnManager.headersElement.style.marginLeft = 0;
10587
- this.table.columnManager.element.style.paddingRight = 0;
10588
10671
  }
10589
10672
 
10590
10673
  initialize(){
@@ -10593,8 +10676,6 @@ class FrozenColumns extends Module{
10593
10676
  this.subscribe("column-width", this.layout.bind(this));
10594
10677
  this.subscribe("row-layout-after", this.layoutRow.bind(this));
10595
10678
  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
10679
  this.subscribe("columns-loading", this.reset.bind(this));
10599
10680
 
10600
10681
  this.subscribe("column-add", this.reinitializeColumns.bind(this));
@@ -10603,6 +10684,7 @@ class FrozenColumns extends Module{
10603
10684
  this.subscribe("table-redraw", this.layout.bind(this));
10604
10685
  this.subscribe("layout-refreshing", this.blockLayout.bind(this));
10605
10686
  this.subscribe("layout-refreshed", this.unblockLayout.bind(this));
10687
+ this.subscribe("scrollbar-vertical", this.adjustForScrollbar.bind(this));
10606
10688
  }
10607
10689
 
10608
10690
  blockLayout(){
@@ -10662,32 +10744,6 @@ class FrozenColumns extends Module{
10662
10744
  }
10663
10745
  }
10664
10746
 
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;
10685
- }
10686
-
10687
- //calculate right frozen columns
10688
- this.rightPadding = this.table.rowManager.element.clientWidth + this.table.columnManager.scrollLeft;
10689
- }
10690
-
10691
10747
  //layout calculation rows
10692
10748
  layoutCalcRows(){
10693
10749
  if(this.table.modExists("columnCalcs")){
@@ -10728,11 +10784,8 @@ class FrozenColumns extends Module{
10728
10784
  var leftMargin = 0;
10729
10785
  var rightMargin = 0;
10730
10786
 
10731
- this.table.columnManager.headersElement.style.marginLeft = this.leftMargin;
10732
- this.table.columnManager.element.style.paddingRight = this.rightMargin;
10733
-
10734
10787
  this.leftColumns.forEach((column, i) => {
10735
- column.modules.frozen.marginValue = leftMargin + this.table.columnManager.scrollLeft;
10788
+ column.modules.frozen.marginValue = leftMargin;
10736
10789
  column.modules.frozen.margin = column.modules.frozen.marginValue + "px";
10737
10790
 
10738
10791
  if(column.visible){
@@ -10768,20 +10821,19 @@ class FrozenColumns extends Module{
10768
10821
 
10769
10822
  this.rightColumns.forEach((column, i) => {
10770
10823
 
10824
+ column.modules.frozen.marginValue = rightMargin;
10825
+ column.modules.frozen.margin = column.modules.frozen.marginValue + "px";
10826
+
10771
10827
  if(column.visible){
10772
10828
  rightMargin += column.getWidth();
10773
10829
  }
10774
10830
 
10775
- column.modules.frozen.marginValue = this.rightPadding - rightMargin;
10776
- column.modules.frozen.margin = column.modules.frozen.marginValue + "px";
10777
-
10778
10831
  if(i == this.rightColumns.length - 1){
10779
10832
  column.modules.frozen.edge = true;
10780
10833
  }else {
10781
10834
  column.modules.frozen.edge = false;
10782
10835
  }
10783
10836
 
10784
-
10785
10837
  if(column.parent.isGroup){
10786
10838
  this.layoutElement(this.getColGroupParentElement(column), column);
10787
10839
  }else {
@@ -10803,12 +10855,10 @@ class FrozenColumns extends Module{
10803
10855
  //layout columns appropriately
10804
10856
  layout(){
10805
10857
  if(this.active && !this.blocked){
10806
- //calculate row padding
10807
- this.calcMargins();
10808
-
10858
+
10809
10859
  //calculate left columns
10810
10860
  this.layoutColumnPosition();
10811
-
10861
+
10812
10862
  this.reinitializeRows();
10813
10863
 
10814
10864
  this.layoutCalcRows();
@@ -10831,11 +10881,6 @@ class FrozenColumns extends Module{
10831
10881
  }
10832
10882
 
10833
10883
  layoutRow(row){
10834
- // console.trace("row")
10835
- var rowEl = row.getElement();
10836
-
10837
- rowEl.style.paddingLeft = this.leftMargin;
10838
-
10839
10884
  if(this.table.options.layout === "fitDataFill" && this.rightColumns.length){
10840
10885
  this.table.rowManager.getTableElement().style.minWidth = "calc(100% - " + this.rightMargin + ")";
10841
10886
  }
@@ -10858,11 +10903,19 @@ class FrozenColumns extends Module{
10858
10903
  }
10859
10904
 
10860
10905
  layoutElement(element, column){
10906
+ var position;
10861
10907
 
10862
10908
  if(column.modules.frozen){
10863
- element.style.position = "absolute";
10864
- element.style.left = column.modules.frozen.margin;
10865
-
10909
+ element.style.position = "sticky";
10910
+
10911
+ if(this.table.rtl){
10912
+ position = column.modules.frozen.position === "left" ? "right" : "left";
10913
+ }else {
10914
+ position = column.modules.frozen.position;
10915
+ }
10916
+
10917
+ element.style[position] = column.modules.frozen.margin;
10918
+
10866
10919
  element.classList.add("tabulator-frozen");
10867
10920
 
10868
10921
  if(column.modules.frozen.edge){
@@ -10870,6 +10923,12 @@ class FrozenColumns extends Module{
10870
10923
  }
10871
10924
  }
10872
10925
  }
10926
+
10927
+ adjustForScrollbar(width){
10928
+ if(this.rightColumns.length){
10929
+ this.table.columnManager.getContentsElement().style.width = "calc(100% - " + width + "px)";
10930
+ }
10931
+ }
10873
10932
 
10874
10933
  _calcSpace(columns, index){
10875
10934
  var width = 0;
@@ -10910,7 +10969,7 @@ class FrozenRows extends Module{
10910
10969
  this.topElement.classList.add("tabulator-frozen-rows-holder");
10911
10970
 
10912
10971
  // this.table.columnManager.element.append(this.topElement);
10913
- this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
10972
+ this.table.columnManager.getContentsElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
10914
10973
 
10915
10974
  this.subscribe("row-deleting", this.detachRow.bind(this));
10916
10975
  this.subscribe("rows-visible", this.visibleRows.bind(this));
@@ -10986,12 +11045,13 @@ class FrozenRows extends Module{
10986
11045
  this.topElement.appendChild(row.getElement());
10987
11046
  row.initialize();
10988
11047
  row.normalizeHeight();
10989
- this.table.rowManager.adjustTableSize();
10990
-
11048
+
10991
11049
  this.rows.push(row);
10992
11050
 
10993
11051
  this.refreshData(false, "display");
10994
11052
 
11053
+ this.table.rowManager.adjustTableSize();
11054
+
10995
11055
  this.styleRows();
10996
11056
 
10997
11057
  }else {
@@ -11084,7 +11144,7 @@ class GroupComponent {
11084
11144
  }
11085
11145
 
11086
11146
  isVisible(){
11087
- return this._group._visible;
11147
+ return this._group.visible;
11088
11148
  }
11089
11149
 
11090
11150
  show(){
@@ -11355,38 +11415,41 @@ class Group{
11355
11415
  }
11356
11416
  }
11357
11417
 
11358
- getHeadersAndRows(noCalc){
11418
+ getHeadersAndRows(){
11359
11419
  var output = [];
11360
11420
 
11361
11421
  output.push(this);
11362
11422
 
11363
11423
  this._visSet();
11364
11424
 
11425
+
11426
+ if(this.calcs.top){
11427
+ this.calcs.top.detachElement();
11428
+ this.calcs.top.deleteCells();
11429
+ }
11430
+
11431
+ if(this.calcs.bottom){
11432
+ this.calcs.bottom.detachElement();
11433
+ this.calcs.bottom.deleteCells();
11434
+ }
11435
+
11436
+
11437
+
11365
11438
  if(this.visible){
11366
11439
  if(this.groupList.length){
11367
11440
  this.groupList.forEach(function(group){
11368
- output = output.concat(group.getHeadersAndRows(noCalc));
11441
+ output = output.concat(group.getHeadersAndRows());
11369
11442
  });
11370
11443
 
11371
11444
  }else {
11372
- if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11373
- if(this.calcs.top){
11374
- this.calcs.top.detachElement();
11375
- this.calcs.top.deleteCells();
11376
- }
11377
-
11445
+ if(this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11378
11446
  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
11379
11447
  output.push(this.calcs.top);
11380
11448
  }
11381
11449
 
11382
11450
  output = output.concat(this.rows);
11383
11451
 
11384
- if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11385
- if(this.calcs.bottom){
11386
- this.calcs.bottom.detachElement();
11387
- this.calcs.bottom.deleteCells();
11388
- }
11389
-
11452
+ if(this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11390
11453
  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
11391
11454
  output.push(this.calcs.bottom);
11392
11455
  }
@@ -11395,25 +11458,14 @@ class Group{
11395
11458
  if(!this.groupList.length && this.groupManager.table.options.columnCalcs != "table"){
11396
11459
 
11397
11460
  if(this.groupManager.table.modExists("columnCalcs")){
11398
-
11399
- if(!noCalc && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11400
- if(this.calcs.top){
11401
- this.calcs.top.detachElement();
11402
- this.calcs.top.deleteCells();
11403
- }
11404
-
11461
+ if(this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
11405
11462
  if(this.groupManager.table.options.groupClosedShowCalcs){
11406
11463
  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
11407
11464
  output.push(this.calcs.top);
11408
11465
  }
11409
11466
  }
11410
11467
 
11411
- if(!noCalc && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11412
- if(this.calcs.bottom){
11413
- this.calcs.bottom.detachElement();
11414
- this.calcs.bottom.deleteCells();
11415
- }
11416
-
11468
+ if(this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
11417
11469
  if(this.groupManager.table.options.groupClosedShowCalcs){
11418
11470
  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
11419
11471
  output.push(this.calcs.bottom);
@@ -11524,7 +11576,7 @@ class Group{
11524
11576
  prev = rowEl;
11525
11577
  });
11526
11578
  }
11527
-
11579
+
11528
11580
  this.groupManager.updateGroupRows(true);
11529
11581
  }else {
11530
11582
  this.groupManager.updateGroupRows(true);
@@ -11982,8 +12034,7 @@ class GroupRows extends Module{
11982
12034
 
11983
12035
  // get grouped table data in the same format as getData()
11984
12036
  userGetGroupedData(){
11985
- return this.table.options.groupBy ?
11986
- this.getGroupedData() : this.getData();
12037
+ return this.table.options.groupBy ? this.getGroupedData() : this.getData();
11987
12038
  }
11988
12039
 
11989
12040
 
@@ -12993,6 +13044,8 @@ class Interaction extends Module{
12993
13044
  rowMouseOver:"row-mouseover",
12994
13045
  rowMouseOut:"row-mouseout",
12995
13046
  rowMouseMove:"row-mousemove",
13047
+ rowMouseDown:"row-mousedown",
13048
+ rowMouseUp:"row-mouseup",
12996
13049
  rowTap:"row",
12997
13050
  rowDblTap:"row",
12998
13051
  rowTapHold:"row",
@@ -13006,6 +13059,8 @@ class Interaction extends Module{
13006
13059
  cellMouseOver:"cell-mouseover",
13007
13060
  cellMouseOut:"cell-mouseout",
13008
13061
  cellMouseMove:"cell-mousemove",
13062
+ cellMouseDown:"cell-mousedown",
13063
+ cellMouseUp:"cell-mouseup",
13009
13064
  cellTap:"cell",
13010
13065
  cellDblTap:"cell",
13011
13066
  cellTapHold:"cell",
@@ -13019,6 +13074,8 @@ class Interaction extends Module{
13019
13074
  headerMouseOver:"column-mouseover",
13020
13075
  headerMouseOut:"column-mouseout",
13021
13076
  headerMouseMove:"column-mousemove",
13077
+ headerMouseDown:"column-mousedown",
13078
+ headerMouseUp:"column-mouseup",
13022
13079
  headerTap:"column",
13023
13080
  headerDblTap:"column",
13024
13081
  headerTapHold:"column",
@@ -13032,6 +13089,8 @@ class Interaction extends Module{
13032
13089
  groupMouseOver:"group-mouseover",
13033
13090
  groupMouseOut:"group-mouseout",
13034
13091
  groupMouseMove:"group-mousemove",
13092
+ groupMouseDown:"group-mousedown",
13093
+ groupMouseUp:"group-mouseup",
13035
13094
  groupTap:"group",
13036
13095
  groupDblTap:"group",
13037
13096
  groupTapHold:"group",
@@ -13074,6 +13133,8 @@ class Interaction extends Module{
13074
13133
  this.registerColumnOption("headerMouseOver");
13075
13134
  this.registerColumnOption("headerMouseOut");
13076
13135
  this.registerColumnOption("headerMouseMove");
13136
+ this.registerColumnOption("headerMouseDown");
13137
+ this.registerColumnOption("headerMouseUp");
13077
13138
  this.registerColumnOption("headerTap");
13078
13139
  this.registerColumnOption("headerDblTap");
13079
13140
  this.registerColumnOption("headerTapHold");
@@ -13086,6 +13147,8 @@ class Interaction extends Module{
13086
13147
  this.registerColumnOption("cellMouseOver");
13087
13148
  this.registerColumnOption("cellMouseOut");
13088
13149
  this.registerColumnOption("cellMouseMove");
13150
+ this.registerColumnOption("cellMouseDown");
13151
+ this.registerColumnOption("cellMouseUp");
13089
13152
  this.registerColumnOption("cellTap");
13090
13153
  this.registerColumnOption("cellDblTap");
13091
13154
  this.registerColumnOption("cellTapHold");
@@ -13600,18 +13663,22 @@ class Menu extends Module{
13600
13663
  this.columnSubscribers = {};
13601
13664
 
13602
13665
  this.registerTableOption("menuContainer", undefined); //deprecated
13603
-
13666
+
13604
13667
  this.registerTableOption("rowContextMenu", false);
13605
13668
  this.registerTableOption("rowClickMenu", false);
13669
+ this.registerTableOption("rowDblClickMenu", false);
13606
13670
  this.registerTableOption("groupContextMenu", false);
13607
13671
  this.registerTableOption("groupClickMenu", false);
13672
+ this.registerTableOption("groupDblClickMenu", false);
13608
13673
 
13609
13674
  this.registerColumnOption("headerContextMenu");
13610
13675
  this.registerColumnOption("headerClickMenu");
13676
+ this.registerColumnOption("headerDblClickMenu");
13611
13677
  this.registerColumnOption("headerMenu");
13612
13678
  this.registerColumnOption("headerMenuIcon");
13613
13679
  this.registerColumnOption("contextMenu");
13614
13680
  this.registerColumnOption("clickMenu");
13681
+ this.registerColumnOption("dblClickMenu");
13615
13682
 
13616
13683
  }
13617
13684
 
@@ -13622,7 +13689,7 @@ class Menu extends Module{
13622
13689
 
13623
13690
  this.subscribe("column-init", this.initializeColumn.bind(this));
13624
13691
  }
13625
-
13692
+
13626
13693
  deprecatedOptionsCheck(){
13627
13694
  if(!this.deprecationCheck("menuContainer", "popupContainer")){
13628
13695
  this.table.options.popupContainer = this.table.options.menuContainer;
@@ -13638,6 +13705,10 @@ class Menu extends Module{
13638
13705
  if(this.table.options.rowClickMenu){
13639
13706
  this.subscribe("row-click", this.loadMenuEvent.bind(this, this.table.options.rowClickMenu));
13640
13707
  }
13708
+
13709
+ if(this.table.options.rowDblClickMenu){
13710
+ this.subscribe("row-dblclick", this.loadMenuEvent.bind(this, this.table.options.rowDblClickMenu));
13711
+ }
13641
13712
  }
13642
13713
 
13643
13714
  initializeGroupWatchers(){
@@ -13649,6 +13720,10 @@ class Menu extends Module{
13649
13720
  if(this.table.options.groupClickMenu){
13650
13721
  this.subscribe("group-click", this.loadMenuEvent.bind(this, this.table.options.groupClickMenu));
13651
13722
  }
13723
+
13724
+ if(this.table.options.groupDblClickMenu){
13725
+ this.subscribe("group-dblclick", this.loadMenuEvent.bind(this, this.table.options.groupDblClickMenu));
13726
+ }
13652
13727
  }
13653
13728
 
13654
13729
  initializeColumn(column){
@@ -13666,6 +13741,11 @@ class Menu extends Module{
13666
13741
  this.subscribe("column-click", this.columnSubscribers.headerClickMenu);
13667
13742
  }
13668
13743
 
13744
+ if(def.headerDblClickMenu && !this.columnSubscribers.headerDblClickMenu){
13745
+ this.columnSubscribers.headerDblClickMenu = this.loadMenuTableColumnEvent.bind(this, "headerDblClickMenu");
13746
+ this.subscribe("column-dblclick", this.columnSubscribers.headerDblClickMenu);
13747
+ }
13748
+
13669
13749
  if(def.headerMenu){
13670
13750
  this.initializeColumnHeaderMenu(column);
13671
13751
  }
@@ -13681,6 +13761,11 @@ class Menu extends Module{
13681
13761
  this.columnSubscribers.clickMenu = this.loadMenuTableCellEvent.bind(this, "clickMenu");
13682
13762
  this.subscribe("cell-click", this.columnSubscribers.clickMenu);
13683
13763
  }
13764
+
13765
+ if(def.dblClickMenu && !this.columnSubscribers.dblClickMenu){
13766
+ this.columnSubscribers.dblClickMenu = this.loadMenuTableCellEvent.bind(this, "dblClickMenu");
13767
+ this.subscribe("cell-dblclick", this.columnSubscribers.dblClickMenu);
13768
+ }
13684
13769
  }
13685
13770
 
13686
13771
  initializeColumnHeaderMenu(column){
@@ -13689,12 +13774,12 @@ class Menu extends Module{
13689
13774
 
13690
13775
  headerMenuEl = document.createElement("span");
13691
13776
  headerMenuEl.classList.add("tabulator-header-popup-button");
13692
-
13777
+
13693
13778
  if(icon){
13694
13779
  if(typeof icon === "function"){
13695
13780
  icon = icon(column.getComponent());
13696
13781
  }
13697
-
13782
+
13698
13783
  if(icon instanceof HTMLElement){
13699
13784
  headerMenuEl.appendChild(icon);
13700
13785
  }else {
@@ -13837,7 +13922,9 @@ class Menu extends Module{
13837
13922
  });
13838
13923
 
13839
13924
  menuEl.addEventListener("click", (e) => {
13840
- this.rootPopup.hide();
13925
+ if(this.rootPopup){
13926
+ this.rootPopup.hide();
13927
+ }
13841
13928
  });
13842
13929
 
13843
13930
  popup.show(parentEl || e);
@@ -13851,9 +13938,9 @@ class Menu extends Module{
13851
13938
  this.currentComponent = null;
13852
13939
  }
13853
13940
  });
13854
-
13941
+
13855
13942
  this.currentComponent = component;
13856
-
13943
+
13857
13944
  this.dispatchExternal("menuOpened", component.getComponent());
13858
13945
  }
13859
13946
  }
@@ -14024,7 +14111,7 @@ class MoveColumns extends Module{
14024
14111
 
14025
14112
  startMove(e, column){
14026
14113
  var element = column.getElement(),
14027
- headerElement = this.table.columnManager.getElement(),
14114
+ headerElement = this.table.columnManager.getContentsElement(),
14028
14115
  headersElement = this.table.columnManager.getHeadersElement();
14029
14116
 
14030
14117
  this.moving = column;
@@ -14043,7 +14130,7 @@ class MoveColumns extends Module{
14043
14130
  this.hoverElement = element.cloneNode(true);
14044
14131
  this.hoverElement.classList.add("tabulator-moving");
14045
14132
 
14046
- this.table.columnManager.getElement().appendChild(this.hoverElement);
14133
+ headerElement.appendChild(this.hoverElement);
14047
14134
 
14048
14135
  this.hoverElement.style.left = "0";
14049
14136
  this.hoverElement.style.bottom = (headerElement.clientHeight - headersElement.offsetHeight) + "px";
@@ -14125,7 +14212,7 @@ class MoveColumns extends Module{
14125
14212
  }
14126
14213
 
14127
14214
  moveHover(e){
14128
- var columnHolder = this.table.columnManager.getElement(),
14215
+ var columnHolder = this.table.columnManager.getContentsElement(),
14129
14216
  scrollLeft = columnHolder.scrollLeft,
14130
14217
  xPos = ((this.touchMove ? e.touches[0].pageX : e.pageX) - Helpers.elOffset(columnHolder).left) + scrollLeft,
14131
14218
  scrollPos;
@@ -16083,6 +16170,7 @@ class Persistence extends Module{
16083
16170
  this.subscribe("group-changed", this.eventSave.bind(this, "group"));
16084
16171
  this.subscribe("page-changed", this.eventSave.bind(this, "page"));
16085
16172
  this.subscribe("column-resized", this.eventSave.bind(this, "columns"));
16173
+ this.subscribe("column-width", this.eventSave.bind(this, "columns"));
16086
16174
  this.subscribe("layout-refreshed", this.eventSave.bind(this, "columns"));
16087
16175
  }
16088
16176
 
@@ -16405,15 +16493,24 @@ class Popup$1 extends Module{
16405
16493
 
16406
16494
  this.registerTableOption("rowContextPopup", false);
16407
16495
  this.registerTableOption("rowClickPopup", false);
16496
+ this.registerTableOption("rowDblClickPopup", false);
16408
16497
  this.registerTableOption("groupContextPopup", false);
16409
16498
  this.registerTableOption("groupClickPopup", false);
16499
+ this.registerTableOption("groupDblClickPopup", false);
16410
16500
 
16411
16501
  this.registerColumnOption("headerContextPopup");
16412
16502
  this.registerColumnOption("headerClickPopup");
16503
+ this.registerColumnOption("headerDblClickPopup");
16413
16504
  this.registerColumnOption("headerPopup");
16414
16505
  this.registerColumnOption("headerPopupIcon");
16415
16506
  this.registerColumnOption("contextPopup");
16416
16507
  this.registerColumnOption("clickPopup");
16508
+ this.registerColumnOption("dblClickPopup");
16509
+
16510
+ this.registerComponentFunction("cell", "popup", this._componentPopupCall.bind(this));
16511
+ this.registerComponentFunction("column", "popup", this._componentPopupCall.bind(this));
16512
+ this.registerComponentFunction("row", "popup", this._componentPopupCall.bind(this));
16513
+ this.registerComponentFunction("group", "popup", this._componentPopupCall.bind(this));
16417
16514
 
16418
16515
  }
16419
16516
 
@@ -16423,6 +16520,10 @@ class Popup$1 extends Module{
16423
16520
 
16424
16521
  this.subscribe("column-init", this.initializeColumn.bind(this));
16425
16522
  }
16523
+
16524
+ _componentPopupCall(component, contents, position){
16525
+ this.loadPopupEvent(contents, null, component, position);
16526
+ }
16426
16527
 
16427
16528
  initializeRowWatchers(){
16428
16529
  if(this.table.options.rowContextPopup){
@@ -16433,6 +16534,10 @@ class Popup$1 extends Module{
16433
16534
  if(this.table.options.rowClickPopup){
16434
16535
  this.subscribe("row-click", this.loadPopupEvent.bind(this, this.table.options.rowClickPopup));
16435
16536
  }
16537
+
16538
+ if(this.table.options.rowDblClickPopup){
16539
+ this.subscribe("row-dblclick", this.loadPopupEvent.bind(this, this.table.options.rowDblClickPopup));
16540
+ }
16436
16541
  }
16437
16542
 
16438
16543
  initializeGroupWatchers(){
@@ -16444,6 +16549,10 @@ class Popup$1 extends Module{
16444
16549
  if(this.table.options.groupClickPopup){
16445
16550
  this.subscribe("group-click", this.loadPopupEvent.bind(this, this.table.options.groupClickPopup));
16446
16551
  }
16552
+
16553
+ if(this.table.options.groupDblClickPopup){
16554
+ this.subscribe("group-dblclick", this.loadPopupEvent.bind(this, this.table.options.groupDblClickPopup));
16555
+ }
16447
16556
  }
16448
16557
 
16449
16558
  initializeColumn(column){
@@ -16459,6 +16568,11 @@ class Popup$1 extends Module{
16459
16568
  if(def.headerClickPopup && !this.columnSubscribers.headerClickPopup){
16460
16569
  this.columnSubscribers.headerClickPopup = this.loadPopupTableColumnEvent.bind(this, "headerClickPopup");
16461
16570
  this.subscribe("column-click", this.columnSubscribers.headerClickPopup);
16571
+
16572
+
16573
+ }if(def.headerDblClickPopup && !this.columnSubscribers.headerDblClickPopup){
16574
+ this.columnSubscribers.headerDblClickPopup = this.loadPopupTableColumnEvent.bind(this, "headerDblClickPopup");
16575
+ this.subscribe("column-dblclick", this.columnSubscribers.headerDblClickPopup);
16462
16576
  }
16463
16577
 
16464
16578
  if(def.headerPopup){
@@ -16476,6 +16590,11 @@ class Popup$1 extends Module{
16476
16590
  this.columnSubscribers.clickPopup = this.loadPopupTableCellEvent.bind(this, "clickPopup");
16477
16591
  this.subscribe("cell-click", this.columnSubscribers.clickPopup);
16478
16592
  }
16593
+
16594
+ if(def.dblClickPopup && !this.columnSubscribers.dblClickPopup){
16595
+ this.columnSubscribers.dblClickPopup = this.loadPopupTableCellEvent.bind(this, "dblClickPopup");
16596
+ this.subscribe("cell-click", this.columnSubscribers.dblClickPopup);
16597
+ }
16479
16598
  }
16480
16599
 
16481
16600
  initializeColumnHeaderPopup(column){
@@ -16529,7 +16648,7 @@ class Popup$1 extends Module{
16529
16648
  }
16530
16649
  }
16531
16650
 
16532
- loadPopupEvent(contents, e, component){
16651
+ loadPopupEvent(contents, e, component, position){
16533
16652
  var renderedCallback;
16534
16653
 
16535
16654
  function onRendered(callback){
@@ -16544,10 +16663,10 @@ class Popup$1 extends Module{
16544
16663
 
16545
16664
  contents = typeof contents == "function" ? contents.call(this.table, e, component.getComponent(), onRendered) : contents;
16546
16665
 
16547
- this.loadPopup(e, component, contents, renderedCallback);
16666
+ this.loadPopup(e, component, contents, renderedCallback, position);
16548
16667
  }
16549
16668
 
16550
- loadPopup(e, component, contents, renderedCallback){
16669
+ loadPopup(e, component, contents, renderedCallback, position){
16551
16670
  var touch = !(e instanceof MouseEvent),
16552
16671
  contentsEl, popup;
16553
16672
 
@@ -16573,8 +16692,15 @@ class Popup$1 extends Module{
16573
16692
  if(typeof renderedCallback === "function"){
16574
16693
  popup.renderCallback(renderedCallback);
16575
16694
  }
16695
+
16696
+ if(e){
16697
+ popup.show(e);
16698
+ }else {
16699
+ popup.show(component.getElement(), position || "center");
16700
+ }
16701
+
16576
16702
 
16577
- popup.show(e).hideOnBlur(() => {
16703
+ popup.hideOnBlur(() => {
16578
16704
  this.dispatchExternal("popupClosed", component.getComponent());
16579
16705
  });
16580
16706
 
@@ -17191,15 +17317,32 @@ class ResizeColumns extends Module{
17191
17317
  }
17192
17318
  }
17193
17319
  }
17320
+
17321
+ frozenColumnOffset(column){
17322
+ var offset = false;
17323
+
17324
+ if(column.modules.frozen){
17325
+ offset = column.modules.frozen.marginValue;
17326
+
17327
+ if(column.modules.frozen.position === "left"){
17328
+ offset += column.getWidth() - 3;
17329
+ }else {
17330
+ if(offset){
17331
+ offset -= 3;
17332
+ }
17333
+ }
17334
+ }
17335
+
17336
+ return offset !== false ? offset + "px" : false;
17337
+ }
17194
17338
 
17195
17339
  reinitializeColumn(column){
17196
- var frozenOffset = column.modules.frozen ? (column.modules.frozen.marginValue + column.getWidth() + "px") : false;
17197
-
17340
+ var frozenOffset = this.frozenColumnOffset(column);
17198
17341
 
17199
17342
  column.cells.forEach((cell) => {
17200
17343
  if(cell.modules.resize && cell.modules.resize.handleEl){
17201
17344
  if(frozenOffset){
17202
- cell.modules.resize.handleEl.style.left = frozenOffset;
17345
+ cell.modules.resize.handleEl.style[column.modules.frozen.position] = frozenOffset;
17203
17346
  }
17204
17347
 
17205
17348
  cell.element.after(cell.modules.resize.handleEl);
@@ -17208,7 +17351,7 @@ class ResizeColumns extends Module{
17208
17351
 
17209
17352
  if(column.modules.resize && column.modules.resize.handleEl){
17210
17353
  if(frozenOffset){
17211
- column.modules.resize.handleEl.style.left = frozenOffset;
17354
+ column.modules.resize.handleEl.style[column.modules.frozen.position] = frozenOffset;
17212
17355
  }
17213
17356
 
17214
17357
  column.element.after(column.modules.resize.handleEl);
@@ -17260,8 +17403,8 @@ class ResizeColumns extends Module{
17260
17403
  });
17261
17404
 
17262
17405
  if(column.modules.frozen){
17263
- handle.style.position = "absolute";
17264
- handle.style.left = column.modules.frozen.marginValue + column.getWidth() + "px";
17406
+ handle.style.position = "sticky";
17407
+ handle.style[column.modules.frozen.position] = this.frozenColumnOffset(column);
17265
17408
  }
17266
17409
 
17267
17410
  config.handleEl = handle;
@@ -17373,6 +17516,8 @@ class ResizeColumns extends Module{
17373
17516
  self.table.element.classList.remove("tabulator-block-select");
17374
17517
 
17375
17518
  if(self.startWidth !== column.getWidth()){
17519
+ self.table.columnManager.verticalAlignHeaders();
17520
+
17376
17521
  self.dispatch("column-resized", column);
17377
17522
  self.table.externalEvents.dispatch("columnResized", column.getComponent());
17378
17523
  }
@@ -17565,7 +17710,7 @@ class ResizeTable extends Module{
17565
17710
  this.containerHeight = table.element.parentNode.clientHeight;
17566
17711
  this.containerWidth = table.element.parentNode.clientWidth;
17567
17712
  }
17568
-
17713
+
17569
17714
  this.redrawTable();
17570
17715
  }
17571
17716
  }
@@ -17617,17 +17762,16 @@ class ResizeTable extends Module{
17617
17762
  initializeVisibilityObserver(){
17618
17763
  this.visibilityObserver = new IntersectionObserver((entries) => {
17619
17764
  this.visible = entries[0].isIntersecting;
17620
-
17765
+
17621
17766
  if(!this.initialized){
17622
17767
  this.initialized = true;
17623
17768
  this.initialRedraw = !this.visible;
17769
+ }else {
17770
+ if(this.visible){
17771
+ this.redrawTable(this.initialRedraw);
17772
+ this.initialRedraw = false;
17773
+ }
17624
17774
  }
17625
-
17626
- if(this.visible){
17627
- this.redrawTable(this.initialRedraw);
17628
- this.initialRedraw = false;
17629
- }
17630
-
17631
17775
  });
17632
17776
 
17633
17777
  this.visibilityObserver.observe(this.table.element);
@@ -17848,22 +17992,21 @@ class ResponsiveLayout extends Module{
17848
17992
 
17849
17993
  //redraw columns to fit space
17850
17994
  update(){
17851
- var self = this,
17852
- working = true;
17995
+ var working = true;
17853
17996
 
17854
17997
  while(working){
17855
17998
 
17856
- let width = self.table.modules.layout.getMode() == "fitColumns" ? self.table.columnManager.getFlexBaseWidth() : self.table.columnManager.getWidth();
17999
+ let width = this.table.modules.layout.getMode() == "fitColumns" ? this.table.columnManager.getFlexBaseWidth() : this.table.columnManager.getWidth();
17857
18000
 
17858
- let diff = (self.table.options.headerVisible ? self.table.columnManager.element.clientWidth : self.table.element.clientWidth) - width;
18001
+ let diff = (this.table.options.headerVisible ? this.table.columnManager.element.clientWidth : this.table.element.clientWidth) - width;
17859
18002
 
17860
18003
  if(diff < 0){
17861
18004
  //table is too wide
17862
- let column = self.columns[self.index];
18005
+ let column = this.columns[this.index];
17863
18006
 
17864
18007
  if(column){
17865
- self.hideColumn(column);
17866
- self.index ++;
18008
+ this.hideColumn(column);
18009
+ this.index ++;
17867
18010
  }else {
17868
18011
  working = false;
17869
18012
  }
@@ -17871,13 +18014,13 @@ class ResponsiveLayout extends Module{
17871
18014
  }else {
17872
18015
 
17873
18016
  //table has spare space
17874
- let column = self.columns[self.index -1];
18017
+ let column = this.columns[this.index -1];
17875
18018
 
17876
18019
  if(column){
17877
18020
  if(diff > 0){
17878
18021
  if(diff >= column.getWidth()){
17879
- self.showColumn(column);
17880
- self.index --;
18022
+ this.showColumn(column);
18023
+ this.index --;
17881
18024
  }else {
17882
18025
  working = false;
17883
18026
  }
@@ -17889,18 +18032,17 @@ class ResponsiveLayout extends Module{
17889
18032
  }
17890
18033
  }
17891
18034
 
17892
- if(!self.table.rowManager.activeRowsCount){
17893
- self.table.rowManager.renderEmptyScroll();
18035
+ if(!this.table.rowManager.activeRowsCount){
18036
+ this.table.rowManager.renderEmptyScroll();
17894
18037
  }
17895
18038
  }
17896
18039
  }
17897
18040
 
17898
18041
  generateCollapsedContent(){
17899
- var self = this,
17900
- rows = this.table.rowManager.getDisplayRows();
18042
+ var rows = this.table.rowManager.getDisplayRows();
17901
18043
 
17902
- rows.forEach(function(row){
17903
- self.generateCollapsedRowContent(row);
18044
+ rows.forEach((row) => {
18045
+ this.generateCollapsedRowContent(row);
17904
18046
  });
17905
18047
  }
17906
18048
 
@@ -17920,16 +18062,15 @@ class ResponsiveLayout extends Module{
17920
18062
  }
17921
18063
 
17922
18064
  generateCollapsedRowData(row){
17923
- var self = this,
17924
- data = row.getData(),
18065
+ var data = row.getData(),
17925
18066
  output = [],
17926
18067
  mockCellComponent;
17927
18068
 
17928
- this.hiddenColumns.forEach(function(column){
18069
+ this.hiddenColumns.forEach((column) => {
17929
18070
  var value = column.getFieldValue(data);
17930
18071
 
17931
18072
  if(column.definition.title && column.field){
17932
- if(column.modules.format && self.table.options.responsiveLayoutCollapseUseFormatters){
18073
+ if(column.modules.format && this.table.options.responsiveLayoutCollapseUseFormatters){
17933
18074
 
17934
18075
  mockCellComponent = {
17935
18076
  value:false,
@@ -17949,6 +18090,9 @@ class ResponsiveLayout extends Module{
17949
18090
  getColumn:function(){
17950
18091
  return column.getComponent();
17951
18092
  },
18093
+ getTable:() => {
18094
+ return this.table;
18095
+ },
17952
18096
  };
17953
18097
 
17954
18098
  function onRendered(callback){
@@ -17958,7 +18102,7 @@ class ResponsiveLayout extends Module{
17958
18102
  output.push({
17959
18103
  field: column.field,
17960
18104
  title: column.definition.title,
17961
- value: column.modules.format.formatter.call(self.table.modules.format, mockCellComponent, column.modules.format.params, onRendered)
18105
+ value: column.modules.format.formatter.call(this.table.modules.format, mockCellComponent, column.modules.format.params, onRendered)
17962
18106
  });
17963
18107
  }else {
17964
18108
  output.push({
@@ -18722,6 +18866,7 @@ class Sort extends Module{
18722
18866
  this.registerTableOption("columnHeaderSortMulti", true); //multiple or single column sorting
18723
18867
  this.registerTableOption("sortOrderReverse", false); //reverse internal sort ordering
18724
18868
  this.registerTableOption("headerSortElement", "<div class='tabulator-arrow'></div>"); //header sort element
18869
+ this.registerTableOption("headerSortClickElement", "header"); //element which triggers sort when clicked
18725
18870
 
18726
18871
  this.registerColumnOption("sorter");
18727
18872
  this.registerColumnOption("sorterParams");
@@ -18819,10 +18964,21 @@ class Sort extends Module{
18819
18964
 
18820
18965
  colEl.classList.add("tabulator-sortable");
18821
18966
 
18822
-
18823
18967
  arrowEl = document.createElement("div");
18824
18968
  arrowEl.classList.add("tabulator-col-sorter");
18825
18969
 
18970
+ switch(this.table.options.headerSortClickElement){
18971
+ case "icon":
18972
+ arrowEl.classList.add("tabulator-col-sorter-element");
18973
+ break;
18974
+ case "header":
18975
+ colEl.classList.add("tabulator-col-sorter-element");
18976
+ break;
18977
+ default:
18978
+ colEl.classList.add("tabulator-col-sorter-element");
18979
+ break;
18980
+ }
18981
+
18826
18982
  switch(this.table.options.headerSortElement){
18827
18983
  case "function":
18828
18984
  //do nothing
@@ -18844,7 +19000,7 @@ class Sort extends Module{
18844
19000
  this.setColumnHeaderSortIcon(column, "none");
18845
19001
 
18846
19002
  //sort on click
18847
- colEl.addEventListener("click", (e) => {
19003
+ (this.table.options.headerSortClickElement === "icon" ? arrowEl : colEl).addEventListener("click", (e) => {
18848
19004
  var dir = "",
18849
19005
  sorters=[],
18850
19006
  match = false;
@@ -20115,7 +20271,7 @@ class VirtualDomHorizontal extends Renderer{
20115
20271
  this.windowBuffer = 200; //pixel margin to make column visible before it is shown on screen
20116
20272
 
20117
20273
  this.visibleRows = null;
20118
-
20274
+
20119
20275
  this.initialized = false;
20120
20276
  this.isFitData = false;
20121
20277
 
@@ -20128,53 +20284,29 @@ class VirtualDomHorizontal extends Renderer{
20128
20284
  this.vertScrollListen();
20129
20285
  }
20130
20286
 
20131
- compatibilityCheck(){
20132
- var columns = this.options("columns"),
20133
- frozen = false,
20134
- ok = true;
20135
-
20287
+ compatibilityCheck(){
20136
20288
  if(this.options("layout") == "fitDataTable"){
20137
20289
  console.warn("Horizontal Virtual DOM is not compatible with fitDataTable layout mode");
20138
- ok = false;
20139
20290
  }
20140
20291
 
20141
20292
  if(this.options("responsiveLayout")){
20142
20293
  console.warn("Horizontal Virtual DOM is not compatible with responsive columns");
20143
- ok = false;
20144
20294
  }
20145
20295
 
20146
20296
  if(this.options("rtl")){
20147
20297
  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
20298
  }
20161
-
20162
- // if(!ok){
20163
- // options.virtualDomHoz = false;
20164
- // }
20165
-
20166
- return ok;
20167
20299
  }
20168
20300
 
20169
20301
  layoutCheck(){
20170
20302
  this.isFitData = this.options("layout").startsWith('fitData');
20171
20303
  }
20172
-
20304
+
20173
20305
  vertScrollListen(){
20174
20306
  this.subscribe("scroll-vertical", this.clearVisRowCache.bind(this));
20175
20307
  this.subscribe("data-refreshed", this.clearVisRowCache.bind(this));
20176
20308
  }
20177
-
20309
+
20178
20310
  clearVisRowCache(){
20179
20311
  this.visibleRows = null;
20180
20312
  }
@@ -20186,7 +20318,7 @@ class VirtualDomHorizontal extends Renderer{
20186
20318
  renderColumns(row, force){
20187
20319
  this.dataChange();
20188
20320
  }
20189
-
20321
+
20190
20322
 
20191
20323
  scrollColumns(left, dir){
20192
20324
  if(this.scrollLeft != left){
@@ -20220,7 +20352,6 @@ class VirtualDomHorizontal extends Renderer{
20220
20352
  },
20221
20353
  colPos = 0;
20222
20354
 
20223
-
20224
20355
  if(update && !this.initialized){
20225
20356
  return;
20226
20357
  }
@@ -20235,41 +20366,44 @@ class VirtualDomHorizontal extends Renderer{
20235
20366
  this.vDomScrollPosRight = this.scrollLeft + this.elementVertical.clientWidth + this.windowBuffer;
20236
20367
 
20237
20368
  this.table.columnManager.columnsByIndex.forEach((column) => {
20238
- var config = {};
20369
+ var config = {},
20370
+ width;
20239
20371
 
20240
20372
  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
20373
+ if(!column.modules.frozen){
20374
+ width = column.getWidth();
20375
+
20376
+ config.leftPos = colPos;
20377
+ config.rightPos = colPos + width;
20254
20378
 
20255
- if(this.leftCol == -1){
20256
- this.leftCol = this.columns.length;
20257
- this.vDomPadLeft = colPos;
20379
+ config.width = width;
20380
+
20381
+ if (this.isFitData) {
20382
+ config.fitDataCheck = column.modules.vdomHoz ? column.modules.vdomHoz.fitDataCheck : true;
20258
20383
  }
20259
20384
 
20260
- this.rightCol = this.columns.length;
20261
- }else {
20262
- // column is hidden
20263
- if(this.leftCol !== -1){
20264
- this.vDomPadRight += width;
20385
+ if((colPos + width > this.vDomScrollPosLeft) && (colPos < this.vDomScrollPosRight)){
20386
+ //column is visible
20387
+
20388
+ if(this.leftCol == -1){
20389
+ this.leftCol = this.columns.length;
20390
+ this.vDomPadLeft = colPos;
20391
+ }
20392
+
20393
+ this.rightCol = this.columns.length;
20394
+ }else {
20395
+ // column is hidden
20396
+ if(this.leftCol !== -1){
20397
+ this.vDomPadRight += width;
20398
+ }
20265
20399
  }
20400
+
20401
+ this.columns.push(column);
20402
+
20403
+ column.modules.vdomHoz = config;
20404
+
20405
+ colPos += width;
20266
20406
  }
20267
-
20268
- this.columns.push(column);
20269
-
20270
- column.modules.vdomHoz = config;
20271
-
20272
- colPos += width;
20273
20407
  }
20274
20408
  });
20275
20409
 
@@ -20361,7 +20495,7 @@ class VirtualDomHorizontal extends Renderer{
20361
20495
  }
20362
20496
 
20363
20497
  rowEl.parentNode.removeChild(rowEl);
20364
-
20498
+
20365
20499
  this.rerenderColumns(false, true);
20366
20500
  }
20367
20501
  }
@@ -20390,24 +20524,30 @@ class VirtualDomHorizontal extends Renderer{
20390
20524
  }
20391
20525
 
20392
20526
  reinitializeRows(){
20393
- var rows = this.getVisibleRows();
20394
- rows.forEach((row) => {
20527
+ var visibleRows = this.getVisibleRows(),
20528
+ otherRows = this.table.rowManager.getRows().filter(row => !visibleRows.includes(row));
20529
+
20530
+ visibleRows.forEach((row) => {
20395
20531
  this.reinitializeRow(row, true);
20396
20532
  });
20533
+
20534
+ otherRows.forEach((row) =>{
20535
+ row.deinitialize();
20536
+ });
20397
20537
  }
20398
20538
 
20399
20539
  getVisibleRows(){
20400
20540
  if (!this.visibleRows){
20401
20541
  this.visibleRows = this.table.rowManager.getVisibleRows();
20402
20542
  }
20403
-
20543
+
20404
20544
  return this.visibleRows;
20405
20545
  }
20406
20546
 
20407
20547
  scroll(diff){
20408
20548
  this.vDomScrollPosLeft += diff;
20409
20549
  this.vDomScrollPosRight += diff;
20410
-
20550
+
20411
20551
  if(Math.abs(diff) > (this.windowBuffer / 2)){
20412
20552
  this.rerenderColumns();
20413
20553
  }else {
@@ -20437,7 +20577,7 @@ class VirtualDomHorizontal extends Renderer{
20437
20577
  working = true;
20438
20578
 
20439
20579
  while(working){
20440
-
20580
+
20441
20581
  let column = this.columns[this.rightCol + 1];
20442
20582
 
20443
20583
  if(column){
@@ -20447,7 +20587,7 @@ class VirtualDomHorizontal extends Renderer{
20447
20587
  this.getVisibleRows().forEach((row) => {
20448
20588
  if(row.type !== "group"){
20449
20589
  var cell = row.getCell(column);
20450
- row.getElement().appendChild(cell.getElement());
20590
+ row.getElement().insertBefore(cell.getElement(), row.getCell(this.columns[this.rightCol]).getElement().nextSibling);
20451
20591
  cell.cellRendered();
20452
20592
  }
20453
20593
  });
@@ -20488,7 +20628,7 @@ class VirtualDomHorizontal extends Renderer{
20488
20628
  this.getVisibleRows().forEach((row) => {
20489
20629
  if(row.type !== "group"){
20490
20630
  var cell = row.getCell(column);
20491
- row.getElement().prepend(cell.getElement());
20631
+ row.getElement().insertBefore(cell.getElement(), row.getCell(this.columns[this.leftCol]).getElement());
20492
20632
  cell.cellRendered();
20493
20633
  }
20494
20634
  });
@@ -20562,7 +20702,7 @@ class VirtualDomHorizontal extends Renderer{
20562
20702
  removeColLeft(){
20563
20703
  var changes = false,
20564
20704
  working = true;
20565
-
20705
+
20566
20706
  while(working){
20567
20707
  let column = this.columns[this.leftCol];
20568
20708
 
@@ -20624,26 +20764,41 @@ class VirtualDomHorizontal extends Renderer{
20624
20764
  leftCol:this.leftCol,
20625
20765
  rightCol:this.rightCol,
20626
20766
  };
20627
-
20767
+
20768
+ if(this.table.modules.frozenColumns){
20769
+ this.table.modules.frozenColumns.leftColumns.forEach((column) => {
20770
+ this.appendCell(row, column);
20771
+ });
20772
+ }
20773
+
20628
20774
  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
- }
20775
+ this.appendCell(row, this.columns[i]);
20637
20776
  }
20777
+
20778
+ if(this.table.modules.frozenColumns){
20779
+ this.table.modules.frozenColumns.rightColumns.forEach((column) => {
20780
+ this.appendCell(row, column);
20781
+ });
20782
+ }
20783
+ }
20784
+ }
20785
+
20786
+ appendCell(row, column){
20787
+ if(column && column.visible){
20788
+ let cell = row.getCell(column);
20789
+
20790
+ row.getElement().appendChild(cell.getElement());
20791
+ cell.cellRendered();
20638
20792
  }
20639
20793
  }
20640
20794
 
20641
20795
  reinitializeRow(row, force){
20642
20796
  if(row.type !== "group"){
20643
20797
  if(force || !row.modules.vdomHoz || row.modules.vdomHoz.leftCol !== this.leftCol || row.modules.vdomHoz.rightCol !== this.rightCol){
20798
+
20644
20799
  var rowEl = row.getElement();
20645
20800
  while(rowEl.firstChild) rowEl.removeChild(rowEl.firstChild);
20646
-
20801
+
20647
20802
  this.initializeRow(row);
20648
20803
  }
20649
20804
  }
@@ -20657,6 +20812,7 @@ class ColumnManager extends CoreFeature {
20657
20812
 
20658
20813
  this.blockHozScrollEvent = false;
20659
20814
  this.headersElement = null;
20815
+ this.contentsElement = null;
20660
20816
  this.element = null ; //containing element
20661
20817
  this.columns = []; // column definition object
20662
20818
  this.columnsByIndex = []; //columns by index
@@ -20676,11 +20832,22 @@ class ColumnManager extends CoreFeature {
20676
20832
  this.initializeRenderer();
20677
20833
 
20678
20834
  this.headersElement = this.createHeadersElement();
20835
+ this.contentsElement = this.createHeaderContentsElement();
20679
20836
  this.element = this.createHeaderElement();
20680
20837
 
20681
- this.element.insertBefore(this.headersElement, this.element.firstChild);
20838
+ this.contentsElement.insertBefore(this.headersElement, this.contentsElement.firstChild);
20839
+ this.element.insertBefore(this.contentsElement, this.element.firstChild);
20682
20840
 
20683
20841
  this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this));
20842
+ this.subscribe("scrollbar-vertical", this.padVerticalScrollbar.bind(this));
20843
+ }
20844
+
20845
+ padVerticalScrollbar(width){
20846
+ if(this.table.rtl){
20847
+ this.headersElement.style.marginLeft = width + "px";
20848
+ }else {
20849
+ this.headersElement.style.marginRight = width + "px";
20850
+ }
20684
20851
  }
20685
20852
 
20686
20853
  initializeRenderer(){
@@ -20714,6 +20881,15 @@ class ColumnManager extends CoreFeature {
20714
20881
 
20715
20882
  return el;
20716
20883
  }
20884
+
20885
+ createHeaderContentsElement (){
20886
+ var el = document.createElement("div");
20887
+
20888
+ el.classList.add("tabulator-header-contents");
20889
+ el.setAttribute("role", "rowgroup");
20890
+
20891
+ return el;
20892
+ }
20717
20893
 
20718
20894
  createHeaderElement (){
20719
20895
  var el = document.createElement("div");
@@ -20732,6 +20908,12 @@ class ColumnManager extends CoreFeature {
20732
20908
  getElement(){
20733
20909
  return this.element;
20734
20910
  }
20911
+
20912
+ //return containing contents element
20913
+ getContentsElement(){
20914
+ return this.contentsElement;
20915
+ }
20916
+
20735
20917
 
20736
20918
  //return header containing element
20737
20919
  getHeadersElement(){
@@ -20740,20 +20922,8 @@ class ColumnManager extends CoreFeature {
20740
20922
 
20741
20923
  //scroll horizontally to match table body
20742
20924
  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
-
20925
+ this.contentsElement.scrollLeft = left;
20926
+
20757
20927
  this.scrollLeft = left;
20758
20928
 
20759
20929
  this.renderer.scrollColumns(left);
@@ -20928,7 +21098,7 @@ class ColumnManager extends CoreFeature {
20928
21098
 
20929
21099
  if(!this.redrawBlock){
20930
21100
 
20931
- this.element.style.height="";
21101
+ this.headersElement.style.height="";
20932
21102
 
20933
21103
  this.columns.forEach((column) => {
20934
21104
  column.clearVerticalAlign();
@@ -20942,7 +21112,7 @@ class ColumnManager extends CoreFeature {
20942
21112
  }
20943
21113
  });
20944
21114
 
20945
- this.element.style.height = minHeight + "px";
21115
+ this.headersElement.style.height = minHeight + "px";
20946
21116
 
20947
21117
  this.columns.forEach((column) => {
20948
21118
  column.verticalAlign(this.table.options.columnHeaderVertAlign, minHeight);
@@ -22045,6 +22215,8 @@ class RowManager extends CoreFeature{
22045
22215
 
22046
22216
  this.dataPipeline = []; //hold data pipeline tasks
22047
22217
  this.displayPipeline = []; //hold data display pipeline tasks
22218
+
22219
+ this.scrollbarWidth = 0;
22048
22220
 
22049
22221
  this.renderer = null;
22050
22222
  }
@@ -22727,6 +22899,10 @@ class RowManager extends CoreFeature{
22727
22899
  //case to handle scenario when trying to skip past end stage
22728
22900
  this.regenerateRowPositions();
22729
22901
  }
22902
+
22903
+ if(this.getDisplayRows().length){
22904
+ this._clearPlaceholder();
22905
+ }
22730
22906
  }
22731
22907
 
22732
22908
  //regenerate row positions
@@ -22795,7 +22971,7 @@ class RowManager extends CoreFeature{
22795
22971
  getRows(type){
22796
22972
  var rows = [];
22797
22973
 
22798
- if(!type){
22974
+ if(!type || type === true){
22799
22975
  rows = this.chain("rows-retrieve", type, null, this.rows) || this.rows;
22800
22976
  }else {
22801
22977
  switch(type){
@@ -22833,10 +23009,26 @@ class RowManager extends CoreFeature{
22833
23009
  if(!this.fixedHeight){
22834
23010
  this.adjustTableSize();
22835
23011
  }
23012
+
23013
+ this.scrollBarCheck();
22836
23014
 
22837
23015
  this.dispatchExternal("renderComplete");
22838
23016
  }
22839
23017
  }
23018
+
23019
+ scrollBarCheck(){
23020
+ var scrollbarWidth = 0;
23021
+
23022
+ //adjust for vertical scrollbar moving table when present
23023
+ if(this.element.scrollHeight > this.element.clientHeight){
23024
+ scrollbarWidth = this.element.offsetWidth - this.element.clientWidth;
23025
+ }
23026
+
23027
+ if(scrollbarWidth !== this.scrollbarWidth){
23028
+ this.scrollbarWidth = scrollbarWidth;
23029
+ this.dispatch("scrollbar-vertical", scrollbarWidth);
23030
+ }
23031
+ }
22840
23032
 
22841
23033
  initializeRenderer(){
22842
23034
  var renderClass;
@@ -22899,6 +23091,8 @@ class RowManager extends CoreFeature{
22899
23091
  if(!this.displayRowsCount){
22900
23092
  this._showPlaceholder();
22901
23093
  }
23094
+
23095
+ this.scrollBarCheck();
22902
23096
 
22903
23097
  this.dispatchExternal("renderComplete");
22904
23098
  }
@@ -22935,10 +23129,10 @@ class RowManager extends CoreFeature{
22935
23129
  _clearPlaceholder(){
22936
23130
  if(this.placeholder && this.placeholder.parentNode){
22937
23131
  this.placeholder.parentNode.removeChild(this.placeholder);
22938
-
22939
- // clear empty table placeholder min
22940
- this.tableElement.style.minWidth = "";
22941
23132
  }
23133
+
23134
+ // clear empty table placeholder min
23135
+ this.tableElement.style.minWidth = "";
22942
23136
  }
22943
23137
 
22944
23138
  _positionPlaceholder(){
@@ -22997,6 +23191,8 @@ class RowManager extends CoreFeature{
22997
23191
  this.redraw();
22998
23192
  }
22999
23193
  }
23194
+
23195
+ this.scrollBarCheck();
23000
23196
  }
23001
23197
 
23002
23198
  this._positionPlaceholder();
@@ -23183,6 +23379,8 @@ class InteractionManager extends CoreFeature {
23183
23379
  "mouseover",
23184
23380
  "mouseout",
23185
23381
  "mousemove",
23382
+ "mouseup",
23383
+ "mousedown",
23186
23384
  "touchstart",
23187
23385
  "touchend",
23188
23386
  ];