tabulator-tables 5.5.4 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/bower.json +1 -1
  2. package/dist/css/tabulator.css +72 -2
  3. package/dist/css/tabulator.css.map +1 -1
  4. package/dist/css/tabulator.min.css +1 -1
  5. package/dist/css/tabulator.min.css.map +1 -1
  6. package/dist/css/tabulator_bootstrap3.css +72 -2
  7. package/dist/css/tabulator_bootstrap3.css.map +1 -1
  8. package/dist/css/tabulator_bootstrap3.min.css +1 -1
  9. package/dist/css/tabulator_bootstrap3.min.css.map +1 -1
  10. package/dist/css/tabulator_bootstrap4.css +72 -2
  11. package/dist/css/tabulator_bootstrap4.css.map +1 -1
  12. package/dist/css/tabulator_bootstrap4.min.css +1 -1
  13. package/dist/css/tabulator_bootstrap4.min.css.map +1 -1
  14. package/dist/css/tabulator_bootstrap5.css +72 -2
  15. package/dist/css/tabulator_bootstrap5.css.map +1 -1
  16. package/dist/css/tabulator_bootstrap5.min.css +1 -1
  17. package/dist/css/tabulator_bootstrap5.min.css.map +1 -1
  18. package/dist/css/tabulator_bulma.css +72 -2
  19. package/dist/css/tabulator_bulma.css.map +1 -1
  20. package/dist/css/tabulator_bulma.min.css +1 -1
  21. package/dist/css/tabulator_bulma.min.css.map +1 -1
  22. package/dist/css/tabulator_materialize.css +72 -2
  23. package/dist/css/tabulator_materialize.css.map +1 -1
  24. package/dist/css/tabulator_materialize.min.css +1 -1
  25. package/dist/css/tabulator_materialize.min.css.map +1 -1
  26. package/dist/css/tabulator_midnight.css +72 -2
  27. package/dist/css/tabulator_midnight.css.map +1 -1
  28. package/dist/css/tabulator_midnight.min.css +1 -1
  29. package/dist/css/tabulator_midnight.min.css.map +1 -1
  30. package/dist/css/tabulator_modern.css +72 -2
  31. package/dist/css/tabulator_modern.css.map +1 -1
  32. package/dist/css/tabulator_modern.min.css +1 -1
  33. package/dist/css/tabulator_modern.min.css.map +1 -1
  34. package/dist/css/tabulator_semanticui.css +72 -2
  35. package/dist/css/tabulator_semanticui.css.map +1 -1
  36. package/dist/css/tabulator_semanticui.min.css +1 -1
  37. package/dist/css/tabulator_semanticui.min.css.map +1 -1
  38. package/dist/css/tabulator_simple.css +72 -2
  39. package/dist/css/tabulator_simple.css.map +1 -1
  40. package/dist/css/tabulator_simple.min.css +1 -1
  41. package/dist/css/tabulator_simple.min.css.map +1 -1
  42. package/dist/css/tabulator_site.css +74 -4
  43. package/dist/css/tabulator_site.css.map +1 -1
  44. package/dist/css/tabulator_site.min.css +1 -1
  45. package/dist/css/tabulator_site.min.css.map +1 -1
  46. package/dist/js/tabulator.js +1868 -245
  47. package/dist/js/tabulator.js.map +1 -1
  48. package/dist/js/tabulator.min.js +2 -2
  49. package/dist/js/tabulator.min.js.map +1 -1
  50. package/dist/js/tabulator_esm.js +1948 -323
  51. package/dist/js/tabulator_esm.js.map +1 -1
  52. package/dist/js/tabulator_esm.min.js +2 -2
  53. package/dist/js/tabulator_esm.min.js.map +1 -1
  54. package/package.json +2 -2
  55. package/src/js/core/ColumnManager.js +4 -0
  56. package/src/js/core/CoreFeature.js +2 -2
  57. package/src/js/core/RowManager.js +12 -6
  58. package/src/js/core/Tabulator.js +2 -1
  59. package/src/js/core/TabulatorFull.js +1 -1
  60. package/src/js/core/column/Column.js +10 -0
  61. package/src/js/core/modules/optional.js +2 -1
  62. package/src/js/core/rendering/renderers/BasicVertical.js +4 -2
  63. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +1 -1
  64. package/src/js/core/row/PseudoRow.js +2 -0
  65. package/src/js/core/tools/Alert.js +4 -0
  66. package/src/js/core/tools/DeprecationAdvisor.js +5 -1
  67. package/src/js/core/tools/Helpers.js +1 -1
  68. package/src/js/core/tools/InteractionMonitor.js +3 -3
  69. package/src/js/modules/Clipboard/Clipboard.js +5 -3
  70. package/src/js/modules/Clipboard/defaults/pasteActions.js +49 -6
  71. package/src/js/modules/Clipboard/defaults/pasteParsers.js +69 -14
  72. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +7 -1
  73. package/src/js/modules/Edit/Edit.js +71 -25
  74. package/src/js/modules/Edit/defaults/editors/datetime.js +1 -1
  75. package/src/js/modules/Edit/defaults/editors/time.js +3 -1
  76. package/src/js/modules/Export/Export.js +38 -18
  77. package/src/js/modules/Format/defaults/formatters/rowSelection.js +2 -2
  78. package/src/js/modules/Format/defaults/formatters/rownum.js +5 -1
  79. package/src/js/modules/FrozenColumns/FrozenColumns.js +11 -11
  80. package/src/js/modules/FrozenRows/FrozenRows.js +6 -1
  81. package/src/js/modules/History/History.js +2 -2
  82. package/src/js/modules/History/defaults/redoers.js +4 -0
  83. package/src/js/modules/History/defaults/undoers.js +4 -0
  84. package/src/js/modules/Keybindings/defaults/actions.js +38 -1
  85. package/src/js/modules/Keybindings/defaults/bindings.js +16 -1
  86. package/src/js/modules/Menu/Menu.js +3 -1
  87. package/src/js/modules/MoveColumns/MoveColumns.js +5 -0
  88. package/src/js/modules/Popup/Popup.js +1 -1
  89. package/src/js/modules/ResizeTable/ResizeTable.js +3 -3
  90. package/src/js/modules/SelectRange/Range.js +354 -0
  91. package/src/js/modules/SelectRange/RangeComponent.js +93 -0
  92. package/src/js/modules/SelectRange/SelectRange.js +870 -0
  93. package/src/js/modules/SelectRow/SelectRow.js +46 -26
  94. package/src/js/modules/Sort/Sort.js +111 -105
  95. package/src/js/modules/Validate/defaults/validators.js +11 -0
  96. package/src/scss/tabulator.scss +95 -13
  97. package/src/scss/themes/bulma/tabulator_bulma.scss +7 -0
  98. package/src/scss/themes/materialize/tabulator_materialize.scss +7 -1
  99. package/src/scss/themes/tabulator_midnight.scss +13 -0
  100. package/src/scss/themes/tabulator_modern.scss +9 -0
  101. package/src/scss/themes/tabulator_site.scss +13 -2
@@ -1,4 +1,4 @@
1
- /* Tabulator v5.5.4 (c) Oliver Folkerd 2024 */
1
+ /* Tabulator v5.6.1 (c) Oliver Folkerd 2024 */
2
2
  class CoreFeature{
3
3
 
4
4
  constructor(table){
@@ -119,8 +119,8 @@ class CoreFeature{
119
119
  /////////// Deprecation Checks ///////////
120
120
  //////////////////////////////////////////
121
121
 
122
- deprecationCheck(oldOption, newOption){
123
- return this.table.deprecationAdvisor.check(oldOption, newOption);
122
+ deprecationCheck(oldOption, newOption, convert){
123
+ return this.table.deprecationAdvisor.check(oldOption, newOption, convert);
124
124
  }
125
125
 
126
126
  deprecationCheckMsg(oldOption, msg){
@@ -1079,15 +1079,58 @@ Ajax.defaultLoaderPromise = defaultLoaderPromise;
1079
1079
  Ajax.contentTypeFormatters = defaultContentTypeFormatters;
1080
1080
 
1081
1081
  var defaultPasteActions = {
1082
- replace:function(rows){
1083
- return this.table.setData(rows);
1082
+ replace:function(data){
1083
+ return this.table.setData(data);
1084
1084
  },
1085
- update:function(rows){
1086
- return this.table.updateOrAddData(rows);
1085
+ update:function(data){
1086
+ return this.table.updateOrAddData(data);
1087
1087
  },
1088
- insert:function(rows){
1089
- return this.table.addData(rows);
1088
+ insert:function(data){
1089
+ return this.table.addData(data);
1090
1090
  },
1091
+ range:function(data){
1092
+ var rows = [],
1093
+ range = this.table.modules.selectRange.activeRange,
1094
+ singleCell = false,
1095
+ bounds, startCell, startRow, rowWidth, dataLength;
1096
+
1097
+ dataLength = data.length;
1098
+
1099
+ if(range){
1100
+ bounds = range.getBounds();
1101
+ startCell = bounds.start;
1102
+
1103
+ if(bounds.start === bounds.end){
1104
+ singleCell = true;
1105
+ }
1106
+
1107
+ if(startCell){
1108
+ rows = this.table.rowManager.activeRows.slice();
1109
+ startRow = rows.indexOf(startCell.row);
1110
+
1111
+ if(singleCell){
1112
+ rowWidth = data.length;
1113
+ }else {
1114
+ rowWidth = (rows.indexOf(bounds.end.row) - startRow) + 1;
1115
+ }
1116
+
1117
+
1118
+ if(startRow >-1){
1119
+ this.table.blockRedraw();
1120
+
1121
+ rows = rows.slice(startRow, startRow + rowWidth);
1122
+
1123
+ rows.forEach((row, i) => {
1124
+ row.updateData(data[i % dataLength]);
1125
+ });
1126
+
1127
+ this.table.restoreRedraw();
1128
+ }
1129
+ }
1130
+ }
1131
+
1132
+ return rows;
1133
+ }
1091
1134
  };
1092
1135
 
1093
1136
  var defaultPasteParsers = {
@@ -1097,72 +1140,127 @@ var defaultPasteParsers = {
1097
1140
  columns = this.table.columnManager.columns,
1098
1141
  columnMap = [],
1099
1142
  rows = [];
1100
-
1143
+
1101
1144
  //get data from clipboard into array of columns and rows.
1102
1145
  clipboard = clipboard.split("\n");
1103
-
1146
+
1104
1147
  clipboard.forEach(function(row){
1105
1148
  data.push(row.split("\t"));
1106
1149
  });
1107
-
1150
+
1108
1151
  if(data.length && !(data.length === 1 && data[0].length < 2)){
1109
-
1152
+
1110
1153
  //check if headers are present by title
1111
1154
  data[0].forEach(function(value){
1112
1155
  var column = columns.find(function(column){
1113
1156
  return value && column.definition.title && value.trim() && column.definition.title.trim() === value.trim();
1114
1157
  });
1115
-
1158
+
1116
1159
  if(column){
1117
1160
  columnMap.push(column);
1118
1161
  }else {
1119
1162
  headerFindSuccess = false;
1120
1163
  }
1121
1164
  });
1122
-
1165
+
1123
1166
  //check if column headers are present by field
1124
1167
  if(!headerFindSuccess){
1125
1168
  headerFindSuccess = true;
1126
1169
  columnMap = [];
1127
-
1170
+
1128
1171
  data[0].forEach(function(value){
1129
1172
  var column = columns.find(function(column){
1130
1173
  return value && column.field && value.trim() && column.field.trim() === value.trim();
1131
1174
  });
1132
-
1175
+
1133
1176
  if(column){
1134
1177
  columnMap.push(column);
1135
1178
  }else {
1136
1179
  headerFindSuccess = false;
1137
1180
  }
1138
1181
  });
1139
-
1182
+
1140
1183
  if(!headerFindSuccess){
1141
1184
  columnMap = this.table.columnManager.columnsByIndex;
1142
1185
  }
1143
1186
  }
1144
-
1187
+
1145
1188
  //remove header row if found
1146
1189
  if(headerFindSuccess){
1147
1190
  data.shift();
1148
1191
  }
1149
-
1192
+
1150
1193
  data.forEach(function(item){
1151
1194
  var row = {};
1152
-
1195
+
1153
1196
  item.forEach(function(value, i){
1154
1197
  if(columnMap[i]){
1155
1198
  row[columnMap[i].field] = value;
1156
1199
  }
1157
1200
  });
1158
-
1201
+
1159
1202
  rows.push(row);
1160
1203
  });
1161
-
1204
+
1162
1205
  return rows;
1163
1206
  }else {
1164
1207
  return false;
1165
1208
  }
1209
+ },
1210
+ range:function(clipboard){
1211
+ var data = [],
1212
+ rows = [],
1213
+ range = this.table.modules.selectRange.activeRange,
1214
+ singleCell = false,
1215
+ bounds, startCell, colWidth, columnMap, startCol;
1216
+
1217
+ if(range){
1218
+ bounds = range.getBounds();
1219
+ startCell = bounds.start;
1220
+
1221
+ if(bounds.start === bounds.end){
1222
+ singleCell = true;
1223
+ }
1224
+
1225
+ if(startCell){
1226
+ //get data from clipboard into array of columns and rows.
1227
+ clipboard = clipboard.split("\n");
1228
+
1229
+ clipboard.forEach(function(row){
1230
+ data.push(row.split("\t"));
1231
+ });
1232
+
1233
+ if(data.length){
1234
+ columnMap = this.table.columnManager.getVisibleColumnsByIndex();
1235
+ startCol = columnMap.indexOf(startCell.column);
1236
+
1237
+ if(startCol > -1){
1238
+ if(singleCell){
1239
+ colWidth = data[0].length;
1240
+ }else {
1241
+ colWidth = (columnMap.indexOf(bounds.end.column) - startCol) + 1;
1242
+ }
1243
+
1244
+ columnMap = columnMap.slice(startCol, startCol + colWidth);
1245
+
1246
+ data.forEach((item) => {
1247
+ var row = {};
1248
+ var itemLength = item.length;
1249
+
1250
+ columnMap.forEach(function(col, i){
1251
+ row[col.field] = item[i % itemLength];
1252
+ });
1253
+
1254
+ rows.push(row);
1255
+ });
1256
+
1257
+ return rows;
1258
+ }
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+ return false;
1166
1264
  }
1167
1265
  };
1168
1266
 
@@ -1305,6 +1403,7 @@ class Clipboard extends Module{
1305
1403
  var sel, textRange;
1306
1404
  this.blocked = false;
1307
1405
  this.customSelection = false;
1406
+
1308
1407
 
1309
1408
  if (this.mode === true || this.mode === "copy") {
1310
1409
 
@@ -1372,7 +1471,7 @@ class Clipboard extends Module{
1372
1471
  paste(e){
1373
1472
  var data, rowData, rows;
1374
1473
 
1375
- if(this.checkPaseOrigin(e)){
1474
+ if(this.checkPasteOrigin(e)){
1376
1475
 
1377
1476
  data = this.getPasteData(e);
1378
1477
 
@@ -1409,10 +1508,11 @@ class Clipboard extends Module{
1409
1508
  }
1410
1509
 
1411
1510
 
1412
- checkPaseOrigin(e){
1511
+ checkPasteOrigin(e){
1413
1512
  var valid = true;
1513
+ var blocked = this.confirm("clipboard-paste", [e]);
1414
1514
 
1415
- if(e.target.tagName != "DIV" || this.table.modules.edit.currentCell){
1515
+ if(blocked || !["DIV", "SPAN"].includes(e.target.tagName)){
1416
1516
  valid = false;
1417
1517
  }
1418
1518
 
@@ -2284,6 +2384,10 @@ class Column extends CoreFeature{
2284
2384
  titleElement.focus();
2285
2385
  });
2286
2386
 
2387
+ titleElement.addEventListener("mousedown", (e) => {
2388
+ e.stopPropagation();
2389
+ });
2390
+
2287
2391
  titleElement.addEventListener("change", () => {
2288
2392
  def.title = titleElement.value;
2289
2393
  this.dispatchExternal("columnTitleChanged", this.getComponent());
@@ -2829,6 +2933,8 @@ class Column extends CoreFeature{
2829
2933
 
2830
2934
  this.table.columnManager.rerenderColumns(true);
2831
2935
 
2936
+ this.dispatch("column-deleted", this);
2937
+
2832
2938
  resolve();
2833
2939
  });
2834
2940
  }
@@ -2969,6 +3075,10 @@ class Column extends CoreFeature{
2969
3075
 
2970
3076
  return this.component;
2971
3077
  }
3078
+
3079
+ getPosition(){
3080
+ return this.table.columnManager.getVisibleColumnsByIndex().indexOf(this) + 1;
3081
+ }
2972
3082
  }
2973
3083
 
2974
3084
  Column.defaultOptionList = defaultColumnOptions;
@@ -3888,8 +3998,14 @@ class ColumnCalcs extends Module{
3888
3998
  }
3889
3999
 
3890
4000
  initializeTopRow(){
4001
+ var fragment = document.createDocumentFragment();
4002
+
3891
4003
  if(!this.topInitialized){
3892
- this.table.columnManager.getContentsElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
4004
+
4005
+ fragment.appendChild(document.createElement("br"));
4006
+ fragment.appendChild(this.topElement);
4007
+
4008
+ this.table.columnManager.getContentsElement().insertBefore(fragment, this.table.columnManager.headersElement.nextSibling);
3893
4009
  this.topInitialized = true;
3894
4010
  }
3895
4011
  }
@@ -5937,12 +6053,14 @@ function time(cell, onRendered, success, cancel, editorParams){
5937
6053
  newDatetime = DT.fromFormat(String(cellValue), inputFormat);
5938
6054
  }
5939
6055
 
5940
- cellValue = newDatetime.toFormat("hh:mm");
6056
+ cellValue = newDatetime.toFormat("HH:mm");
5941
6057
 
5942
6058
  }else {
5943
6059
  console.error("Editor Error - 'date' editor 'format' param is dependant on luxon.js");
5944
6060
  }
5945
6061
  }
6062
+
6063
+ console.log("val", cellValue);
5946
6064
 
5947
6065
  input.value = cellValue;
5948
6066
 
@@ -6064,7 +6182,7 @@ function datetime(cell, onRendered, success, cancel, editorParams){
6064
6182
  newDatetime = DT.fromFormat(String(cellValue), inputFormat);
6065
6183
  }
6066
6184
 
6067
- cellValue = newDatetime.toFormat("yyyy-MM-dd") + "T" + newDatetime.toFormat("hh:mm");
6185
+ cellValue = newDatetime.toFormat("yyyy-MM-dd") + "T" + newDatetime.toFormat("HH:mm");
6068
6186
  }else {
6069
6187
  console.error("Editor Error - 'date' editor 'format' param is dependant on luxon.js");
6070
6188
  }
@@ -7631,6 +7749,8 @@ class Edit$1 extends Module{
7631
7749
  this.registerColumnOption("cellEdited");
7632
7750
  this.registerColumnOption("cellEditCancelled");
7633
7751
 
7752
+ this.registerTableOption("editTriggerEvent", "focus");
7753
+
7634
7754
  this.registerTableFunction("getEditedCells", this.getEditedCells.bind(this));
7635
7755
  this.registerTableFunction("clearCellEdited", this.clearCellEdited.bind(this));
7636
7756
  this.registerTableFunction("navigatePrev", this.navigatePrev.bind(this));
@@ -7662,16 +7782,30 @@ class Edit$1 extends Module{
7662
7782
  this.subscribe("row-deleting", this.rowDeleteCheck.bind(this));
7663
7783
  this.subscribe("row-layout", this.rowEditableCheck.bind(this));
7664
7784
  this.subscribe("data-refreshing", this.cancelEdit.bind(this));
7785
+ this.subscribe("clipboard-paste", this.pasteBlocker.bind(this));
7665
7786
 
7666
7787
  this.subscribe("keybinding-nav-prev", this.navigatePrev.bind(this, undefined));
7667
7788
  this.subscribe("keybinding-nav-next", this.keybindingNavigateNext.bind(this));
7668
- this.subscribe("keybinding-nav-left", this.navigateLeft.bind(this, undefined));
7669
- this.subscribe("keybinding-nav-right", this.navigateRight.bind(this, undefined));
7789
+
7790
+
7791
+ // this.subscribe("keybinding-nav-left", this.navigateLeft.bind(this, undefined));
7792
+ // this.subscribe("keybinding-nav-right", this.navigateRight.bind(this, undefined));
7670
7793
  this.subscribe("keybinding-nav-up", this.navigateUp.bind(this, undefined));
7671
7794
  this.subscribe("keybinding-nav-down", this.navigateDown.bind(this, undefined));
7672
7795
  }
7673
7796
 
7674
7797
 
7798
+ ///////////////////////////////////
7799
+ ///////// Paste Negation //////////
7800
+ ///////////////////////////////////
7801
+
7802
+ pasteBlocker(e){
7803
+ if(this.currentCell){
7804
+ return true;
7805
+ }
7806
+ }
7807
+
7808
+
7675
7809
  ///////////////////////////////////
7676
7810
  ////// Keybinding Functions ///////
7677
7811
  ///////////////////////////////////
@@ -7679,7 +7813,7 @@ class Edit$1 extends Module{
7679
7813
  keybindingNavigateNext(e){
7680
7814
  var cell = this.currentCell,
7681
7815
  newRow = this.options("tabEndNewRow");
7682
-
7816
+
7683
7817
  if(cell){
7684
7818
  if(!this.navigateNext(cell, e)){
7685
7819
  if(newRow){
@@ -8068,12 +8202,6 @@ class Edit$1 extends Module{
8068
8202
  this.updateCellClass(cell);
8069
8203
  element.setAttribute("tabindex", 0);
8070
8204
 
8071
- element.addEventListener("click", function(e){
8072
- if(!element.classList.contains("tabulator-editing")){
8073
- element.focus({preventScroll: true});
8074
- }
8075
- });
8076
-
8077
8205
  element.addEventListener("mousedown", function(e){
8078
8206
  if (e.button === 2) {
8079
8207
  e.preventDefault();
@@ -8081,12 +8209,33 @@ class Edit$1 extends Module{
8081
8209
  self.mouseClick = true;
8082
8210
  }
8083
8211
  });
8212
+
8213
+ if(this.options("editTriggerEvent") === "dblclick"){
8214
+ element.addEventListener("dblclick", function(e){
8215
+ if(!element.classList.contains("tabulator-editing")){
8216
+ element.focus({preventScroll: true});
8217
+ self.edit(cell, e, false);
8218
+ }
8219
+ });
8220
+ }
8084
8221
 
8085
- element.addEventListener("focus", function(e){
8086
- if(!self.recursionBlock){
8087
- self.edit(cell, e, false);
8088
- }
8089
- });
8222
+
8223
+ if(this.options("editTriggerEvent") === "focus" || this.options("editTriggerEvent") === "click"){
8224
+ element.addEventListener("click", function(e){
8225
+ if(!element.classList.contains("tabulator-editing")){
8226
+ element.focus({preventScroll: true});
8227
+ self.edit(cell, e, false);
8228
+ }
8229
+ });
8230
+ }
8231
+
8232
+ if(this.options("editTriggerEvent") === "focus"){
8233
+ element.addEventListener("focus", function(e){
8234
+ if(!self.recursionBlock){
8235
+ self.edit(cell, e, false);
8236
+ }
8237
+ });
8238
+ }
8090
8239
  }
8091
8240
  }
8092
8241
 
@@ -8172,8 +8321,9 @@ class Edit$1 extends Module{
8172
8321
  allowEdit = true,
8173
8322
  rendered = function(){},
8174
8323
  element = cell.getElement(),
8324
+ editFinished = false,
8175
8325
  cellEditor, component, params;
8176
-
8326
+
8177
8327
  //prevent editing if another cell is refusing to leave focus (eg. validation fail)
8178
8328
 
8179
8329
  if(this.currentCell){
@@ -8185,13 +8335,15 @@ class Edit$1 extends Module{
8185
8335
 
8186
8336
  //handle successful value change
8187
8337
  function success(value){
8188
- if(self.currentCell === cell){
8338
+ if(self.currentCell === cell && !editFinished){
8189
8339
  var valid = self.chain("edit-success", [cell, value], true, true);
8190
-
8340
+
8191
8341
  if(valid === true || self.table.options.validationMode === "highlight"){
8342
+
8343
+ editFinished = true;
8344
+
8192
8345
  self.clearEditor();
8193
8346
 
8194
-
8195
8347
  if(!cell.modules.edit){
8196
8348
  cell.modules.edit = {};
8197
8349
  }
@@ -8203,12 +8355,17 @@ class Edit$1 extends Module{
8203
8355
  }
8204
8356
 
8205
8357
  cell.setValue(value, true);
8206
-
8358
+
8207
8359
  return valid === true;
8208
8360
  }else {
8361
+ editFinished = true;
8209
8362
  self.invalidEdit = true;
8210
8363
  self.focusCellNoEvent(cell, true);
8211
8364
  rendered();
8365
+
8366
+ setTimeout(() => {
8367
+ editFinished = false;
8368
+ }, 10);
8212
8369
  return false;
8213
8370
  }
8214
8371
  }
@@ -8216,7 +8373,9 @@ class Edit$1 extends Module{
8216
8373
 
8217
8374
  //handle aborted edit
8218
8375
  function cancel(){
8219
- if(self.currentCell === cell){
8376
+ // editFinished = true;
8377
+
8378
+ if(self.currentCell === cell && !editFinished){
8220
8379
  self.cancelEdit();
8221
8380
  }
8222
8381
  }
@@ -8233,7 +8392,6 @@ class Edit$1 extends Module{
8233
8392
  allowEdit = this.allowEdit(cell);
8234
8393
 
8235
8394
  if(allowEdit || forceEdit){
8236
-
8237
8395
  self.cancelEdit();
8238
8396
 
8239
8397
  self.currentCell = cell;
@@ -8283,27 +8441,33 @@ class Edit$1 extends Module{
8283
8441
  }
8284
8442
  }else {
8285
8443
  console.warn("Edit Error - Editor should return an instance of Node, the editor returned:", cellEditor);
8286
- element.blur();
8444
+ this.blur(element);
8287
8445
  return false;
8288
8446
  }
8289
8447
  }else {
8290
- element.blur();
8448
+ this.blur(element);
8291
8449
  return false;
8292
8450
  }
8293
8451
 
8294
8452
  return true;
8295
8453
  }else {
8296
8454
  this.mouseClick = false;
8297
- element.blur();
8455
+ this.blur(element);
8298
8456
  return false;
8299
8457
  }
8300
8458
  }else {
8301
8459
  this.mouseClick = false;
8302
- element.blur();
8460
+ this.blur(element);
8303
8461
  return false;
8304
8462
  }
8305
8463
  }
8306
8464
 
8465
+ blur(element){
8466
+ if(!this.confirm("edit-blur", [element]) ){
8467
+ element.blur();
8468
+ }
8469
+ }
8470
+
8307
8471
  getEditedCells(){
8308
8472
  var output = [];
8309
8473
 
@@ -8387,10 +8551,20 @@ class Export extends Module{
8387
8551
  this.cloneTableStyle = style;
8388
8552
  this.config = config || {};
8389
8553
  this.colVisProp = colVisProp;
8554
+
8555
+ var headers, body;
8390
8556
 
8391
- var headers = this.config.columnHeaders !== false ? this.headersToExportRows(this.generateColumnGroupHeaders()) : [];
8392
- var body = this.bodyToExportRows(this.rowLookup(range));
8393
-
8557
+ if (range === 'range') {
8558
+ var columns = this.table.modules.selectRange.selectedColumns();
8559
+ headers = this.config.columnHeaders !== false
8560
+ ? this.headersToExportRows(this.generateColumnGroupHeaders(columns))
8561
+ : [];
8562
+ body = this.bodyToExportRows(this.rowLookup(range), this.table.modules.selectRange.selectedColumns(true));
8563
+ } else {
8564
+ headers = this.config.columnHeaders !== false ? this.headersToExportRows(this.generateColumnGroupHeaders()) : [];
8565
+ body = this.bodyToExportRows(this.rowLookup(range));
8566
+ }
8567
+
8394
8568
  return headers.concat(body);
8395
8569
  }
8396
8570
 
@@ -8425,7 +8599,11 @@ class Export extends Module{
8425
8599
  case "selected":
8426
8600
  rows = this.table.modules.selectRow.selectedRows;
8427
8601
  break;
8428
-
8602
+
8603
+ case "range":
8604
+ rows = this.table.modules.selectRange.selectedRows();
8605
+ break;
8606
+
8429
8607
  case "active":
8430
8608
  default:
8431
8609
  if(this.table.options.pagination){
@@ -8439,10 +8617,12 @@ class Export extends Module{
8439
8617
  return Object.assign([], rows);
8440
8618
  }
8441
8619
 
8442
- generateColumnGroupHeaders(){
8620
+ generateColumnGroupHeaders(columns){
8443
8621
  var output = [];
8444
8622
 
8445
- var columns = this.config.columnGroups !== false ? this.table.columnManager.columns : this.table.columnManager.columnsByIndex;
8623
+ if (!columns) {
8624
+ columns = this.config.columnGroups !== false ? this.table.columnManager.columns : this.table.columnManager.columnsByIndex;
8625
+ }
8446
8626
 
8447
8627
  columns.forEach((column) => {
8448
8628
  var colData = this.processColumnGroup(column);
@@ -8451,7 +8631,7 @@ class Export extends Module{
8451
8631
  output.push(colData);
8452
8632
  }
8453
8633
  });
8454
-
8634
+
8455
8635
  return output;
8456
8636
  }
8457
8637
 
@@ -8579,16 +8759,16 @@ class Export extends Module{
8579
8759
  return exportRows;
8580
8760
  }
8581
8761
 
8582
- bodyToExportRows(rows){
8583
-
8584
- var columns = [];
8762
+ bodyToExportRows(rows, columns = []){
8585
8763
  var exportRows = [];
8586
8764
 
8587
- this.table.columnManager.columnsByIndex.forEach((column) => {
8588
- if (this.columnVisCheck(column)) {
8589
- columns.push(column.getComponent());
8590
- }
8591
- });
8765
+ if (columns.length === 0) {
8766
+ this.table.columnManager.columnsByIndex.forEach((column) => {
8767
+ if (this.columnVisCheck(column)) {
8768
+ columns.push(column.getComponent());
8769
+ }
8770
+ });
8771
+ }
8592
8772
 
8593
8773
  if(this.config.columnCalcs !== false && this.table.modExists("columnCalcs")){
8594
8774
  if(this.table.modules.columnCalcs.topInitialized){
@@ -8599,7 +8779,7 @@ class Export extends Module{
8599
8779
  rows.push(this.table.modules.columnCalcs.botRow);
8600
8780
  }
8601
8781
  }
8602
-
8782
+
8603
8783
  rows = rows.filter((row) => {
8604
8784
  switch(row.type){
8605
8785
  case "group":
@@ -8826,7 +9006,8 @@ class Export extends Module{
8826
9006
  if(col){
8827
9007
  var cellEl = document.createElement("td"),
8828
9008
  column = col.component._column,
8829
- index = this.table.columnManager.findColumnIndex(column),
9009
+ table = this.table,
9010
+ index = table.columnManager.findColumnIndex(column),
8830
9011
  value = col.value,
8831
9012
  cellStyle;
8832
9013
 
@@ -8853,6 +9034,9 @@ class Export extends Module{
8853
9034
  getRow:function(){
8854
9035
  return row.component;
8855
9036
  },
9037
+ getTable:function(){
9038
+ return table;
9039
+ },
8856
9040
  getComponent:function(){
8857
9041
  return cellWrapper;
8858
9042
  },
@@ -10511,8 +10695,12 @@ function buttonCross(cell, formatterParams, onRendered){
10511
10695
  function rownum(cell, formatterParams, onRendered){
10512
10696
  var content = document.createElement("span");
10513
10697
  var row = cell.getRow();
10698
+ var table = cell.getTable();
10514
10699
 
10515
10700
  row.watchPosition((position) => {
10701
+ if (formatterParams.relativeToPage) {
10702
+ position += table.modules.page.getPageSize() * (table.modules.page.getPage() - 1);
10703
+ }
10516
10704
  content.innerText = position;
10517
10705
  });
10518
10706
 
@@ -10589,7 +10777,7 @@ function rowSelection(cell, formatterParams, onRendered){
10589
10777
  if(row instanceof RowComponent){
10590
10778
 
10591
10779
  checkbox.addEventListener("change", (e) => {
10592
- if(this.table.options.selectableRangeMode === "click"){
10780
+ if(this.table.options.selectableRowsRangeMode === "click"){
10593
10781
  if(!blocked){
10594
10782
  row.toggleSelect();
10595
10783
  }else {
@@ -10600,7 +10788,7 @@ function rowSelection(cell, formatterParams, onRendered){
10600
10788
  }
10601
10789
  });
10602
10790
 
10603
- if(this.table.options.selectableRangeMode === "click"){
10791
+ if(this.table.options.selectableRowsRangeMode === "click"){
10604
10792
  checkbox.addEventListener("click", (e) => {
10605
10793
  blocked = true;
10606
10794
  this.table.modules.selectRow.handleComplexRowClick(row._row, e);
@@ -10893,7 +11081,10 @@ class FrozenColumns extends Module{
10893
11081
  this.subscribe("columns-loading", this.reset.bind(this));
10894
11082
 
10895
11083
  this.subscribe("column-add", this.reinitializeColumns.bind(this));
10896
- this.subscribe("column-delete", this.reinitializeColumns.bind(this));
11084
+ this.subscribe("column-deleted", this.reinitializeColumns.bind(this));
11085
+ this.subscribe("column-hide", this.reinitializeColumns.bind(this));
11086
+ this.subscribe("column-show", this.reinitializeColumns.bind(this));
11087
+ this.subscribe("columns-loaded", this.reinitializeColumns.bind(this));
10897
11088
 
10898
11089
  this.subscribe("table-redraw", this.layout.bind(this));
10899
11090
  this.subscribe("layout-refreshing", this.blockLayout.bind(this));
@@ -10919,16 +11110,16 @@ class FrozenColumns extends Module{
10919
11110
  this.table.columnManager.columnsByIndex.forEach((column) => {
10920
11111
  this.initializeColumn(column);
10921
11112
  });
11113
+
11114
+ this.layout();
10922
11115
  }
10923
11116
 
10924
11117
  //initialize specific column
10925
11118
  initializeColumn(column){
10926
11119
  var config = {margin:0, edge:false};
10927
11120
 
10928
- if(!column.isGroup){
10929
-
11121
+ if(!column.isGroup){
10930
11122
  if(this.frozenCheck(column)){
10931
-
10932
11123
  config.position = this.initializationMode;
10933
11124
 
10934
11125
  if(this.initializationMode == "left"){
@@ -11019,9 +11210,8 @@ class FrozenColumns extends Module{
11019
11210
  leftParents.push(parentEl);
11020
11211
  }
11021
11212
 
11022
- if(column.modules.frozen.edge){
11023
- parentEl.classList.add("tabulator-frozen-" + column.modules.frozen.position);
11024
- }
11213
+ parentEl.classList.toggle("tabulator-frozen-left", column.modules.frozen.edge && column.modules.frozen.position === "left");
11214
+ parentEl.classList.toggle("tabulator-frozen-right", column.modules.frozen.edge && column.modules.frozen.position === "right");
11025
11215
  }else {
11026
11216
  this.layoutElement(column.getElement(), column);
11027
11217
  }
@@ -11069,7 +11259,6 @@ class FrozenColumns extends Module{
11069
11259
  //layout columns appropriately
11070
11260
  layout(){
11071
11261
  if(this.active && !this.blocked){
11072
-
11073
11262
  //calculate left columns
11074
11263
  this.layoutColumnPosition();
11075
11264
 
@@ -11132,9 +11321,8 @@ class FrozenColumns extends Module{
11132
11321
 
11133
11322
  element.classList.add("tabulator-frozen");
11134
11323
 
11135
- if(column.modules.frozen.edge){
11136
- element.classList.add("tabulator-frozen-" + column.modules.frozen.position);
11137
- }
11324
+ element.classList.toggle("tabulator-frozen-left", column.modules.frozen.edge && column.modules.frozen.position === "left");
11325
+ element.classList.toggle("tabulator-frozen-right", column.modules.frozen.edge && column.modules.frozen.position === "right");
11138
11326
  }
11139
11327
  }
11140
11328
 
@@ -11178,12 +11366,17 @@ class FrozenRows extends Module{
11178
11366
  }
11179
11367
 
11180
11368
  initialize(){
11369
+ var fragment = document.createDocumentFragment();
11370
+
11181
11371
  this.rows = [];
11182
11372
 
11183
11373
  this.topElement.classList.add("tabulator-frozen-rows-holder");
11374
+
11375
+ fragment.appendChild(document.createElement("br"));
11376
+ fragment.appendChild(this.topElement);
11184
11377
 
11185
11378
  // this.table.columnManager.element.append(this.topElement);
11186
- this.table.columnManager.getContentsElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
11379
+ this.table.columnManager.getContentsElement().insertBefore(fragment, this.table.columnManager.headersElement.nextSibling);
11187
11380
 
11188
11381
  this.subscribe("row-deleting", this.detachRow.bind(this));
11189
11382
  this.subscribe("rows-visible", this.visibleRows.bind(this));
@@ -12649,6 +12842,8 @@ var defaultUndoers = {
12649
12842
 
12650
12843
  rowAdd: function(action){
12651
12844
  action.component.deleteActual();
12845
+
12846
+ this.table.rowManager.checkPlaceholder();
12652
12847
  },
12653
12848
 
12654
12849
  rowDelete: function(action){
@@ -12659,6 +12854,8 @@ var defaultUndoers = {
12659
12854
  }
12660
12855
 
12661
12856
  this._rebindRow(action.component, newRow);
12857
+
12858
+ this.table.rowManager.checkPlaceholder();
12662
12859
  },
12663
12860
 
12664
12861
  rowMove: function(action){
@@ -12685,10 +12882,14 @@ var defaultRedoers = {
12685
12882
  }
12686
12883
 
12687
12884
  this._rebindRow(action.component, newRow);
12885
+
12886
+ this.table.rowManager.checkPlaceholder();
12688
12887
  },
12689
12888
 
12690
12889
  rowDelete:function(action){
12691
12890
  action.component.deleteActual();
12891
+
12892
+ this.table.rowManager.checkPlaceholder();
12692
12893
  },
12693
12894
 
12694
12895
  rowMove: function(action){
@@ -12813,7 +13014,7 @@ class History extends Module{
12813
13014
 
12814
13015
  return true;
12815
13016
  }else {
12816
- console.warn("History Undo Error - No more history to undo");
13017
+ console.warn(this.options("history") ? "History Undo Error - No more history to undo" : "History module not enabled");
12817
13018
  return false;
12818
13019
  }
12819
13020
  }
@@ -12831,7 +13032,7 @@ class History extends Module{
12831
13032
 
12832
13033
  return true;
12833
13034
  }else {
12834
- console.warn("History Redo Error - No more history to redo");
13035
+ console.warn(this.options("history") ? "History Redo Error - No more history to redo" : "History module not enabled");
12835
13036
  return false;
12836
13037
  }
12837
13038
  }
@@ -13648,6 +13849,8 @@ var defaultBindings = {
13648
13849
  navNext:9,
13649
13850
  navUp:38,
13650
13851
  navDown:40,
13852
+ navLeft:37,
13853
+ navRight:39,
13651
13854
  scrollPageUp:33,
13652
13855
  scrollPageDown:34,
13653
13856
  scrollToStart:36,
@@ -13655,6 +13858,19 @@ var defaultBindings = {
13655
13858
  undo:["ctrl + 90", "meta + 90"],
13656
13859
  redo:["ctrl + 89", "meta + 89"],
13657
13860
  copyToClipboard:["ctrl + 67", "meta + 67"],
13861
+
13862
+ rangeJumpUp:["ctrl + 38", "meta + 38"],
13863
+ rangeJumpDown:["ctrl + 40", "meta + 40"],
13864
+ rangeJumpLeft:["ctrl + 37", "meta + 37"],
13865
+ rangeJumpRight:["ctrl + 39", "meta + 39"],
13866
+ rangeExpandUp:"shift + 38",
13867
+ rangeExpandDown:"shift + 40",
13868
+ rangeExpandLeft:"shift + 37",
13869
+ rangeExpandRight:"shift + 39",
13870
+ rangeExpandJumpUp:["ctrl + shift + 38", "meta + shift + 38"],
13871
+ rangeExpandJumpDown:["ctrl + shift + 40", "meta + shift + 40"],
13872
+ rangeExpandJumpLeft:["ctrl + shift + 37", "meta + shift + 37"],
13873
+ rangeExpandJumpRight:["ctrl + shift + 39", "meta + shift + 39"],
13658
13874
  };
13659
13875
 
13660
13876
  var defaultActions = {
@@ -13742,6 +13958,43 @@ var defaultActions = {
13742
13958
  this.dispatch("keybinding-nav-down", e);
13743
13959
  },
13744
13960
 
13961
+ rangeJumpLeft: function(e){
13962
+ this.dispatch("keybinding-nav-range", e, "left", true, false);
13963
+ },
13964
+ rangeJumpRight: function(e){
13965
+ this.dispatch("keybinding-nav-range", e, "right", true, false);
13966
+ },
13967
+ rangeJumpUp: function(e){
13968
+ this.dispatch("keybinding-nav-range", e, "up", true, false);
13969
+ },
13970
+ rangeJumpDown: function(e){
13971
+ this.dispatch("keybinding-nav-range", e, "down", true, false);
13972
+ },
13973
+ rangeExpandLeft: function(e){
13974
+ this.dispatch("keybinding-nav-range", e, "left", false, true);
13975
+ },
13976
+ rangeExpandRight: function(e){
13977
+ this.dispatch("keybinding-nav-range", e, "right", false, true);
13978
+ },
13979
+ rangeExpandUp: function(e){
13980
+ this.dispatch("keybinding-nav-range", e, "up", false, true);
13981
+ },
13982
+ rangeExpandDown: function(e){
13983
+ this.dispatch("keybinding-nav-range", e, "down", false, true);
13984
+ },
13985
+ rangeExpandJumpLeft: function(e){
13986
+ this.dispatch("keybinding-nav-range", e, "left", true, true);
13987
+ },
13988
+ rangeExpandJumpRight: function(e){
13989
+ this.dispatch("keybinding-nav-range", e, "right", true, true);
13990
+ },
13991
+ rangeExpandJumpUp: function(e){
13992
+ this.dispatch("keybinding-nav-range", e, "up", true, true);
13993
+ },
13994
+ rangeExpandJumpDown: function(e){
13995
+ this.dispatch("keybinding-nav-range", e, "down", true, true);
13996
+ },
13997
+
13745
13998
  undo:function(e){
13746
13999
  var cell = false;
13747
14000
  if(this.table.options.history && this.table.modExists("history") && this.table.modExists("edit")){
@@ -14020,7 +14273,7 @@ class Menu extends Module{
14020
14273
  this.subscribe("group-dblclick", this.loadMenuEvent.bind(this, this.table.options.groupDblClickMenu));
14021
14274
  }
14022
14275
  }
14023
-
14276
+
14024
14277
  initializeColumn(column){
14025
14278
  var def = column.definition;
14026
14279
 
@@ -14229,6 +14482,7 @@ class Menu extends Module{
14229
14482
  this.rootPopup = null;
14230
14483
 
14231
14484
  if(this.currentComponent){
14485
+ this.dispatch("menu-closed", menu, popup);
14232
14486
  this.dispatchExternal("menuClosed", this.currentComponent.getComponent());
14233
14487
  this.currentComponent = null;
14234
14488
  }
@@ -14236,6 +14490,7 @@ class Menu extends Module{
14236
14490
 
14237
14491
  this.currentComponent = component;
14238
14492
 
14493
+ this.dispatch("menu-opened", menu, popup);
14239
14494
  this.dispatchExternal("menuOpened", component.getComponent());
14240
14495
  }
14241
14496
  }
@@ -14279,8 +14534,13 @@ class MoveColumns extends Module{
14279
14534
  initialize(){
14280
14535
  if(this.table.options.movableColumns){
14281
14536
  this.subscribe("column-init", this.initializeColumn.bind(this));
14537
+ this.subscribe("alert-show", this.abortMove.bind(this));
14282
14538
  }
14283
14539
  }
14540
+
14541
+ abortMove(){
14542
+ clearTimeout(this.checkTimeout);
14543
+ }
14284
14544
 
14285
14545
  initializeColumn(column){
14286
14546
  var self = this,
@@ -16866,7 +17126,7 @@ class Popup$1 extends Module{
16866
17126
  this.subscribe("group-dblclick", this.loadPopupEvent.bind(this, this.table.options.groupDblClickPopup));
16867
17127
  }
16868
17128
  }
16869
-
17129
+
16870
17130
  initializeColumn(column){
16871
17131
  var def = column.definition;
16872
17132
 
@@ -18023,7 +18283,7 @@ class ResizeTable extends Module{
18023
18283
  this.autoResize = true;
18024
18284
 
18025
18285
  this.resizeObserver = new ResizeObserver((entry) => {
18026
- if(!table.browserMobile || (table.browserMobile &&!table.modules.edit.currentCell)){
18286
+ if(!table.browserMobile || (table.browserMobile && (!table.modules.edit || (table.modules.edit && !table.modules.edit.currentCell)))){
18027
18287
 
18028
18288
  var nodeHeight = Math.floor(entry[0].contentRect.height);
18029
18289
  var nodeWidth = Math.floor(entry[0].contentRect.width);
@@ -18049,7 +18309,7 @@ class ResizeTable extends Module{
18049
18309
  if(this.table.element.parentNode && !this.table.rowManager.fixedHeight && (tableStyle.getPropertyValue("max-height") || tableStyle.getPropertyValue("min-height"))){
18050
18310
 
18051
18311
  this.containerObserver = new ResizeObserver((entry) => {
18052
- if(!table.browserMobile || (table.browserMobile &&!table.modules.edit.currentCell)){
18312
+ if(!table.browserMobile || (table.browserMobile && (!table.modules.edit || (table.modules.edit && !table.modules.edit.currentCell)))){
18053
18313
 
18054
18314
  var nodeHeight = Math.floor(entry[0].contentRect.height);
18055
18315
  var nodeWidth = Math.floor(entry[0].contentRect.width);
@@ -18072,7 +18332,7 @@ class ResizeTable extends Module{
18072
18332
 
18073
18333
  }else {
18074
18334
  this.binding = function(){
18075
- if(!table.browserMobile || (table.browserMobile && !table.modules.edit.currentCell)){
18335
+ if(!table.browserMobile || (table.browserMobile && (!table.modules.edit || (table.modules.edit && !table.modules.edit.currentCell)))){
18076
18336
  table.columnManager.rerenderColumns(true);
18077
18337
  table.redraw();
18078
18338
  }
@@ -18491,11 +18751,11 @@ class SelectRow extends Module{
18491
18751
  this.selectedRows = []; //hold selected rows
18492
18752
  this.headerCheckboxElement = null; // hold header select element
18493
18753
 
18494
- this.registerTableOption("selectable", "highlight"); //highlight rows on hover
18495
- this.registerTableOption("selectableRangeMode", "drag"); //highlight rows on hover
18496
- this.registerTableOption("selectableRollingSelection", true); //roll selection once maximum number of selectable rows is reached
18497
- this.registerTableOption("selectablePersistence", true); // maintain selection when table view is updated
18498
- this.registerTableOption("selectableCheck", function(data, row){return true;}); //check whether row is selectable
18754
+ this.registerTableOption("selectableRows", "highlight"); //highlight rows on hover
18755
+ this.registerTableOption("selectableRowsRangeMode", "drag"); //highlight rows on hover
18756
+ this.registerTableOption("selectableRowsRollingSelection", true); //roll selection once maximum number of selectable rows is reached
18757
+ this.registerTableOption("selectableRowsPersistence", true); // maintain selection when table view is updated
18758
+ this.registerTableOption("selectableRowsCheck", function(data, row){return true;}); //check whether row is selectable
18499
18759
 
18500
18760
  this.registerTableFunction("selectRow", this.selectRows.bind(this));
18501
18761
  this.registerTableFunction("deselectRow", this.deselectRows.bind(this));
@@ -18511,17 +18771,32 @@ class SelectRow extends Module{
18511
18771
  }
18512
18772
 
18513
18773
  initialize(){
18514
- if(this.table.options.selectable !== false){
18774
+
18775
+ this.deprecatedOptionsCheck();
18776
+
18777
+ if(this.table.options.selectableRows === "highlight" && this.table.options.selectableRange){
18778
+ this.table.options.selectableRows = false;
18779
+ }
18780
+
18781
+ if(this.table.options.selectableRows !== false){
18515
18782
  this.subscribe("row-init", this.initializeRow.bind(this));
18516
18783
  this.subscribe("row-deleting", this.rowDeleted.bind(this));
18517
18784
  this.subscribe("rows-wipe", this.clearSelectionData.bind(this));
18518
18785
  this.subscribe("rows-retrieve", this.rowRetrieve.bind(this));
18519
18786
 
18520
- if(this.table.options.selectable && !this.table.options.selectablePersistence){
18787
+ if(this.table.options.selectableRows && !this.table.options.selectableRowsPersistence){
18521
18788
  this.subscribe("data-refreshing", this.deselectRows.bind(this));
18522
18789
  }
18523
18790
  }
18524
18791
  }
18792
+
18793
+ deprecatedOptionsCheck(){
18794
+ this.deprecationCheck("selectable", "selectableRows", true);
18795
+ this.deprecationCheck("selectableRollingSelection", "selectableRowsRollingSelection", true);
18796
+ this.deprecationCheck("selectableRangeMode", "selectableRowsRangeMode", true);
18797
+ this.deprecationCheck("selectablePersistence", "selectableRowsPersistence", true);
18798
+ this.deprecationCheck("selectableCheck", "selectableRowsCheck", true);
18799
+ }
18525
18800
 
18526
18801
  rowRetrieve(type, prevValue){
18527
18802
  return type === "selected" ? this.selectedRows : prevValue;
@@ -18546,6 +18821,7 @@ class SelectRow extends Module{
18546
18821
 
18547
18822
  initializeRow(row){
18548
18823
  var self = this,
18824
+ selectable = self.checkRowSelectability(row),
18549
18825
  element = row.getElement();
18550
18826
 
18551
18827
  // trigger end of row selection
@@ -18559,14 +18835,14 @@ class SelectRow extends Module{
18559
18835
  };
18560
18836
 
18561
18837
  row.modules.select = {selected:false};
18838
+
18839
+ element.classList.toggle("tabulator-selectable", selectable);
18840
+ element.classList.toggle("tabulator-unselectable", !selectable);
18562
18841
 
18563
18842
  //set row selection class
18564
- if(self.checkRowSelectability(row)){
18565
- element.classList.add("tabulator-selectable");
18566
- element.classList.remove("tabulator-unselectable");
18567
-
18568
- if(self.table.options.selectable && self.table.options.selectable != "highlight"){
18569
- if(self.table.options.selectableRangeMode === "click"){
18843
+ if(self.checkRowSelectability(row)){
18844
+ if(self.table.options.selectableRows && self.table.options.selectableRows != "highlight"){
18845
+ if(self.table.options.selectableRowsRangeMode === "click"){
18570
18846
  element.addEventListener("click", this.handleComplexRowClick.bind(this, row));
18571
18847
  }else {
18572
18848
  element.addEventListener("click", function(e){
@@ -18615,10 +18891,6 @@ class SelectRow extends Module{
18615
18891
  });
18616
18892
  }
18617
18893
  }
18618
-
18619
- }else {
18620
- element.classList.add("tabulator-unselectable");
18621
- element.classList.remove("tabulator-selectable");
18622
18894
  }
18623
18895
  }
18624
18896
 
@@ -18640,8 +18912,8 @@ class SelectRow extends Module{
18640
18912
  toggledRows.forEach((toggledRow)=>{
18641
18913
  if(toggledRow !== this.lastClickedRow){
18642
18914
 
18643
- if(this.table.options.selectable !== true && !this.isRowSelected(row)){
18644
- if(this.selectedRows.length < this.table.options.selectable){
18915
+ if(this.table.options.selectableRows !== true && !this.isRowSelected(row)){
18916
+ if(this.selectedRows.length < this.table.options.selectableRows){
18645
18917
  this.toggleRow(toggledRow);
18646
18918
  }
18647
18919
  }else {
@@ -18653,9 +18925,9 @@ class SelectRow extends Module{
18653
18925
  }else {
18654
18926
  this.deselectRows(undefined, true);
18655
18927
 
18656
- if(this.table.options.selectable !== true){
18657
- if(toggledRows.length > this.table.options.selectable){
18658
- toggledRows = toggledRows.slice(0, this.table.options.selectable);
18928
+ if(this.table.options.selectableRows !== true){
18929
+ if(toggledRows.length > this.table.options.selectableRows){
18930
+ toggledRows = toggledRows.slice(0, this.table.options.selectableRows);
18659
18931
  }
18660
18932
  }
18661
18933
 
@@ -18675,7 +18947,7 @@ class SelectRow extends Module{
18675
18947
 
18676
18948
  checkRowSelectability(row){
18677
18949
  if(row && row.type === "row"){
18678
- return this.table.options.selectableCheck.call(this.table, row.getComponent());
18950
+ return this.table.options.selectableRowsCheck.call(this.table, row.getComponent());
18679
18951
  }
18680
18952
 
18681
18953
  return false;
@@ -18702,6 +18974,10 @@ class SelectRow extends Module{
18702
18974
  rowMatch = this.table.rowManager.rows;
18703
18975
  break;
18704
18976
 
18977
+ case "number":
18978
+ rowMatch = this.table.rowManager.findRow(rows);
18979
+ break;
18980
+
18705
18981
  case "string":
18706
18982
  rowMatch = this.table.rowManager.findRow(rows);
18707
18983
 
@@ -18737,9 +19013,9 @@ class SelectRow extends Module{
18737
19013
  //select an individual row
18738
19014
  _selectRow(rowInfo, silent, force){
18739
19015
  //handle max row count
18740
- if(!isNaN(this.table.options.selectable) && this.table.options.selectable !== true && !force){
18741
- if(this.selectedRows.length >= this.table.options.selectable){
18742
- if(this.table.options.selectableRollingSelection){
19016
+ if(!isNaN(this.table.options.selectableRows) && this.table.options.selectableRows !== true && !force){
19017
+ if(this.selectedRows.length >= this.table.options.selectableRows){
19018
+ if(this.table.options.selectableRowsRollingSelection){
18743
19019
  this._deselectRow(this.selectedRows[0]);
18744
19020
  }else {
18745
19021
  return false;
@@ -18793,6 +19069,10 @@ class SelectRow extends Module{
18793
19069
  case "undefined":
18794
19070
  rowMatch = Object.assign([], this.selectedRows);
18795
19071
  break;
19072
+
19073
+ case "number":
19074
+ rowMatch = this.table.rowManager.findRow(rows);
19075
+ break;
18796
19076
 
18797
19077
  case "string":
18798
19078
  rowMatch = this.table.rowManager.findRow(rows);
@@ -19220,90 +19500,90 @@ var defaultSorters = {
19220
19500
  };
19221
19501
 
19222
19502
  class Sort extends Module{
19223
-
19503
+
19224
19504
  constructor(table){
19225
19505
  super(table);
19226
-
19506
+
19227
19507
  this.sortList = []; //holder current sort
19228
19508
  this.changed = false; //has the sort changed since last render
19229
-
19509
+
19230
19510
  this.registerTableOption("sortMode", "local"); //local or remote sorting
19231
-
19511
+
19232
19512
  this.registerTableOption("initialSort", false); //initial sorting criteria
19233
19513
  this.registerTableOption("columnHeaderSortMulti", true); //multiple or single column sorting
19234
19514
  this.registerTableOption("sortOrderReverse", false); //reverse internal sort ordering
19235
19515
  this.registerTableOption("headerSortElement", "<div class='tabulator-arrow'></div>"); //header sort element
19236
19516
  this.registerTableOption("headerSortClickElement", "header"); //element which triggers sort when clicked
19237
-
19517
+
19238
19518
  this.registerColumnOption("sorter");
19239
19519
  this.registerColumnOption("sorterParams");
19240
-
19520
+
19241
19521
  this.registerColumnOption("headerSort", true);
19242
19522
  this.registerColumnOption("headerSortStartingDir");
19243
19523
  this.registerColumnOption("headerSortTristate");
19244
-
19524
+
19245
19525
  }
19246
-
19526
+
19247
19527
  initialize(){
19248
19528
  this.subscribe("column-layout", this.initializeColumn.bind(this));
19249
19529
  this.subscribe("table-built", this.tableBuilt.bind(this));
19250
19530
  this.registerDataHandler(this.sort.bind(this), 20);
19251
-
19531
+
19252
19532
  this.registerTableFunction("setSort", this.userSetSort.bind(this));
19253
19533
  this.registerTableFunction("getSorters", this.getSort.bind(this));
19254
19534
  this.registerTableFunction("clearSort", this.clearSort.bind(this));
19255
-
19535
+
19256
19536
  if(this.table.options.sortMode === "remote"){
19257
19537
  this.subscribe("data-params", this.remoteSortParams.bind(this));
19258
19538
  }
19259
19539
  }
19260
-
19540
+
19261
19541
  tableBuilt(){
19262
19542
  if(this.table.options.initialSort){
19263
19543
  this.setSort(this.table.options.initialSort);
19264
19544
  }
19265
19545
  }
19266
-
19546
+
19267
19547
  remoteSortParams(data, config, silent, params){
19268
19548
  var sorters = this.getSort();
19269
-
19549
+
19270
19550
  sorters.forEach((item) => {
19271
19551
  delete item.column;
19272
19552
  });
19273
-
19553
+
19274
19554
  params.sort = sorters;
19275
-
19555
+
19276
19556
  return params;
19277
19557
  }
19278
-
19279
-
19558
+
19559
+
19280
19560
  ///////////////////////////////////
19281
19561
  ///////// Table Functions /////////
19282
19562
  ///////////////////////////////////
19283
-
19563
+
19284
19564
  userSetSort(sortList, dir){
19285
19565
  this.setSort(sortList, dir);
19286
19566
  // this.table.rowManager.sorterRefresh();
19287
19567
  this.refreshSort();
19288
19568
  }
19289
-
19569
+
19290
19570
  clearSort(){
19291
19571
  this.clear();
19292
19572
  // this.table.rowManager.sorterRefresh();
19293
19573
  this.refreshSort();
19294
19574
  }
19295
-
19296
-
19575
+
19576
+
19297
19577
  ///////////////////////////////////
19298
19578
  ///////// Internal Logic //////////
19299
19579
  ///////////////////////////////////
19300
-
19580
+
19301
19581
  //initialize column header for sorting
19302
19582
  initializeColumn(column){
19303
19583
  var sorter = false,
19304
19584
  colEl,
19305
19585
  arrowEl;
19306
-
19586
+
19307
19587
  switch(typeof column.definition.sorter){
19308
19588
  case "string":
19309
19589
  if(Sort.sorters[column.definition.sorter]){
@@ -19312,28 +19592,28 @@ class Sort extends Module{
19312
19592
  console.warn("Sort Error - No such sorter found: ", column.definition.sorter);
19313
19593
  }
19314
19594
  break;
19315
-
19595
+
19316
19596
  case "function":
19317
19597
  sorter = column.definition.sorter;
19318
19598
  break;
19319
19599
  }
19320
-
19600
+
19321
19601
  column.modules.sort = {
19322
19602
  sorter:sorter, dir:"none",
19323
19603
  params:column.definition.sorterParams || {},
19324
19604
  startingDir:column.definition.headerSortStartingDir || "asc",
19325
19605
  tristate: column.definition.headerSortTristate,
19326
19606
  };
19327
-
19607
+
19328
19608
  if(column.definition.headerSort !== false){
19329
-
19609
+
19330
19610
  colEl = column.getElement();
19331
-
19611
+
19332
19612
  colEl.classList.add("tabulator-sortable");
19333
-
19613
+
19334
19614
  arrowEl = document.createElement("div");
19335
19615
  arrowEl.classList.add("tabulator-col-sorter");
19336
-
19616
+
19337
19617
  switch(this.table.options.headerSortClickElement){
19338
19618
  case "icon":
19339
19619
  arrowEl.classList.add("tabulator-col-sorter-element");
@@ -19345,33 +19625,39 @@ class Sort extends Module{
19345
19625
  colEl.classList.add("tabulator-col-sorter-element");
19346
19626
  break;
19347
19627
  }
19348
-
19628
+
19349
19629
  switch(this.table.options.headerSortElement){
19350
19630
  case "function":
19351
- //do nothing
19631
+ //do nothing
19352
19632
  break;
19353
-
19633
+
19354
19634
  case "object":
19355
19635
  arrowEl.appendChild(this.table.options.headerSortElement);
19356
19636
  break;
19357
-
19637
+
19358
19638
  default:
19359
19639
  arrowEl.innerHTML = this.table.options.headerSortElement;
19360
19640
  }
19361
-
19641
+
19362
19642
  //create sorter arrow
19363
19643
  column.titleHolderElement.appendChild(arrowEl);
19364
-
19644
+
19365
19645
  column.modules.sort.element = arrowEl;
19366
-
19646
+
19367
19647
  this.setColumnHeaderSortIcon(column, "none");
19368
-
19648
+
19649
+ if(this.table.options.headerSortClickElement === "icon"){
19650
+ arrowEl.addEventListener("mousedown", (e) => {
19651
+ e.stopPropagation();
19652
+ });
19653
+ }
19654
+
19369
19655
  //sort on click
19370
19656
  (this.table.options.headerSortClickElement === "icon" ? arrowEl : colEl).addEventListener("click", (e) => {
19371
19657
  var dir = "",
19372
19658
  sorters=[],
19373
19659
  match = false;
19374
-
19660
+
19375
19661
  if(column.modules.sort){
19376
19662
  if(column.modules.sort.tristate){
19377
19663
  if(column.modules.sort.dir == "none"){
@@ -19388,26 +19674,26 @@ class Sort extends Module{
19388
19674
  case "asc":
19389
19675
  dir = "desc";
19390
19676
  break;
19391
-
19677
+
19392
19678
  case "desc":
19393
19679
  dir = "asc";
19394
19680
  break;
19395
-
19681
+
19396
19682
  default:
19397
19683
  dir = column.modules.sort.startingDir;
19398
19684
  }
19399
19685
  }
19400
-
19686
+
19401
19687
  if (this.table.options.columnHeaderSortMulti && (e.shiftKey || e.ctrlKey)) {
19402
19688
  sorters = this.getSort();
19403
-
19689
+
19404
19690
  match = sorters.findIndex((sorter) => {
19405
19691
  return sorter.field === column.getField();
19406
19692
  });
19407
-
19693
+
19408
19694
  if(match > -1){
19409
19695
  sorters[match].dir = dir;
19410
-
19696
+
19411
19697
  match = sorters.splice(match, 1)[0];
19412
19698
  if(dir != "none"){
19413
19699
  sorters.push(match);
@@ -19417,7 +19703,7 @@ class Sort extends Module{
19417
19703
  sorters.push({column:column, dir:dir});
19418
19704
  }
19419
19705
  }
19420
-
19706
+
19421
19707
  //add to existing sort
19422
19708
  this.setSort(sorters);
19423
19709
  }else {
@@ -19427,63 +19713,63 @@ class Sort extends Module{
19427
19713
  //sort by column only
19428
19714
  this.setSort(column, dir);
19429
19715
  }
19430
-
19716
+
19431
19717
  }
19432
-
19718
+
19433
19719
  // this.table.rowManager.sorterRefresh(!this.sortList.length);
19434
19720
  this.refreshSort();
19435
19721
  }
19436
19722
  });
19437
19723
  }
19438
19724
  }
19439
-
19725
+
19440
19726
  refreshSort(){
19441
19727
  if(this.table.options.sortMode === "remote"){
19442
19728
  this.reloadData(null, false, false);
19443
19729
  }else {
19444
19730
  this.refreshData(true);
19445
19731
  }
19446
-
19732
+
19447
19733
  //TODO - Persist left position of row manager
19448
19734
  // left = this.scrollLeft;
19449
19735
  // this.scrollHorizontal(left);
19450
19736
  }
19451
-
19737
+
19452
19738
  //check if the sorters have changed since last use
19453
19739
  hasChanged(){
19454
19740
  var changed = this.changed;
19455
19741
  this.changed = false;
19456
19742
  return changed;
19457
19743
  }
19458
-
19744
+
19459
19745
  //return current sorters
19460
19746
  getSort(){
19461
19747
  var self = this,
19462
19748
  sorters = [];
19463
-
19749
+
19464
19750
  self.sortList.forEach(function(item){
19465
19751
  if(item.column){
19466
19752
  sorters.push({column:item.column.getComponent(), field:item.column.getField(), dir:item.dir});
19467
19753
  }
19468
19754
  });
19469
-
19755
+
19470
19756
  return sorters;
19471
19757
  }
19472
-
19758
+
19473
19759
  //change sort list and trigger sort
19474
19760
  setSort(sortList, dir){
19475
19761
  var self = this,
19476
19762
  newSortList = [];
19477
-
19763
+
19478
19764
  if(!Array.isArray(sortList)){
19479
19765
  sortList = [{column: sortList, dir:dir}];
19480
19766
  }
19481
-
19767
+
19482
19768
  sortList.forEach(function(item){
19483
19769
  var column;
19484
-
19770
+
19485
19771
  column = self.table.columnManager.findColumn(item.column);
19486
-
19772
+
19487
19773
  if(column){
19488
19774
  item.column = column;
19489
19775
  newSortList.push(item);
@@ -19491,42 +19777,42 @@ class Sort extends Module{
19491
19777
  }else {
19492
19778
  console.warn("Sort Warning - Sort field does not exist and is being ignored: ", item.column);
19493
19779
  }
19494
-
19780
+
19495
19781
  });
19496
-
19782
+
19497
19783
  self.sortList = newSortList;
19498
-
19784
+
19499
19785
  this.dispatch("sort-changed");
19500
19786
  }
19501
-
19787
+
19502
19788
  //clear sorters
19503
19789
  clear(){
19504
19790
  this.setSort([]);
19505
19791
  }
19506
-
19792
+
19507
19793
  //find appropriate sorter for column
19508
19794
  findSorter(column){
19509
19795
  var row = this.table.rowManager.activeRows[0],
19510
19796
  sorter = "string",
19511
19797
  field, value;
19512
-
19798
+
19513
19799
  if(row){
19514
19800
  row = row.getData();
19515
19801
  field = column.getField();
19516
-
19802
+
19517
19803
  if(field){
19518
-
19804
+
19519
19805
  value = column.getFieldValue(row);
19520
-
19806
+
19521
19807
  switch(typeof value){
19522
19808
  case "undefined":
19523
19809
  sorter = "string";
19524
19810
  break;
19525
-
19811
+
19526
19812
  case "boolean":
19527
19813
  sorter = "boolean";
19528
19814
  break;
19529
-
19815
+
19530
19816
  default:
19531
19817
  if(!isNaN(value) && value !== ""){
19532
19818
  sorter = "number";
@@ -19539,151 +19825,1455 @@ class Sort extends Module{
19539
19825
  }
19540
19826
  }
19541
19827
  }
19542
-
19543
- return Sort.sorters[sorter];
19828
+
19829
+ return Sort.sorters[sorter];
19830
+ }
19831
+
19832
+ //work through sort list sorting data
19833
+ sort(data){
19834
+ var self = this,
19835
+ sortList = this.table.options.sortOrderReverse ? self.sortList.slice().reverse() : self.sortList,
19836
+ sortListActual = [],
19837
+ rowComponents = [];
19838
+
19839
+ if(this.subscribedExternal("dataSorting")){
19840
+ this.dispatchExternal("dataSorting", self.getSort());
19841
+ }
19842
+
19843
+ self.clearColumnHeaders();
19844
+
19845
+ if(this.table.options.sortMode !== "remote"){
19846
+
19847
+ //build list of valid sorters and trigger column specific callbacks before sort begins
19848
+ sortList.forEach(function(item, i){
19849
+ var sortObj;
19850
+
19851
+ if(item.column){
19852
+ sortObj = item.column.modules.sort;
19853
+
19854
+ if(sortObj){
19855
+
19856
+ //if no sorter has been defined, take a guess
19857
+ if(!sortObj.sorter){
19858
+ sortObj.sorter = self.findSorter(item.column);
19859
+ }
19860
+
19861
+ item.params = typeof sortObj.params === "function" ? sortObj.params(item.column.getComponent(), item.dir) : sortObj.params;
19862
+
19863
+ sortListActual.push(item);
19864
+ }
19865
+
19866
+ self.setColumnHeader(item.column, item.dir);
19867
+ }
19868
+ });
19869
+
19870
+ //sort data
19871
+ if (sortListActual.length) {
19872
+ self._sortItems(data, sortListActual);
19873
+ }
19874
+
19875
+ }else {
19876
+ sortList.forEach(function(item, i){
19877
+ self.setColumnHeader(item.column, item.dir);
19878
+ });
19879
+ }
19880
+
19881
+ if(this.subscribedExternal("dataSorted")){
19882
+ data.forEach((row) => {
19883
+ rowComponents.push(row.getComponent());
19884
+ });
19885
+
19886
+ this.dispatchExternal("dataSorted", self.getSort(), rowComponents);
19887
+ }
19888
+
19889
+ return data;
19890
+ }
19891
+
19892
+ //clear sort arrows on columns
19893
+ clearColumnHeaders(){
19894
+ this.table.columnManager.getRealColumns().forEach((column) => {
19895
+ if(column.modules.sort){
19896
+ column.modules.sort.dir = "none";
19897
+ column.getElement().setAttribute("aria-sort", "none");
19898
+ this.setColumnHeaderSortIcon(column, "none");
19899
+ }
19900
+ });
19901
+ }
19902
+
19903
+ //set the column header sort direction
19904
+ setColumnHeader(column, dir){
19905
+ column.modules.sort.dir = dir;
19906
+ column.getElement().setAttribute("aria-sort", dir === "asc" ? "ascending" : "descending");
19907
+ this.setColumnHeaderSortIcon(column, dir);
19908
+ }
19909
+
19910
+ setColumnHeaderSortIcon(column, dir){
19911
+ var sortEl = column.modules.sort.element,
19912
+ arrowEl;
19913
+
19914
+ if(column.definition.headerSort && typeof this.table.options.headerSortElement === "function"){
19915
+ while(sortEl.firstChild) sortEl.removeChild(sortEl.firstChild);
19916
+
19917
+ arrowEl = this.table.options.headerSortElement.call(this.table, column.getComponent(), dir);
19918
+
19919
+ if(typeof arrowEl === "object"){
19920
+ sortEl.appendChild(arrowEl);
19921
+ }else {
19922
+ sortEl.innerHTML = arrowEl;
19923
+ }
19924
+ }
19925
+ }
19926
+
19927
+ //sort each item in sort list
19928
+ _sortItems(data, sortList){
19929
+ var sorterCount = sortList.length - 1;
19930
+
19931
+ data.sort((a, b) => {
19932
+ var result;
19933
+
19934
+ for(var i = sorterCount; i>= 0; i--){
19935
+ let sortItem = sortList[i];
19936
+
19937
+ result = this._sortRow(a, b, sortItem.column, sortItem.dir, sortItem.params);
19938
+
19939
+ if(result !== 0){
19940
+ break;
19941
+ }
19942
+ }
19943
+
19944
+ return result;
19945
+ });
19946
+ }
19947
+
19948
+ //process individual rows for a sort function on active data
19949
+ _sortRow(a, b, column, dir, params){
19950
+ var el1Comp, el2Comp;
19951
+
19952
+ //switch elements depending on search direction
19953
+ var el1 = dir == "asc" ? a : b;
19954
+ var el2 = dir == "asc" ? b : a;
19955
+
19956
+ a = column.getFieldValue(el1.getData());
19957
+ b = column.getFieldValue(el2.getData());
19958
+
19959
+ a = typeof a !== "undefined" ? a : "";
19960
+ b = typeof b !== "undefined" ? b : "";
19961
+
19962
+ el1Comp = el1.getComponent();
19963
+ el2Comp = el2.getComponent();
19964
+
19965
+ return column.modules.sort.sorter.call(this, a, b, el1Comp, el2Comp, column.getComponent(), dir, params);
19966
+ }
19967
+ }
19968
+
19969
+ Sort.moduleName = "sort";
19970
+
19971
+ //load defaults
19972
+ Sort.sorters = defaultSorters;
19973
+
19974
+ class RangeComponent {
19975
+ constructor(range) {
19976
+ this._range = range;
19977
+
19978
+ return new Proxy(this, {
19979
+ get: function (target, name, receiver) {
19980
+ if (typeof target[name] !== "undefined") {
19981
+ return target[name];
19982
+ } else {
19983
+ return target._range.table.componentFunctionBinder.handle("range", target._range, name);
19984
+ }
19985
+ },
19986
+ });
19987
+ }
19988
+
19989
+ getElement() {
19990
+ return this._range.element;
19991
+ }
19992
+
19993
+ getData() {
19994
+ return this._range.getData();
19995
+ }
19996
+
19997
+ getCells() {
19998
+ return this._range.getCells(true);
19999
+ }
20000
+
20001
+ getStructuredCells() {
20002
+ return this._range.getStructuredCells();
20003
+ }
20004
+
20005
+ getRows() {
20006
+ return this._range.getRows().map((row) => row.getComponent());
20007
+ }
20008
+
20009
+ getColumns() {
20010
+ return this._range.getColumns().map((column) => column.getComponent());
20011
+ }
20012
+
20013
+ getBounds() {
20014
+ return this._range.getBounds();
20015
+ }
20016
+
20017
+ getTopEdge() {
20018
+ return this._range.top;
20019
+ }
20020
+
20021
+ getBottomEdge() {
20022
+ return this._range.bottom;
20023
+ }
20024
+
20025
+ getLeftEdge() {
20026
+ return this._range.left;
20027
+ }
20028
+
20029
+ getRightEdge() {
20030
+ return this._range.right;
20031
+ }
20032
+
20033
+ setBounds(start, end){
20034
+ if(this._range.destroyedGuard("setBounds")){
20035
+ this._range.setBounds(start ? start._cell : start, end ? end._cell : end);
20036
+ }
20037
+ }
20038
+
20039
+ setStartBound(start){
20040
+ if(this._range.destroyedGuard("setStartBound")){
20041
+ this._range.setEndBound(start ? start._cell : start);
20042
+ this._range.rangeManager.layoutElement();
20043
+ }
20044
+ }
20045
+
20046
+ setEndBound(end){
20047
+ if(this._range.destroyedGuard("setEndBound")){
20048
+ this._range.setEndBound(end ? end._cell : end);
20049
+ this._range.rangeManager.layoutElement();
20050
+ }
20051
+ }
20052
+
20053
+ clearValues(){
20054
+ if(this._range.destroyedGuard("clearValues")){
20055
+ this._range.clearValues();
20056
+ }
20057
+ }
20058
+
20059
+ remove(){
20060
+ if(this._range.destroyedGuard("remove")){
20061
+ this._range.destroy(true);
20062
+ }
20063
+ }
20064
+ }
20065
+
20066
+ class Range extends CoreFeature{
20067
+ constructor(table, rangeManager, start, end) {
20068
+ super(table);
20069
+
20070
+ this.rangeManager = rangeManager;
20071
+ this.element = null;
20072
+ this.initialized = false;
20073
+ this.initializing = {
20074
+ start:false,
20075
+ end:false,
20076
+ };
20077
+ this.destroyed = false;
20078
+
20079
+ this.top = 0;
20080
+ this.bottom = 0;
20081
+ this.left = 0;
20082
+ this.right = 0;
20083
+
20084
+ this.table = table;
20085
+ this.start = {row:0, col:0};
20086
+ this.end = {row:0, col:0};
20087
+
20088
+ if(this.rangeManager.rowHeader){
20089
+ this.left = 1;
20090
+ this.right = 1;
20091
+ this.start.col = 1;
20092
+ this.end.col = 1;
20093
+ }
20094
+
20095
+ this.initElement();
20096
+
20097
+ setTimeout(() => {
20098
+ this.initBounds(start, end);
20099
+ });
20100
+ }
20101
+
20102
+ initElement(){
20103
+ this.element = document.createElement("div");
20104
+ this.element.classList.add("tabulator-range");
20105
+ }
20106
+
20107
+ initBounds(start, end){
20108
+ this._updateMinMax();
20109
+
20110
+ if(start){
20111
+ this.setBounds(start, end || start);
20112
+ }
20113
+ }
20114
+
20115
+ ///////////////////////////////////
20116
+ /////// Boundary Setup ///////
20117
+ ///////////////////////////////////
20118
+
20119
+ setStart(row, col) {
20120
+ if(this.start.row !== row || this.start.col !== col){
20121
+ this.start.row = row;
20122
+ this.start.col = col;
20123
+
20124
+ this.initializing.start = true;
20125
+ this._updateMinMax();
20126
+ }
20127
+ }
20128
+
20129
+ setEnd(row, col) {
20130
+ if(this.end.row !== row || this.end.col !== col){
20131
+ this.end.row = row;
20132
+ this.end.col = col;
20133
+
20134
+ this.initializing.end = true;
20135
+ this._updateMinMax();
20136
+ }
20137
+ }
20138
+
20139
+ setBounds(start, end, visibleRows){
20140
+ if(start){
20141
+ this.setStartBound(start);
20142
+ }
20143
+
20144
+ this.setEndBound(end || start);
20145
+ this.rangeManager.layoutElement(visibleRows);
20146
+ }
20147
+
20148
+ setStartBound(element){
20149
+ var row, col;
20150
+
20151
+ if (element.type === "column") {
20152
+ if(this.rangeManager.columnSelection){
20153
+ this.setStart(0, element.getPosition() - 1);
20154
+ }
20155
+ }else {
20156
+ row = element.row.position - 1;
20157
+ col = element.column.getPosition() - 1;
20158
+
20159
+ if (element.column === this.rangeManager.rowHeader) {
20160
+ this.setStart(row, 1);
20161
+ } else {
20162
+ this.setStart(row, col);
20163
+ }
20164
+ }
20165
+ }
20166
+
20167
+ setEndBound(element){
20168
+ var rowsCount = this._getTableRows().length,
20169
+ row, col, isRowHeader;
20170
+
20171
+ if (element.type === "column") {
20172
+ if(this.rangeManager.columnSelection){
20173
+ if (this.rangeManager.selecting === "column") {
20174
+ this.setEnd(rowsCount - 1, element.getPosition() - 1);
20175
+ } else if (this.rangeManager.selecting === "cell") {
20176
+ this.setEnd(0, element.getPosition() - 1);
20177
+ }
20178
+ }
20179
+ }else {
20180
+ row = element.row.position - 1;
20181
+ col = element.column.getPosition() - 1;
20182
+ isRowHeader = element.column === this.rangeManager.rowHeader;
20183
+
20184
+ if (this.rangeManager.selecting === "row") {
20185
+ this.setEnd(row, this._getTableColumns().length - 1);
20186
+ } else if (this.rangeManager.selecting !== "row" && isRowHeader) {
20187
+ this.setEnd(row, 0);
20188
+ } else if (this.rangeManager.selecting === "column") {
20189
+ this.setEnd(rowsCount - 1, col);
20190
+ } else {
20191
+ this.setEnd(row, col);
20192
+ }
20193
+ }
20194
+ }
20195
+
20196
+ _updateMinMax() {
20197
+ this.top = Math.min(this.start.row, this.end.row);
20198
+ this.bottom = Math.max(this.start.row, this.end.row);
20199
+ this.left = Math.min(this.start.col, this.end.col);
20200
+ this.right = Math.max(this.start.col, this.end.col);
20201
+
20202
+ if(this.initialized){
20203
+ this.dispatchExternal("rangeChanged", this.getComponent());
20204
+ }else {
20205
+ if(this.initializing.start && this.initializing.end){
20206
+ this.initialized = true;
20207
+ this.dispatchExternal("rangeAdded", this.getComponent());
20208
+ }
20209
+ }
20210
+ }
20211
+
20212
+ _getTableColumns() {
20213
+ return this.table.columnManager.getVisibleColumnsByIndex();
20214
+ }
20215
+
20216
+ _getTableRows() {
20217
+ return this.table.rowManager.getDisplayRows();
20218
+ }
20219
+
20220
+ ///////////////////////////////////
20221
+ /////// Rendering ///////
20222
+ ///////////////////////////////////
20223
+
20224
+ layout() {
20225
+ var _vDomTop = this.table.rowManager.renderer.vDomTop,
20226
+ _vDomBottom = this.table.rowManager.renderer.vDomBottom,
20227
+ _vDomLeft = this.table.columnManager.renderer.leftCol,
20228
+ _vDomRight = this.table.columnManager.renderer.rightCol,
20229
+ top, bottom, left, right, topLeftCell, bottomRightCell;
20230
+
20231
+ if (_vDomTop == null) {
20232
+ _vDomTop = 0;
20233
+ }
20234
+
20235
+ if (_vDomBottom == null) {
20236
+ _vDomBottom = Infinity;
20237
+ }
20238
+
20239
+ if (_vDomLeft == null) {
20240
+ _vDomLeft = 0;
20241
+ }
20242
+
20243
+ if (_vDomRight == null) {
20244
+ _vDomRight = Infinity;
20245
+ }
20246
+
20247
+ if (this.overlaps(_vDomLeft, _vDomTop, _vDomRight, _vDomBottom)) {
20248
+ top = Math.max(this.top, _vDomTop);
20249
+ bottom = Math.min(this.bottom, _vDomBottom);
20250
+ left = Math.max(this.left, _vDomLeft);
20251
+ right = Math.min(this.right, _vDomRight);
20252
+
20253
+ topLeftCell = this.rangeManager.getCell(top, left);
20254
+ bottomRightCell = this.rangeManager.getCell(bottom, right);
20255
+
20256
+ this.element.classList.add("tabulator-range-active");
20257
+ // this.element.classList.toggle("tabulator-range-active", this === this.rangeManager.activeRange);
20258
+
20259
+ this.element.style.left = topLeftCell.row.getElement().offsetLeft + topLeftCell.getElement().offsetLeft + "px";
20260
+ this.element.style.top = topLeftCell.row.getElement().offsetTop + "px";
20261
+ this.element.style.width = bottomRightCell.getElement().offsetLeft + bottomRightCell.getElement().offsetWidth - topLeftCell.getElement().offsetLeft + "px";
20262
+ this.element.style.height = bottomRightCell.row.getElement().offsetTop + bottomRightCell.row.getElement().offsetHeight - topLeftCell.row.getElement().offsetTop + "px";
20263
+ }
20264
+ }
20265
+
20266
+ atTopLeft(cell) {
20267
+ return cell.row.position - 1 === this.top && cell.column.getPosition() - 1 === this.left;
20268
+ }
20269
+
20270
+ atBottomRight(cell) {
20271
+ return cell.row.position - 1 === this.bottom && cell.column.getPosition() - 1 === this.right;
20272
+ }
20273
+
20274
+ occupies(cell) {
20275
+ return this.occupiesRow(cell.row) && this.occupiesColumn(cell.column);
20276
+ }
20277
+
20278
+ occupiesRow(row) {
20279
+ return this.top <= row.position - 1 && row.position - 1 <= this.bottom;
20280
+ }
20281
+
20282
+ occupiesColumn(col) {
20283
+ return this.left <= col.getPosition() - 1 && col.getPosition() - 1 <= this.right;
20284
+ }
20285
+
20286
+ overlaps(left, top, right, bottom) {
20287
+ if ((this.left > right || left > this.right) || (this.top > bottom || top > this.bottom)){
20288
+ return false;
20289
+ }
20290
+
20291
+ return true;
20292
+ }
20293
+
20294
+ getData() {
20295
+ var data = [],
20296
+ rows = this.getRows(),
20297
+ columns = this.getColumns();
20298
+
20299
+ rows.forEach((row) => {
20300
+ var rowData = row.getData(),
20301
+ result = {};
20302
+
20303
+ columns.forEach((column) => {
20304
+ result[column.field] = rowData[column.field];
20305
+ });
20306
+
20307
+ data.push(result);
20308
+ });
20309
+
20310
+ return data;
20311
+ }
20312
+
20313
+ getCells(structured, component) {
20314
+ var cells = [],
20315
+ rows = this.getRows(),
20316
+ columns = this.getColumns();
20317
+
20318
+ if (structured) {
20319
+ cells = rows.map((row) => {
20320
+ var arr = [];
20321
+
20322
+ row.getCells().forEach((cell) => {
20323
+ if (columns.includes(cell.column)) {
20324
+ arr.push(component ? cell.getComponent() : cell);
20325
+ }
20326
+ });
20327
+
20328
+ return arr;
20329
+ });
20330
+ } else {
20331
+ rows.forEach((row) => {
20332
+ row.getCells().forEach((cell) => {
20333
+ if (columns.includes(cell.column)) {
20334
+ cells.push(component ? cell.getComponent() : cell);
20335
+ }
20336
+ });
20337
+ });
20338
+ }
20339
+
20340
+ return cells;
20341
+ }
20342
+
20343
+ getStructuredCells() {
20344
+ return this.getCells(true, true);
20345
+ }
20346
+
20347
+ getRows() {
20348
+ return this._getTableRows().slice(this.top, this.bottom + 1);
20349
+ }
20350
+
20351
+ getColumns() {
20352
+ return this._getTableColumns().slice(this.left, this.right + 1);
20353
+ }
20354
+
20355
+ clearValues(){
20356
+ var cells = this.getCells();
20357
+ var clearValue = this.table.options.selectableRangeClearCellsValue;
20358
+
20359
+ this.table.blockRedraw();
20360
+
20361
+ cells.forEach((cell) => {
20362
+ cell.setValue(clearValue);
20363
+ });
20364
+
20365
+ this.table.restoreRedraw();
20366
+
20367
+ }
20368
+
20369
+ getBounds(component){
20370
+ var cells = this.getCells(false, component),
20371
+ output = {
20372
+ start:null,
20373
+ end:null,
20374
+ };
20375
+
20376
+ if(cells.length){
20377
+ output.start = cells[0];
20378
+ output.end = cells[cells.length - 1];
20379
+ }else {
20380
+ console.warn("No bounds defined on range");
20381
+ }
20382
+
20383
+ return output;
20384
+ }
20385
+
20386
+ getComponent() {
20387
+ if (!this.component) {
20388
+ this.component = new RangeComponent(this);
20389
+ }
20390
+ return this.component;
20391
+ }
20392
+
20393
+ destroy(notify) {
20394
+ this.destroyed = true;
20395
+
20396
+ this.element.remove();
20397
+
20398
+ if(notify){
20399
+ this.rangeManager.rangeRemoved(this);
20400
+ }
20401
+
20402
+ if(this.initialized){
20403
+ this.dispatchExternal("rangeRemoved", this.getComponent());
20404
+ }
20405
+ }
20406
+
20407
+ destroyedGuard(func){
20408
+ if(this.destroyed){
20409
+ console.warn("You cannot call the " + func + " function on a destroyed range");
20410
+ }
20411
+
20412
+ return !this.destroyed;
20413
+ }
20414
+ }
20415
+
20416
+ class SelectRange extends Module {
20417
+ constructor(table) {
20418
+ super(table);
20419
+
20420
+ this.selecting = "cell";
20421
+ this.mousedown = false;
20422
+ this.ranges = [];
20423
+ this.overlay = null;
20424
+ this.rowHeader = null;
20425
+ this.layoutChangeTimeout = null;
20426
+ this.columnSelection = false;
20427
+ this.rowSelection = false;
20428
+ this.maxRanges = 0;
20429
+ this.activeRange = false;
20430
+ this.blockKeydown = false;
20431
+
20432
+ this.keyDownEvent = this._handleKeyDown.bind(this);
20433
+ this.mouseUpEvent = this._handleMouseUp.bind(this);
20434
+
20435
+ this.registerTableOption("selectableRange", false); //enable selectable range
20436
+ this.registerTableOption("selectableRangeColumns", false); //enable selectable range
20437
+ this.registerTableOption("selectableRangeRows", false); //enable selectable range
20438
+ this.registerTableOption("selectableRangeClearCells", false); //allow clearing of active range
20439
+ this.registerTableOption("selectableRangeClearCellsValue", undefined); //value for cleared active range
20440
+
20441
+ this.registerTableFunction("getRangesData", this.getRangesData.bind(this));
20442
+ this.registerTableFunction("getRanges", this.getRanges.bind(this));
20443
+ this.registerTableFunction("addRange", this.addRangeFromComponent.bind(this));
20444
+
20445
+ this.registerComponentFunction("cell", "getRanges", this.cellGetRanges.bind(this));
20446
+ this.registerComponentFunction("row", "getRanges", this.rowGetRanges.bind(this));
20447
+ this.registerComponentFunction("column", "getRanges", this.colGetRanges.bind(this));
20448
+ }
20449
+
20450
+ ///////////////////////////////////
20451
+ /////// Initialization ///////
20452
+ ///////////////////////////////////
20453
+
20454
+ initialize() {
20455
+ if (this.options("selectableRange")) {
20456
+ if(!this.options("selectableRows")){
20457
+
20458
+ this.maxRanges = this.options("selectableRange");
20459
+
20460
+ this.initializeTable();
20461
+ this.initializeWatchers();
20462
+ }else {
20463
+ console.warn("SelectRange functionality cannot be used in conjunction with row selection");
20464
+ }
20465
+ }
20466
+ }
20467
+
20468
+
20469
+ initializeTable() {
20470
+ this.overlay = document.createElement("div");
20471
+ this.overlay.classList.add("tabulator-range-overlay");
20472
+
20473
+ this.rangeContainer = document.createElement("div");
20474
+ this.rangeContainer.classList.add("tabulator-range-container");
20475
+
20476
+ this.activeRangeCellElement = document.createElement("div");
20477
+ this.activeRangeCellElement.classList.add("tabulator-range-cell-active");
20478
+
20479
+ this.overlay.appendChild(this.rangeContainer);
20480
+ this.overlay.appendChild(this.activeRangeCellElement);
20481
+
20482
+ this.table.rowManager.element.addEventListener("keydown", this.keyDownEvent);
20483
+
20484
+ this.resetRanges();
20485
+
20486
+ this.table.rowManager.element.appendChild(this.overlay);
20487
+ this.table.columnManager.element.setAttribute("tabindex", 0);
20488
+ this.table.element.classList.add("tabulator-ranges");
20489
+ }
20490
+
20491
+ initializeWatchers() {
20492
+ this.columnSelection = this.options("selectableRangeColumns");
20493
+ this.rowSelection = this.options("selectableRangeRows");
20494
+
20495
+ this.subscribe("column-init", this.initializeColumn.bind(this));
20496
+ this.subscribe("column-mousedown", this.handleColumnMouseDown.bind(this));
20497
+ this.subscribe("column-mousemove", this.handleColumnMouseMove.bind(this));
20498
+ this.subscribe("column-resized", this.handleColumnResized.bind(this));
20499
+ this.subscribe("column-width", this.layoutChange.bind(this));
20500
+ this.subscribe("column-height", this.layoutChange.bind(this));
20501
+ this.subscribe("column-resized", this.layoutChange.bind(this));
20502
+ this.subscribe("columns-loaded", this.updateHeaderColumn.bind(this));
20503
+
20504
+ this.subscribe("cell-height", this.layoutChange.bind(this));
20505
+ this.subscribe("cell-rendered", this.renderCell.bind(this));
20506
+ this.subscribe("cell-mousedown", this.handleCellMouseDown.bind(this));
20507
+ this.subscribe("cell-mousemove", this.handleCellMouseMove.bind(this));
20508
+ this.subscribe("cell-click", this.handleCellClick.bind(this));
20509
+ this.subscribe("cell-editing", this.handleEditingCell.bind(this));
20510
+
20511
+ this.subscribe("page-changed", this.redraw.bind(this));
20512
+
20513
+ this.subscribe("scroll-vertical", this.layoutChange.bind(this));
20514
+ this.subscribe("scroll-horizontal", this.layoutChange.bind(this));
20515
+
20516
+ this.subscribe("data-destroy", this.tableDestroyed.bind(this));
20517
+ this.subscribe("data-processed", this.resetRanges.bind(this));
20518
+
20519
+ this.subscribe("table-layout", this.layoutElement.bind(this));
20520
+ this.subscribe("table-redraw", this.redraw.bind(this));
20521
+ this.subscribe("table-destroy", this.tableDestroyed.bind(this));
20522
+
20523
+ this.subscribe("edit-editor-clear", this.finishEditingCell.bind(this));
20524
+ this.subscribe("edit-blur", this.restoreFocus.bind(this));
20525
+
20526
+ this.subscribe("keybinding-nav-prev", this.keyNavigate.bind(this, "left"));
20527
+ this.subscribe("keybinding-nav-next", this.keyNavigate.bind(this, "right"));
20528
+ this.subscribe("keybinding-nav-left", this.keyNavigate.bind(this, "left"));
20529
+ this.subscribe("keybinding-nav-right", this.keyNavigate.bind(this, "right"));
20530
+ this.subscribe("keybinding-nav-up", this.keyNavigate.bind(this, "up"));
20531
+ this.subscribe("keybinding-nav-down", this.keyNavigate.bind(this, "down"));
20532
+ this.subscribe("keybinding-nav-range", this.keyNavigateRange.bind(this));
20533
+ }
20534
+
20535
+
20536
+ initializeColumn(column) {
20537
+ if(this.columnSelection && column.definition.headerSort && this.options("headerSortClickElement") !== "icon"){
20538
+ console.warn("Using column headerSort with selectableRangeColumns option may result in unpredictable behavior. Consider using headerSortClickElement: 'icon'.");
20539
+ }
20540
+
20541
+ if (column.modules.edit) ;
20542
+ }
20543
+
20544
+ updateHeaderColumn(){
20545
+ if(this.rowSelection){
20546
+ this.rowHeader = this.table.columnManager.getVisibleColumnsByIndex()[0];
20547
+
20548
+ if(this.rowHeader){
20549
+ this.rowHeader.definition.cssClass = this.rowHeader.definition.cssClass + " tabulator-range-row-header";
20550
+
20551
+ if(this.rowHeader.definition.headerSort){
20552
+ console.warn("Using column headerSort with selectableRangeRows option may result in unpredictable behavior");
20553
+ }
20554
+
20555
+ if(this.rowHeader.definition.editor){
20556
+ console.warn("Using column editor with selectableRangeRows option may result in unpredictable behavior");
20557
+ }
20558
+ }
20559
+ }
20560
+ }
20561
+
20562
+ ///////////////////////////////////
20563
+ /////// Table Functions ///////
20564
+ ///////////////////////////////////
20565
+
20566
+ getRanges(){
20567
+ return this.ranges.map((range) => range.getComponent());
20568
+ }
20569
+
20570
+ getRangesData() {
20571
+ return this.ranges.map((range) => range.getData());
20572
+ }
20573
+
20574
+ addRangeFromComponent(start, end){
20575
+ start = start ? start._cell : null;
20576
+ end = end ? end._cell : null;
20577
+
20578
+ return this.addRange(start, end);
20579
+ }
20580
+
20581
+ ///////////////////////////////////
20582
+ /////// Component Functions ///////
20583
+ ///////////////////////////////////
20584
+
20585
+ cellGetRanges(cell){
20586
+ var ranges = [];
20587
+
20588
+ if (cell.column === this.rowHeader) {
20589
+ ranges = this.ranges.filter((range) => range.occupiesRow(cell.row));
20590
+ } else {
20591
+ ranges = this.ranges.filter((range) => range.occupies(cell));
20592
+ }
20593
+
20594
+ return ranges.map((range) => range.getComponent());
20595
+ }
20596
+
20597
+ rowGetRanges(row){
20598
+ var ranges = this.ranges.filter((range) => range.occupiesRow(row));
20599
+
20600
+ return ranges.map((range) => range.getComponent());
20601
+ }
20602
+
20603
+ colGetRanges(col){
20604
+ var ranges = this.ranges.filter((range) => range.occupiesColumn(col));
20605
+
20606
+ return ranges.map((range) => range.getComponent());
20607
+ }
20608
+
20609
+ ///////////////////////////////////
20610
+ ////////// Event Handlers /////////
20611
+ ///////////////////////////////////
20612
+
20613
+ _handleMouseUp(e){
20614
+ this.mousedown = false;
20615
+ document.removeEventListener("mouseup", this.mouseUpEvent);
20616
+ }
20617
+
20618
+ _handleKeyDown(e) {
20619
+ if (!this.blockKeydown && (!this.table.modules.edit || (this.table.modules.edit && !this.table.modules.edit.currentCell))) {
20620
+ if (e.key === "Enter") {
20621
+ // is editing a cell?
20622
+ if (this.table.modules.edit && this.table.modules.edit.currentCell) {
20623
+ return;
20624
+ }
20625
+
20626
+ this.table.modules.edit.editCell(this.getActiveCell());
20627
+
20628
+ e.preventDefault();
20629
+ }
20630
+
20631
+ if ((e.key === "Backspace" || e.key === "Delete") && this.options("selectableRangeClearCells")) {
20632
+ if(this.activeRange){
20633
+ this.activeRange.clearValues();
20634
+ }
20635
+ }
20636
+ }
20637
+ }
20638
+
20639
+ initializeFocus(cell){
20640
+ var range;
20641
+
20642
+ try{
20643
+ if (document.selection) { // IE
20644
+ range = document.body.createTextRange();
20645
+ range.moveToElementText(cell.getElement());
20646
+ range.select();
20647
+ } else if (window.getSelection) {
20648
+ range = document.createRange();
20649
+ range.selectNode(cell.getElement());
20650
+ window.getSelection().removeAllRanges();
20651
+ window.getSelection().addRange(range);
20652
+ }
20653
+ }catch(e){}
20654
+ }
20655
+
20656
+ restoreFocus(element){
20657
+ this.table.rowManager.element.focus();
20658
+
20659
+ return true;
20660
+ }
20661
+
20662
+ ///////////////////////////////////
20663
+ ////// Column Functionality ///////
20664
+ ///////////////////////////////////
20665
+
20666
+ handleColumnResized(column) {
20667
+ var selected;
20668
+
20669
+ if (this.selecting !== "column" && this.selecting !== "all") {
20670
+ return;
20671
+ }
20672
+
20673
+ selected = this.ranges.some((range) => range.occupiesColumn(column));
20674
+
20675
+ if (!selected) {
20676
+ return;
20677
+ }
20678
+
20679
+ this.ranges.forEach((range) => {
20680
+ var selectedColumns = range.getColumns(true);
20681
+
20682
+ selectedColumns.forEach((selectedColumn) => {
20683
+ if (selectedColumn !== column) {
20684
+ selectedColumn.setWidth(column.width);
20685
+ }
20686
+ });
20687
+ });
20688
+ }
20689
+
20690
+ handleColumnMouseDown(event, column) {
20691
+ if (event.button === 2 && (this.selecting === "column" || this.selecting === "all") && this.activeRange.occupiesColumn(column)) {
20692
+ return;
20693
+ }
20694
+
20695
+ this.mousedown = true;
20696
+
20697
+ document.addEventListener("mouseup", this.mouseUpEvent);
20698
+
20699
+ this.newSelection(event, column);
20700
+ }
20701
+
20702
+ handleColumnMouseMove(e, column) {
20703
+ if (column === this.rowHeader || !this.mousedown || this.selecting === 'all') {
20704
+ return;
20705
+ }
20706
+
20707
+ this.activeRange.setBounds(false, column, true);
20708
+ }
20709
+
20710
+ ///////////////////////////////////
20711
+ //////// Cell Functionality ///////
20712
+ ///////////////////////////////////
20713
+
20714
+ renderCell(cell) {
20715
+ var el = cell.getElement(),
20716
+ rangeIdx = this.ranges.findIndex((range) => range.occupies(cell));
20717
+
20718
+ el.classList.toggle("tabulator-range-selected", rangeIdx !== -1);
20719
+ el.classList.toggle("tabulator-range-only-cell-selected", this.ranges.length === 1 && this.ranges[0].atTopLeft(cell) && this.ranges[0].atBottomRight(cell));
20720
+
20721
+ el.dataset.range = rangeIdx;
20722
+ }
20723
+
20724
+ handleCellMouseDown(event, cell) {
20725
+ if (event.button === 2 && (this.activeRange.occupies(cell) || ((this.selecting === "row" || this.selecting === "all") && this.activeRange.occupiesRow(cell.row)))) {
20726
+ return;
20727
+ }
20728
+
20729
+ this.mousedown = true;
20730
+
20731
+ document.addEventListener("mouseup", this.mouseUpEvent);
20732
+
20733
+ this.newSelection(event, cell);
20734
+ }
20735
+
20736
+ handleCellMouseMove(e, cell) {
20737
+ if (!this.mousedown || this.selecting === "all") {
20738
+ return;
20739
+ }
20740
+
20741
+ this.activeRange.setBounds(false, cell, true);
20742
+ }
20743
+
20744
+ handleCellClick(e, cell){
20745
+ this.initializeFocus(cell);
20746
+ }
20747
+
20748
+ handleEditingCell(cell) {
20749
+ if(this.activeRange){
20750
+ this.activeRange.setBounds(cell);
20751
+ }
20752
+ }
20753
+
20754
+ finishEditingCell() {
20755
+ this.blockKeydown = true;
20756
+ this.table.rowManager.element.focus();
20757
+
20758
+ setTimeout(() => {
20759
+ this.blockKeydown = false;
20760
+ }, 10);
20761
+ }
20762
+
20763
+ ///////////////////////////////////
20764
+ /////// Navigation ///////
20765
+ ///////////////////////////////////
20766
+
20767
+ keyNavigate(dir, e){
20768
+ if(this.navigate(false, false, dir)){
20769
+ e.preventDefault();
20770
+ }
20771
+ }
20772
+
20773
+ keyNavigateRange(e, dir, jump, expand){
20774
+ if(this.navigate(jump, expand, dir)){
20775
+ e.preventDefault();
20776
+ }
20777
+ }
20778
+
20779
+ navigate(jump, expand, dir) {
20780
+ var moved = false,
20781
+ range, rangeEdge, nextRow, nextCol, row, column;
20782
+
20783
+ // Don't navigate while editing
20784
+ if (this.table.modules.edit && this.table.modules.edit.currentCell) {
20785
+ return false;
20786
+ }
20787
+
20788
+ // If there are more than 1 range, use the active range and destroy the others
20789
+ if (this.ranges.length > 1) {
20790
+ this.ranges = this.ranges.filter((range) => {
20791
+ if (range === this.activeRange) {
20792
+ range.setEnd(range.start.row, range.start.col);
20793
+ return true;
20794
+ }
20795
+ range.destroy();
20796
+ return false;
20797
+ });
20798
+ }
20799
+
20800
+ range = this.activeRange;
20801
+
20802
+ rangeEdge = expand ? range.end : range.start;
20803
+ nextRow = rangeEdge.row;
20804
+ nextCol = rangeEdge.col;
20805
+
20806
+ if(jump){
20807
+ switch(dir){
20808
+ case "left":
20809
+ nextCol = this.findJumpCellLeft(range.start.row, rangeEdge.col);
20810
+ break;
20811
+ case "right":
20812
+ nextCol = this.findJumpCellRight(range.start.row, rangeEdge.col);
20813
+ break;
20814
+ case "up":
20815
+ nextRow = this.findJumpCellUp(rangeEdge.row, range.start.col);
20816
+ break;
20817
+ case "down":
20818
+ nextRow = this.findJumpCellDown(rangeEdge.row, range.start.col);
20819
+ break;
20820
+ }
20821
+ }else {
20822
+ if(expand){
20823
+ if ((this.selecting === 'row' && (dir === 'left' || dir === 'right')) || (this.selecting === 'column' && (dir === 'up' || dir === 'down'))) {
20824
+ return;
20825
+ }
20826
+ }
20827
+
20828
+ switch(dir){
20829
+ case "left":
20830
+ nextCol = Math.max(nextCol - 1, 0);
20831
+ break;
20832
+ case "right":
20833
+ nextCol = Math.min(nextCol + 1, this.getTableColumns().length - 1);
20834
+ break;
20835
+ case "up":
20836
+ nextRow = Math.max(nextRow - 1, 0);
20837
+ break;
20838
+ case "down":
20839
+ nextRow = Math.min(nextRow + 1, this.getTableRows().length - 1);
20840
+ break;
20841
+ }
20842
+ }
20843
+
20844
+ moved = nextCol !== rangeEdge.col || nextRow !== rangeEdge.row;
20845
+
20846
+ if(!expand){
20847
+ range.setStart(nextRow, nextCol);
20848
+ }
20849
+
20850
+ range.setEnd(nextRow, nextCol);
20851
+
20852
+ if(!expand){
20853
+ this.selecting = "cell";
20854
+ }
20855
+
20856
+ if (moved) {
20857
+ row = this.getRowByRangePos(range.end.row);
20858
+ column = this.getColumnByRangePos(range.end.col);
20859
+
20860
+ if ((dir === 'left' || dir === 'right') && column.getElement().parentNode === null) {
20861
+ column.getComponent().scrollTo(undefined, false);
20862
+ } else if ((dir === 'up' || dir === 'down') && row.getElement().parentNode === null) {
20863
+ row.getComponent().scrollTo(undefined, false);
20864
+ } else {
20865
+ // Use faster autoScroll when the elements are on the DOM
20866
+ this.autoScroll(range, row.getElement(), column.getElement());
20867
+ }
20868
+
20869
+ this.layoutElement();
20870
+
20871
+ return true;
20872
+ }
20873
+ }
20874
+
20875
+ rangeRemoved(removed){
20876
+ this.ranges = this.ranges.filter((range) => range !== removed);
20877
+
20878
+ if(this.activeRange === removed){
20879
+ if(this.ranges.length){
20880
+ this.activeRange = this.ranges[this.ranges.length - 1];
20881
+ }else {
20882
+ this.addRange();
20883
+ }
20884
+ }
20885
+
20886
+ this.layoutElement();
20887
+ }
20888
+
20889
+ findJumpCell(cells, reverse, emptyStart, emptySide){
20890
+ var nextCell;
20891
+
20892
+ if(reverse){
20893
+ cells = cells.reverse();
20894
+ }
20895
+
20896
+ for(let currentCell of cells){
20897
+ let currentValue = currentCell.getValue();
20898
+
20899
+ if(emptyStart){
20900
+ nextCell = currentCell;
20901
+ if(currentValue){
20902
+ break;
20903
+ }
20904
+ }else {
20905
+ if(emptySide){
20906
+ nextCell = currentCell;
20907
+
20908
+ if(currentValue){
20909
+ break;
20910
+ }
20911
+ }else {
20912
+ if(currentValue){
20913
+ nextCell = currentCell;
20914
+ }else {
20915
+ break;
20916
+ }
20917
+ }
20918
+ }
20919
+ }
20920
+
20921
+ return nextCell;
20922
+ }
20923
+
20924
+ findJumpCellLeft(rowPos, colPos){
20925
+ var row = this.getRowByRangePos(rowPos),
20926
+ cells = row.cells.filter((cell) => cell.column.visible),
20927
+ isStartingCellEmpty = !cells[colPos].getValue(),
20928
+ isLeftOfStartingCellEmpty = cells[colPos] ? !cells[colPos].getValue() : false,
20929
+ jumpCol = colPos,
20930
+ targetCells = this.rowHeader ? cells.slice(1, colPos) : cells.slice(0, colPos),
20931
+ nextCell = this.findJumpCell(targetCells, true, isStartingCellEmpty, isLeftOfStartingCellEmpty);
20932
+
20933
+ if(nextCell){
20934
+ jumpCol = nextCell.column.getPosition() - 1;
20935
+ }
20936
+
20937
+ return jumpCol;
20938
+ }
20939
+
20940
+ findJumpCellRight(rowPos, colPos){
20941
+ var row = this.getRowByRangePos(rowPos),
20942
+ cells = row.cells.filter((cell) => cell.column.visible),
20943
+ isStartingCellEmpty = !cells[colPos].getValue(),
20944
+ isRightOfStartingCellEmpty = cells[colPos + 1] ? !cells[colPos + 1].getValue() : false,
20945
+ jumpCol = colPos,
20946
+ nextCell = this.findJumpCell(cells.slice(colPos + 1, cells.length), false, isStartingCellEmpty, isRightOfStartingCellEmpty);
20947
+
20948
+ if(nextCell){
20949
+ jumpCol = nextCell.column.getPosition() - 1;
20950
+ }
20951
+
20952
+ return jumpCol;
20953
+ }
20954
+
20955
+ findJumpCellUp(rowPos, colPos) {
20956
+ var column = this.getColumnByRangePos(colPos),
20957
+ cells = column.cells.filter((cell) => this.table.rowManager.activeRows.includes(cell.row)),
20958
+ isStartingCellEmpty = !cells[rowPos].getValue(),
20959
+ isTopOfStartingCellEmpty = cells[rowPos - 1] ? !cells[rowPos - 1].getValue() : false,
20960
+ jumpRow = rowPos,
20961
+ nextCell = this.findJumpCell(cells.slice(0, jumpRow), true, isStartingCellEmpty, isTopOfStartingCellEmpty);
20962
+
20963
+ if(nextCell){
20964
+ jumpRow = nextCell.row.position - 1;
20965
+ }
20966
+
20967
+ return jumpRow;
20968
+ }
20969
+
20970
+ findJumpCellDown(rowPos, colPos) {
20971
+ var column = this.getColumnByRangePos(colPos),
20972
+ cells = column.cells.filter((cell) => this.table.rowManager.activeRows.includes(cell.row)),
20973
+ isStartingCellEmpty = !cells[rowPos].getValue(),
20974
+ isBottomOfStartingCellEmpty = cells[rowPos + 1] ? !cells[rowPos + 1].getValue() : false,
20975
+ jumpRow = rowPos,
20976
+ nextCell = this.findJumpCell(cells.slice(jumpRow + 1, cells.length), false, isStartingCellEmpty, isBottomOfStartingCellEmpty);
20977
+
20978
+ if(nextCell){
20979
+ jumpRow = nextCell.row.position - 1;
20980
+ }
20981
+
20982
+ return jumpRow;
20983
+ }
20984
+
20985
+ ///////////////////////////////////
20986
+ /////// Selection ///////
20987
+ ///////////////////////////////////
20988
+ newSelection(event, element) {
20989
+ var range;
20990
+
20991
+ if (element.type === "column") {
20992
+ if(!this.columnSelection){
20993
+ return;
20994
+ }
20995
+
20996
+ if (element === this.rowHeader) {
20997
+ range = this.resetRanges();
20998
+ this.selecting = "all";
20999
+
21000
+ var topLeftCell, bottomRightCell = this.getCell(-1, -1);
21001
+
21002
+ if(this.rowHeader){
21003
+ topLeftCell = this.getCell(0, 1);
21004
+ }else {
21005
+ topLeftCell = this.getCell(0, 0);
21006
+ }
21007
+
21008
+ range.setBounds(topLeftCell, bottomRightCell);
21009
+ return;
21010
+ } else {
21011
+ this.selecting = "column";
21012
+ }
21013
+ } else if (element.column === this.rowHeader) {
21014
+ this.selecting = "row";
21015
+ } else {
21016
+ this.selecting = "cell";
21017
+ }
21018
+
21019
+ if (event.shiftKey) {
21020
+ this.activeRange.setBounds(false, element);
21021
+ } else if (event.ctrlKey) {
21022
+ this.addRange().setBounds(element);
21023
+ } else {
21024
+ this.resetRanges().setBounds(element);
21025
+ }
19544
21026
  }
21027
+
21028
+ autoScroll(range, row, column) {
21029
+ var tableHolder = this.table.rowManager.element,
21030
+ rowHeader, rect, view, withinHorizontalView, withinVerticalView;
19545
21031
 
19546
- //work through sort list sorting data
19547
- sort(data){
19548
- var self = this,
19549
- sortList = this.table.options.sortOrderReverse ? self.sortList.slice().reverse() : self.sortList,
19550
- sortListActual = [],
19551
- rowComponents = [];
19552
-
19553
- if(this.subscribedExternal("dataSorting")){
19554
- this.dispatchExternal("dataSorting", self.getSort());
21032
+ if (typeof row === 'undefined') {
21033
+ row = this.getRowByRangePos(range.end.row).getElement();
21034
+ }
21035
+
21036
+ if (typeof column === 'undefined') {
21037
+ column = this.getColumnByRangePos(range.end.col).getElement();
19555
21038
  }
19556
21039
 
19557
- self.clearColumnHeaders();
19558
-
19559
- if(this.table.options.sortMode !== "remote"){
19560
-
19561
- //build list of valid sorters and trigger column specific callbacks before sort begins
19562
- sortList.forEach(function(item, i){
19563
- var sortObj;
19564
-
19565
- if(item.column){
19566
- sortObj = item.column.modules.sort;
19567
-
19568
- if(sortObj){
19569
-
19570
- //if no sorter has been defined, take a guess
19571
- if(!sortObj.sorter){
19572
- sortObj.sorter = self.findSorter(item.column);
19573
- }
19574
-
19575
- item.params = typeof sortObj.params === "function" ? sortObj.params(item.column.getComponent(), item.dir) : sortObj.params;
19576
-
19577
- sortListActual.push(item);
19578
- }
21040
+ if (this.rowHeader) {
21041
+ rowHeader = this.rowHeader.getElement();
21042
+ }
21043
+
21044
+ rect = {
21045
+ left: column.offsetLeft,
21046
+ right: column.offsetLeft + column.offsetWidth,
21047
+ top: row.offsetTop,
21048
+ bottom: row.offsetTop + row.offsetHeight,
21049
+ };
21050
+
21051
+ view = {
21052
+ left: tableHolder.scrollLeft,
21053
+ right: Math.ceil(tableHolder.scrollLeft + tableHolder.clientWidth),
21054
+ top: tableHolder.scrollTop,
21055
+ bottom: tableHolder.scrollTop + tableHolder.offsetHeight - this.table.rowManager.scrollbarWidth,
21056
+ };
19579
21057
 
19580
- self.setColumnHeader(item.column, item.dir);
21058
+ if (rowHeader) {
21059
+ view.left += rowHeader.offsetWidth;
21060
+ }
21061
+
21062
+ withinHorizontalView = view.left < rect.left && rect.left < view.right && view.left < rect.right && rect.right < view.right;
21063
+
21064
+ withinVerticalView = view.top < rect.top && rect.top < view.bottom && view.top < rect.bottom && rect.bottom < view.bottom;
21065
+
21066
+ if (!withinHorizontalView) {
21067
+ if (rect.left < view.left) {
21068
+ tableHolder.scrollLeft = rect.left;
21069
+ if (rowHeader) {
21070
+ tableHolder.scrollLeft -= rowHeader.offsetWidth;
19581
21071
  }
19582
- });
19583
-
19584
- //sort data
19585
- if (sortListActual.length) {
19586
- self._sortItems(data, sortListActual);
21072
+ } else if (rect.right > view.right) {
21073
+ tableHolder.scrollLeft = rect.right - tableHolder.clientWidth;
19587
21074
  }
19588
-
19589
- }else {
19590
- sortList.forEach(function(item, i){
19591
- self.setColumnHeader(item.column, item.dir);
19592
- });
19593
21075
  }
19594
-
19595
- if(this.subscribedExternal("dataSorted")){
19596
- data.forEach((row) => {
19597
- rowComponents.push(row.getComponent());
19598
- });
19599
-
19600
- this.dispatchExternal("dataSorted", self.getSort(), rowComponents);
21076
+
21077
+ if (!withinVerticalView) {
21078
+ if (rect.top < view.top) {
21079
+ tableHolder.scrollTop = rect.top;
21080
+ } else if (rect.bottom > view.bottom) {
21081
+ tableHolder.scrollTop = rect.bottom - tableHolder.clientHeight;
21082
+ }
19601
21083
  }
19602
-
19603
- return data;
19604
21084
  }
19605
-
19606
- //clear sort arrows on columns
19607
- clearColumnHeaders(){
19608
- this.table.columnManager.getRealColumns().forEach((column) => {
19609
- if(column.modules.sort){
19610
- column.modules.sort.dir = "none";
19611
- column.getElement().setAttribute("aria-sort", "none");
19612
- this.setColumnHeaderSortIcon(column, "none");
21085
+
21086
+
21087
+ ///////////////////////////////////
21088
+ /////// Layout ///////
21089
+ ///////////////////////////////////
21090
+
21091
+ layoutChange(){
21092
+ this.overlay.style.visibility = "hidden";
21093
+ clearTimeout(this.layoutChangeTimeout);
21094
+ this.layoutChangeTimeout = setTimeout(this.layoutRanges.bind(this), 200);
21095
+ }
21096
+
21097
+ redraw(force) {
21098
+ if (force) {
21099
+ this.selecting = 'cell';
21100
+ this.resetRanges();
21101
+ this.layoutElement();
21102
+ }
21103
+ }
21104
+
21105
+ layoutElement(visibleRows) {
21106
+ var rows;
21107
+
21108
+ if (visibleRows) {
21109
+ rows = this.table.rowManager.getVisibleRows(true);
21110
+ } else {
21111
+ rows = this.table.rowManager.getRows();
21112
+ }
21113
+
21114
+ rows.forEach((row) => {
21115
+ if (row.type === "row") {
21116
+ this.layoutRow(row);
21117
+ row.cells.forEach((cell) => this.renderCell(cell));
19613
21118
  }
19614
21119
  });
21120
+
21121
+ this.getTableColumns().forEach((column) => {
21122
+ this.layoutColumn(column);
21123
+ });
21124
+
21125
+ this.layoutRanges();
19615
21126
  }
19616
-
19617
- //set the column header sort direction
19618
- setColumnHeader(column, dir){
19619
- column.modules.sort.dir = dir;
19620
- column.getElement().setAttribute("aria-sort", dir === "asc" ? "ascending" : "descending");
19621
- this.setColumnHeaderSortIcon(column, dir);
21127
+
21128
+ layoutRow(row) {
21129
+ var el = row.getElement(),
21130
+ selected = false,
21131
+ occupied = this.ranges.some((range) => range.occupiesRow(row));
21132
+
21133
+ if (this.selecting === "row") {
21134
+ selected = occupied;
21135
+ } else if (this.selecting === "all") {
21136
+ selected = true;
21137
+ }
21138
+
21139
+ el.classList.toggle("tabulator-range-selected", selected);
21140
+ el.classList.toggle("tabulator-range-highlight", occupied);
19622
21141
  }
19623
-
19624
- setColumnHeaderSortIcon(column, dir){
19625
- var sortEl = column.modules.sort.element,
19626
- arrowEl;
19627
-
19628
- if(column.definition.headerSort && typeof this.table.options.headerSortElement === "function"){
19629
- while(sortEl.firstChild) sortEl.removeChild(sortEl.firstChild);
19630
-
19631
- arrowEl = this.table.options.headerSortElement.call(this.table, column.getComponent(), dir);
19632
-
19633
- if(typeof arrowEl === "object"){
19634
- sortEl.appendChild(arrowEl);
19635
- }else {
19636
- sortEl.innerHTML = arrowEl;
21142
+
21143
+ layoutColumn(column) {
21144
+ var el = column.getElement(),
21145
+ selected = false,
21146
+ occupied = this.ranges.some((range) => range.occupiesColumn(column));
21147
+
21148
+ if (this.selecting === "column") {
21149
+ selected = occupied;
21150
+ } else if (this.selecting === "all") {
21151
+ selected = true;
21152
+ }
21153
+
21154
+ el.classList.toggle("tabulator-range-selected", selected);
21155
+ el.classList.toggle("tabulator-range-highlight", occupied);
21156
+ }
21157
+
21158
+ layoutRanges() {
21159
+ var activeCell;
21160
+
21161
+ if (!this.table.initialized) {
21162
+ return;
21163
+ }
21164
+
21165
+ activeCell = this.getActiveCell();
21166
+
21167
+ if (!activeCell) {
21168
+ return;
21169
+ }
21170
+
21171
+ this.activeRangeCellElement.style.left = activeCell.row.getElement().offsetLeft + activeCell.getElement().offsetLeft + "px";
21172
+ this.activeRangeCellElement.style.top = activeCell.row.getElement().offsetTop + "px";
21173
+ this.activeRangeCellElement.style.width = activeCell.getElement().offsetLeft + activeCell.getElement().offsetWidth - activeCell.getElement().offsetLeft + "px";
21174
+ this.activeRangeCellElement.style.height = activeCell.row.getElement().offsetTop + activeCell.row.getElement().offsetHeight - activeCell.row.getElement().offsetTop + "px";
21175
+
21176
+ this.ranges.forEach((range) => range.layout());
21177
+
21178
+ this.overlay.style.visibility = "visible";
21179
+ }
21180
+
21181
+
21182
+ ///////////////////////////////////
21183
+ /////// Helper Functions ///////
21184
+ ///////////////////////////////////
21185
+
21186
+ getCell(rowIdx, colIdx) {
21187
+ var row;
21188
+
21189
+ if (colIdx < 0) {
21190
+ colIdx = this.getTableColumns().length + colIdx;
21191
+ if (colIdx < 0) {
21192
+ return null;
19637
21193
  }
19638
21194
  }
21195
+
21196
+ if (rowIdx < 0) {
21197
+ rowIdx = this.getTableRows().length + rowIdx;
21198
+ }
21199
+
21200
+ row = this.table.rowManager.getRowFromPosition(rowIdx + 1);
21201
+
21202
+ return row ? row.getCells(false, true).filter((cell) => cell.column.visible)[colIdx] : null;
19639
21203
  }
21204
+
21205
+
21206
+ getActiveCell() {
21207
+ return this.getCell(this.activeRange.start.row, this.activeRange.start.col);
21208
+ }
21209
+
21210
+ getRowByRangePos(pos) {
21211
+ return this.getTableRows()[pos];
21212
+ }
21213
+
21214
+ getColumnByRangePos(pos) {
21215
+ return this.getTableColumns()[pos];
21216
+ }
21217
+
21218
+ getTableRows() {
21219
+ return this.table.rowManager.getDisplayRows();
21220
+ }
21221
+
21222
+ getTableColumns() {
21223
+ return this.table.columnManager.getVisibleColumnsByIndex();
21224
+ }
21225
+
21226
+ addRange(start, end) {
21227
+ var range;
21228
+
21229
+ if(this.maxRanges !== true && this.ranges.length >= this.maxRanges){
21230
+ this.ranges.shift().destroy();
21231
+ }
21232
+
21233
+ range = new Range(this.table, this, start, end);
21234
+
21235
+ this.activeRange = range;
21236
+ this.ranges.push(range);
21237
+ this.rangeContainer.appendChild(range.element);
21238
+
21239
+ return range;
21240
+ }
21241
+
21242
+ resetRanges() {
21243
+ var range, cell;
21244
+
21245
+ this.ranges.forEach((range) => range.destroy());
21246
+ this.ranges = [];
21247
+
21248
+ range = this.addRange();
21249
+
21250
+ if(this.table.rowManager.activeRows.length){
21251
+ cell = this.table.rowManager.activeRows[0].cells[this.rowHeader ? 1 : 0];
19640
21252
 
19641
- //sort each item in sort list
19642
- _sortItems(data, sortList){
19643
- var sorterCount = sortList.length - 1;
19644
-
19645
- data.sort((a, b) => {
19646
- var result;
19647
-
19648
- for(var i = sorterCount; i>= 0; i--){
19649
- let sortItem = sortList[i];
19650
-
19651
- result = this._sortRow(a, b, sortItem.column, sortItem.dir, sortItem.params);
19652
-
19653
- if(result !== 0){
19654
- break;
19655
- }
21253
+ if(cell){
21254
+ range.setBounds(cell);
21255
+ this.initializeFocus(cell);
19656
21256
  }
19657
-
19658
- return result;
19659
- });
21257
+ }
21258
+
21259
+ return range;
19660
21260
  }
19661
-
19662
- //process individual rows for a sort function on active data
19663
- _sortRow(a, b, column, dir, params){
19664
- var el1Comp, el2Comp;
19665
-
19666
- //switch elements depending on search direction
19667
- var el1 = dir == "asc" ? a : b;
19668
- var el2 = dir == "asc" ? b : a;
19669
-
19670
- a = column.getFieldValue(el1.getData());
19671
- b = column.getFieldValue(el2.getData());
19672
-
19673
- a = typeof a !== "undefined" ? a : "";
19674
- b = typeof b !== "undefined" ? b : "";
19675
-
19676
- el1Comp = el1.getComponent();
19677
- el2Comp = el2.getComponent();
19678
-
19679
- return column.modules.sort.sorter.call(this, a, b, el1Comp, el2Comp, column.getComponent(), dir, params);
21261
+
21262
+ tableDestroyed(){
21263
+ document.removeEventListener("mouseup", this.mouseUpEvent);
21264
+ this.table.rowManager.element.removeEventListener("keydown", this.keyDownEvent);
21265
+ }
21266
+
21267
+ selectedRows(component) {
21268
+ return component ? this.activeRange.getRows().map((row) => row.getComponent()) : this.activeRange.getRows();
21269
+ }
21270
+
21271
+ selectedColumns(component) {
21272
+ return component ? this.activeRange.getColumns().map((col) => col.getComponent()) : this.activeRange.getColumns();
19680
21273
  }
19681
21274
  }
19682
21275
 
19683
- Sort.moduleName = "sort";
19684
-
19685
- //load defaults
19686
- Sort.sorters = defaultSorters;
21276
+ SelectRange.moduleName = "selectRange";
19687
21277
 
19688
21278
  class Tooltip extends Module{
19689
21279
 
@@ -19850,6 +21440,17 @@ var defaultValidators = {
19850
21440
  return isNaN(value);
19851
21441
  },
19852
21442
 
21443
+ //must be alphanumeric
21444
+ alphanumeric: function(cell, value, parameters){
21445
+ if(value === "" || value === null || typeof value === "undefined"){
21446
+ return true;
21447
+ }
21448
+
21449
+ var reg = new RegExp(/^[a-z0-9]+$/i);
21450
+
21451
+ return reg.test(value);
21452
+ },
21453
+
19853
21454
  //maximum value
19854
21455
  max: function(cell, value, parameters){
19855
21456
  if(value === "" || value === null || typeof value === "undefined"){
@@ -20286,6 +21887,7 @@ var modules = /*#__PURE__*/Object.freeze({
20286
21887
  ResponsiveLayoutModule: ResponsiveLayout,
20287
21888
  SelectRowModule: SelectRow,
20288
21889
  SortModule: Sort,
21890
+ SelectRangeModule: SelectRange,
20289
21891
  TooltipModule: Tooltip,
20290
21892
  ValidateModule: Validate
20291
21893
  });
@@ -21610,6 +23212,10 @@ class ColumnManager extends CoreFeature {
21610
23212
 
21611
23213
  return index > -1 ? this.columnsByIndex[index] : false;
21612
23214
  }
23215
+
23216
+ getVisibleColumnsByIndex() {
23217
+ return this.columnsByIndex.filter((col) => col.visible);
23218
+ }
21613
23219
 
21614
23220
  getColumns(){
21615
23221
  return this.columns;
@@ -22009,8 +23615,6 @@ class BasicVertical extends Renderer{
22009
23615
  }
22010
23616
  });
22011
23617
 
22012
-
22013
-
22014
23618
  if(onlyGroupHeaders){
22015
23619
  element.style.minWidth = this.table.columnManager.getWidth() + "px";
22016
23620
  }else {
@@ -22027,6 +23631,10 @@ class BasicVertical extends Renderer{
22027
23631
  }
22028
23632
 
22029
23633
  this.renderRows();
23634
+
23635
+ if(!this.rows().length){
23636
+ this.table.rowManager.tableEmpty();
23637
+ }
22030
23638
  }
22031
23639
 
22032
23640
  scrollToRowNearestTop(row){
@@ -23020,7 +24628,7 @@ class RowManager extends CoreFeature{
23020
24628
 
23021
24629
  this.regenerateRowPositions();
23022
24630
 
23023
- if(rows.length){
24631
+ if(this.displayRowsCount){
23024
24632
  this._clearPlaceholder();
23025
24633
  }
23026
24634
 
@@ -23649,6 +25257,14 @@ class RowManager extends CoreFeature{
23649
25257
  this.renderEmptyScroll();
23650
25258
  this._showPlaceholder();
23651
25259
  }
25260
+
25261
+ checkPlaceholder(){
25262
+ if(this.displayRowsCount){
25263
+ this._clearPlaceholder();
25264
+ }else {
25265
+ this.tableEmpty();
25266
+ }
25267
+ }
23652
25268
 
23653
25269
  _showPlaceholder(){
23654
25270
  if(this.placeholder){
@@ -23777,13 +25393,11 @@ class RowManager extends CoreFeature{
23777
25393
 
23778
25394
  //redraw table
23779
25395
  redraw (force){
23780
- const resized = this.adjustTableSize();
25396
+ this.adjustTableSize();
23781
25397
  this.table.tableWidth = this.table.element.clientWidth;
23782
25398
 
23783
- if(!force){
23784
- if(resized) {
23785
- this.reRenderInPosition();
23786
- }
25399
+ if(!force){
25400
+ this.reRenderInPosition();
23787
25401
  this.scrollHorizontal(this.scrollLeft);
23788
25402
  }else {
23789
25403
  this.renderTable();
@@ -24130,11 +25744,11 @@ class InteractionManager extends CoreFeature {
24130
25744
  }
24131
25745
  }
24132
25746
  }
24133
-
25747
+
24134
25748
  if(targets.group && targets.group === targets.row){
24135
25749
  delete targets.row;
24136
25750
  }
24137
-
25751
+
24138
25752
  return targets;
24139
25753
  }
24140
25754
 
@@ -24666,7 +26280,7 @@ class DeprecationAdvisor extends CoreFeature{
24666
26280
  }
24667
26281
  }
24668
26282
 
24669
- check(oldOption, newOption){
26283
+ check(oldOption, newOption, convert){
24670
26284
  var msg = "";
24671
26285
 
24672
26286
  if(typeof this.options(oldOption) !== "undefined"){
@@ -24675,6 +26289,10 @@ class DeprecationAdvisor extends CoreFeature{
24675
26289
  if(newOption){
24676
26290
  msg = msg + ", Please use the %c" + newOption + "%c option instead";
24677
26291
  this._warnUser(msg, 'font-weight: bold;', 'font-weight: normal;', 'font-weight: bold;', 'font-weight: normal;');
26292
+
26293
+ if(convert){
26294
+ this.table.options[newOption] = this.table.options[oldOption];
26295
+ }
24678
26296
  }else {
24679
26297
  this._warnUser(msg, 'font-weight: bold;', 'font-weight: normal;');
24680
26298
  }
@@ -25463,6 +27081,8 @@ class Alert extends CoreFeature{
25463
27081
  alert(content, type = "msg"){
25464
27082
  if(content){
25465
27083
  this.clear();
27084
+
27085
+ this.dispatch("alert-show", type);
25466
27086
 
25467
27087
  this.type = type;
25468
27088
 
@@ -25485,6 +27105,8 @@ class Alert extends CoreFeature{
25485
27105
  }
25486
27106
 
25487
27107
  clear(){
27108
+ this.dispatch("alert-hide", this.type);
27109
+
25488
27110
  if(this.element.parentNode){
25489
27111
  this.element.parentNode.removeChild(this.element);
25490
27112
  }
@@ -25748,6 +27370,7 @@ class Tabulator {
25748
27370
 
25749
27371
  _loadInitialData(){
25750
27372
  this.dataLoader.load(this.options.data);
27373
+ this.columnManager.verticalAlignHeaders();
25751
27374
  }
25752
27375
 
25753
27376
  //deconstructor
@@ -26300,7 +27923,7 @@ class Tabulator {
26300
27923
  this.options.height = isNaN(height) ? height : height + "px";
26301
27924
  this.element.style.height = this.options.height;
26302
27925
  this.rowManager.initializeRenderer();
26303
- this.rowManager.redraw();
27926
+ this.rowManager.redraw(true);
26304
27927
  }
26305
27928
 
26306
27929
  //////////////////// Event Bus ///////////////////
@@ -26414,7 +28037,9 @@ class PseudoRow {
26414
28037
  setCellHeight(){}
26415
28038
 
26416
28039
  clearCellHeight(){}
28040
+
28041
+ rendered(){}
26417
28042
  }
26418
28043
 
26419
- export { Accessor as AccessorModule, Ajax as AjaxModule, CalcComponent, CellComponent, Clipboard as ClipboardModule, ColumnCalcs as ColumnCalcsModule, ColumnComponent, DataTree as DataTreeModule, Download as DownloadModule, Edit$1 as EditModule, Export as ExportModule, Filter as FilterModule, Format as FormatModule, FrozenColumns as FrozenColumnsModule, FrozenRows as FrozenRowsModule, GroupComponent, GroupRows as GroupRowsModule, History as HistoryModule, HtmlTableImport as HtmlTableImportModule, Import as ImportModule, Interaction as InteractionModule, Keybindings as KeybindingsModule, Menu as MenuModule, Module, MoveColumns as MoveColumnsModule, MoveRows as MoveRowsModule, Mutator as MutatorModule, Page as PageModule, Persistence as PersistenceModule, Popup$1 as PopupModule, Print as PrintModule, PseudoRow, ReactiveData as ReactiveDataModule, Renderer, ResizeColumns as ResizeColumnsModule, ResizeRows as ResizeRowsModule, ResizeTable as ResizeTableModule, ResponsiveLayout as ResponsiveLayoutModule, RowComponent, SelectRow as SelectRowModule, Sort as SortModule, Tabulator, TabulatorFull, Tooltip as TooltipModule, Validate as ValidateModule };
28044
+ export { Accessor as AccessorModule, Ajax as AjaxModule, CalcComponent, CellComponent, Clipboard as ClipboardModule, ColumnCalcs as ColumnCalcsModule, ColumnComponent, DataTree as DataTreeModule, Download as DownloadModule, Edit$1 as EditModule, Export as ExportModule, Filter as FilterModule, Format as FormatModule, FrozenColumns as FrozenColumnsModule, FrozenRows as FrozenRowsModule, GroupComponent, GroupRows as GroupRowsModule, History as HistoryModule, HtmlTableImport as HtmlTableImportModule, Import as ImportModule, Interaction as InteractionModule, Keybindings as KeybindingsModule, Menu as MenuModule, Module, MoveColumns as MoveColumnsModule, MoveRows as MoveRowsModule, Mutator as MutatorModule, Page as PageModule, Persistence as PersistenceModule, Popup$1 as PopupModule, Print as PrintModule, PseudoRow, ReactiveData as ReactiveDataModule, Renderer, ResizeColumns as ResizeColumnsModule, ResizeRows as ResizeRowsModule, ResizeTable as ResizeTableModule, ResponsiveLayout as ResponsiveLayoutModule, RowComponent, SelectRange as SelectRangeModule, SelectRow as SelectRowModule, Sort as SortModule, Tabulator, TabulatorFull, Tooltip as TooltipModule, Validate as ValidateModule };
26420
28045
  //# sourceMappingURL=tabulator_esm.js.map