tabulator-tables 6.5.0 → 6.5.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 (222) hide show
  1. package/dist/js/tabulator.js +1 -1
  2. package/dist/js/tabulator.min.js +1 -1
  3. package/dist/js/tabulator_esm.js +1 -1
  4. package/dist/js/tabulator_esm.min.js +1 -1
  5. package/dist/js/tabulator_esm.min.mjs +1 -1
  6. package/dist/js/tabulator_esm.mjs +1 -1
  7. package/package.json +2 -1
  8. package/src/js/builds/esm.js +16 -0
  9. package/src/js/builds/jquery_wrapper.js +63 -0
  10. package/src/js/builds/usd.js +1 -0
  11. package/src/js/core/ColumnManager.js +789 -0
  12. package/src/js/core/CoreFeature.js +140 -0
  13. package/src/js/core/FooterManager.js +102 -0
  14. package/src/js/core/Module.js +140 -0
  15. package/src/js/core/RowManager.js +1140 -0
  16. package/src/js/core/Tabulator.js +928 -0
  17. package/src/js/core/TabulatorFull.js +21 -0
  18. package/src/js/core/cell/Cell.js +299 -0
  19. package/src/js/core/cell/CellComponent.js +79 -0
  20. package/src/js/core/column/Column.js +978 -0
  21. package/src/js/core/column/ColumnComponent.js +151 -0
  22. package/src/js/core/column/defaults/options.js +18 -0
  23. package/src/js/core/defaults/options.js +66 -0
  24. package/src/js/core/modules/core.js +3 -0
  25. package/src/js/core/modules/optional.js +37 -0
  26. package/src/js/core/rendering/Renderer.js +204 -0
  27. package/src/js/core/rendering/renderers/BasicHorizontal.js +27 -0
  28. package/src/js/core/rendering/renderers/BasicVertical.js +103 -0
  29. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +587 -0
  30. package/src/js/core/rendering/renderers/VirtualDomVertical.js +642 -0
  31. package/src/js/core/row/PseudoRow.js +47 -0
  32. package/src/js/core/row/Row.js +487 -0
  33. package/src/js/core/row/RowComponent.js +94 -0
  34. package/src/js/core/tools/Alert.js +66 -0
  35. package/src/js/core/tools/ComponentFunctionBinder.js +32 -0
  36. package/src/js/core/tools/DataLoader.js +128 -0
  37. package/src/js/core/tools/DependencyRegistry.js +82 -0
  38. package/src/js/core/tools/DeprecationAdvisor.js +51 -0
  39. package/src/js/core/tools/ExternalEventBus.js +105 -0
  40. package/src/js/core/tools/Helpers.js +66 -0
  41. package/src/js/core/tools/InteractionMonitor.js +329 -0
  42. package/src/js/core/tools/InternalEventBus.js +162 -0
  43. package/src/js/core/tools/ModuleBinder.js +153 -0
  44. package/src/js/core/tools/OptionsList.js +45 -0
  45. package/src/js/core/tools/Popup.js +317 -0
  46. package/src/js/core/tools/TableRegistry.js +65 -0
  47. package/src/js/modules/Accessor/Accessor.js +115 -0
  48. package/src/js/modules/Accessor/defaults/accessors.js +5 -0
  49. package/src/js/modules/Ajax/Ajax.js +142 -0
  50. package/src/js/modules/Ajax/defaults/config.js +3 -0
  51. package/src/js/modules/Ajax/defaults/contentTypeFormatters.js +45 -0
  52. package/src/js/modules/Ajax/defaults/loaderPromise.js +87 -0
  53. package/src/js/modules/Ajax/defaults/urlGenerator.js +44 -0
  54. package/src/js/modules/Clipboard/Clipboard.js +282 -0
  55. package/src/js/modules/Clipboard/defaults/pasteActions.js +11 -0
  56. package/src/js/modules/Clipboard/defaults/pasteParsers.js +75 -0
  57. package/src/js/modules/Clipboard/extensions/extensions.js +9 -0
  58. package/src/js/modules/Clipboard/extensions/keybindings/actions.js +9 -0
  59. package/src/js/modules/Clipboard/extensions/keybindings/bindings.js +3 -0
  60. package/src/js/modules/ColumnCalcs/CalcComponent.js +46 -0
  61. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +586 -0
  62. package/src/js/modules/ColumnCalcs/defaults/calculations.js +93 -0
  63. package/src/js/modules/Comms/Comms.js +49 -0
  64. package/src/js/modules/DataTree/DataTree.js +620 -0
  65. package/src/js/modules/Download/Download.js +146 -0
  66. package/src/js/modules/Download/defaults/downloaders/csv.js +61 -0
  67. package/src/js/modules/Download/defaults/downloaders/html.js +5 -0
  68. package/src/js/modules/Download/defaults/downloaders/json.js +34 -0
  69. package/src/js/modules/Download/defaults/downloaders/jsonLines.js +32 -0
  70. package/src/js/modules/Download/defaults/downloaders/pdf.js +113 -0
  71. package/src/js/modules/Download/defaults/downloaders/xlsx.js +103 -0
  72. package/src/js/modules/Download/defaults/downloaders.js +15 -0
  73. package/src/js/modules/Edit/Edit.js +845 -0
  74. package/src/js/modules/Edit/List.js +1060 -0
  75. package/src/js/modules/Edit/defaults/editors/adaptable.js +37 -0
  76. package/src/js/modules/Edit/defaults/editors/date.js +144 -0
  77. package/src/js/modules/Edit/defaults/editors/datetime.js +131 -0
  78. package/src/js/modules/Edit/defaults/editors/input.js +77 -0
  79. package/src/js/modules/Edit/defaults/editors/list.js +7 -0
  80. package/src/js/modules/Edit/defaults/editors/number.js +110 -0
  81. package/src/js/modules/Edit/defaults/editors/progress.js +127 -0
  82. package/src/js/modules/Edit/defaults/editors/range.js +81 -0
  83. package/src/js/modules/Edit/defaults/editors/star.js +146 -0
  84. package/src/js/modules/Edit/defaults/editors/textarea.js +123 -0
  85. package/src/js/modules/Edit/defaults/editors/tickCross.js +95 -0
  86. package/src/js/modules/Edit/defaults/editors/time.js +132 -0
  87. package/src/js/modules/Edit/defaults/editors.js +27 -0
  88. package/src/js/modules/Edit/inputMask.js +74 -0
  89. package/src/js/modules/Export/Export.js +654 -0
  90. package/src/js/modules/Export/ExportColumn.js +9 -0
  91. package/src/js/modules/Export/ExportRow.js +8 -0
  92. package/src/js/modules/Export/defaults/columnLookups.js +3 -0
  93. package/src/js/modules/Export/defaults/rowLookups.js +18 -0
  94. package/src/js/modules/Filter/Filter.js +902 -0
  95. package/src/js/modules/Filter/defaults/filters.js +215 -0
  96. package/src/js/modules/Format/Format.js +200 -0
  97. package/src/js/modules/Format/defaults/formatters/adaptable.js +32 -0
  98. package/src/js/modules/Format/defaults/formatters/array.js +30 -0
  99. package/src/js/modules/Format/defaults/formatters/buttonCross.js +3 -0
  100. package/src/js/modules/Format/defaults/formatters/buttonTick.js +3 -0
  101. package/src/js/modules/Format/defaults/formatters/color.js +4 -0
  102. package/src/js/modules/Format/defaults/formatters/datetime.js +39 -0
  103. package/src/js/modules/Format/defaults/formatters/datetimediff.js +43 -0
  104. package/src/js/modules/Format/defaults/formatters/handle.js +4 -0
  105. package/src/js/modules/Format/defaults/formatters/html.js +3 -0
  106. package/src/js/modules/Format/defaults/formatters/image.js +40 -0
  107. package/src/js/modules/Format/defaults/formatters/json.js +12 -0
  108. package/src/js/modules/Format/defaults/formatters/link.js +82 -0
  109. package/src/js/modules/Format/defaults/formatters/lookup.js +10 -0
  110. package/src/js/modules/Format/defaults/formatters/money.js +44 -0
  111. package/src/js/modules/Format/defaults/formatters/plaintext.js +3 -0
  112. package/src/js/modules/Format/defaults/formatters/progress.js +133 -0
  113. package/src/js/modules/Format/defaults/formatters/rownum.js +14 -0
  114. package/src/js/modules/Format/defaults/formatters/star.js +38 -0
  115. package/src/js/modules/Format/defaults/formatters/textarea.js +4 -0
  116. package/src/js/modules/Format/defaults/formatters/tickCross.js +22 -0
  117. package/src/js/modules/Format/defaults/formatters/toggle.js +48 -0
  118. package/src/js/modules/Format/defaults/formatters/traffic.js +47 -0
  119. package/src/js/modules/Format/defaults/formatters.js +47 -0
  120. package/src/js/modules/FrozenColumns/FrozenColumns.js +302 -0
  121. package/src/js/modules/FrozenRows/FrozenRows.js +175 -0
  122. package/src/js/modules/GroupRows/Group.js +615 -0
  123. package/src/js/modules/GroupRows/GroupComponent.js +69 -0
  124. package/src/js/modules/GroupRows/GroupRows.js +636 -0
  125. package/src/js/modules/History/History.js +172 -0
  126. package/src/js/modules/History/defaults/redoers.js +31 -0
  127. package/src/js/modules/History/defaults/undoers.js +33 -0
  128. package/src/js/modules/History/extensions/extensions.js +9 -0
  129. package/src/js/modules/History/extensions/keybindings/actions.js +27 -0
  130. package/src/js/modules/History/extensions/keybindings/bindings.js +4 -0
  131. package/src/js/modules/HtmlTableImport/HtmlTableImport.js +180 -0
  132. package/src/js/modules/Import/Import.js +303 -0
  133. package/src/js/modules/Import/defaults/importers/array.js +3 -0
  134. package/src/js/modules/Import/defaults/importers/csv.js +61 -0
  135. package/src/js/modules/Import/defaults/importers/json.js +8 -0
  136. package/src/js/modules/Import/defaults/importers/xlsx.js +7 -0
  137. package/src/js/modules/Import/defaults/importers.js +11 -0
  138. package/src/js/modules/Interaction/Interaction.js +339 -0
  139. package/src/js/modules/Keybindings/Keybindings.js +198 -0
  140. package/src/js/modules/Keybindings/defaults/actions.js +90 -0
  141. package/src/js/modules/Keybindings/defaults/bindings.js +12 -0
  142. package/src/js/modules/Layout/Layout.js +66 -0
  143. package/src/js/modules/Layout/defaults/modes/fitColumns.js +171 -0
  144. package/src/js/modules/Layout/defaults/modes/fitData.js +10 -0
  145. package/src/js/modules/Layout/defaults/modes/fitDataGeneral.js +10 -0
  146. package/src/js/modules/Layout/defaults/modes/fitDataStretch.js +40 -0
  147. package/src/js/modules/Layout/defaults/modes.js +12 -0
  148. package/src/js/modules/Localize/Localize.js +184 -0
  149. package/src/js/modules/Localize/defaults/langs.js +37 -0
  150. package/src/js/modules/Menu/Menu.js +302 -0
  151. package/src/js/modules/MoveColumns/MoveColumns.js +311 -0
  152. package/src/js/modules/MoveRows/MoveRows.js +604 -0
  153. package/src/js/modules/MoveRows/defaults/receivers.js +30 -0
  154. package/src/js/modules/MoveRows/defaults/senders.js +5 -0
  155. package/src/js/modules/Mutator/Mutator.js +164 -0
  156. package/src/js/modules/Mutator/defaults/mutators.js +1 -0
  157. package/src/js/modules/Page/Page.js +891 -0
  158. package/src/js/modules/Page/defaults/pageCounters/pages.js +33 -0
  159. package/src/js/modules/Page/defaults/pageCounters/rows.js +40 -0
  160. package/src/js/modules/Page/defaults/pageCounters.js +8 -0
  161. package/src/js/modules/Persistence/Persistence.js +473 -0
  162. package/src/js/modules/Persistence/defaults/readers.js +29 -0
  163. package/src/js/modules/Persistence/defaults/writers.js +13 -0
  164. package/src/js/modules/Popup/Popup.js +227 -0
  165. package/src/js/modules/Print/Print.js +136 -0
  166. package/src/js/modules/ReactiveData/ReactiveData.js +416 -0
  167. package/src/js/modules/ResizeColumns/ResizeColumns.js +365 -0
  168. package/src/js/modules/ResizeRows/ResizeRows.js +145 -0
  169. package/src/js/modules/ResizeTable/ResizeTable.js +158 -0
  170. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +354 -0
  171. package/src/js/modules/ResponsiveLayout/extensions/extensions.js +9 -0
  172. package/src/js/modules/ResponsiveLayout/extensions/formatters/responsiveCollapse.js +44 -0
  173. package/src/js/modules/SelectRange/Range.js +366 -0
  174. package/src/js/modules/SelectRange/RangeComponent.js +91 -0
  175. package/src/js/modules/SelectRange/SelectRange.js +993 -0
  176. package/src/js/modules/SelectRange/extensions/clipboard/pasteActions.js +45 -0
  177. package/src/js/modules/SelectRange/extensions/clipboard/pasteParsers.js +57 -0
  178. package/src/js/modules/SelectRange/extensions/export/columnLookups.js +11 -0
  179. package/src/js/modules/SelectRange/extensions/export/rowLookups.js +5 -0
  180. package/src/js/modules/SelectRange/extensions/extensions.js +21 -0
  181. package/src/js/modules/SelectRange/extensions/keybindings/actions.js +38 -0
  182. package/src/js/modules/SelectRange/extensions/keybindings/bindings.js +14 -0
  183. package/src/js/modules/SelectRow/SelectRow.js +499 -0
  184. package/src/js/modules/SelectRow/extensions/extensions.js +9 -0
  185. package/src/js/modules/SelectRow/extensions/formatters/rowSelection.js +60 -0
  186. package/src/js/modules/Sort/Sort.js +480 -0
  187. package/src/js/modules/Sort/defaults/sorters/alphanum.js +44 -0
  188. package/src/js/modules/Sort/defaults/sorters/array.js +82 -0
  189. package/src/js/modules/Sort/defaults/sorters/boolean.js +7 -0
  190. package/src/js/modules/Sort/defaults/sorters/date.js +10 -0
  191. package/src/js/modules/Sort/defaults/sorters/datetime.js +48 -0
  192. package/src/js/modules/Sort/defaults/sorters/exists.js +7 -0
  193. package/src/js/modules/Sort/defaults/sorters/number.js +40 -0
  194. package/src/js/modules/Sort/defaults/sorters/string.js +34 -0
  195. package/src/js/modules/Sort/defaults/sorters/time.js +10 -0
  196. package/src/js/modules/Sort/defaults/sorters.js +21 -0
  197. package/src/js/modules/Spreadsheet/GridCalculator.js +64 -0
  198. package/src/js/modules/Spreadsheet/Sheet.js +243 -0
  199. package/src/js/modules/Spreadsheet/SheetComponent.js +59 -0
  200. package/src/js/modules/Spreadsheet/Spreadsheet.js +309 -0
  201. package/src/js/modules/Tooltip/Tooltip.js +128 -0
  202. package/src/js/modules/Validate/Validate.js +303 -0
  203. package/src/js/modules/Validate/defaults/validators.js +150 -0
  204. package/src/scss/tabulator.scss +1693 -0
  205. package/src/scss/themes/bootstrap/tabulator_bootstrap3.scss +302 -0
  206. package/src/scss/themes/bootstrap/tabulator_bootstrap4.scss +589 -0
  207. package/src/scss/themes/bootstrap/tabulator_bootstrap5.scss +979 -0
  208. package/src/scss/themes/bootstrap/variables3.scss +872 -0
  209. package/src/scss/themes/bootstrap/variables4.scss +1059 -0
  210. package/src/scss/themes/bootstrap/variables5.scss +1967 -0
  211. package/src/scss/themes/bulma/tabulator_bulma.scss +316 -0
  212. package/src/scss/themes/bulma/variables.scss +198 -0
  213. package/src/scss/themes/materialize/tabulator_materialize.scss +318 -0
  214. package/src/scss/themes/materialize/variables.scss +71 -0
  215. package/src/scss/themes/semanticui/tabulator_semanticui.scss +623 -0
  216. package/src/scss/themes/semanticui/variables.scss +843 -0
  217. package/src/scss/themes/semanticui/variables_table.scss +248 -0
  218. package/src/scss/themes/tabulator_midnight.scss +235 -0
  219. package/src/scss/themes/tabulator_modern.scss +308 -0
  220. package/src/scss/themes/tabulator_simple.scss +143 -0
  221. package/src/scss/themes/tabulator_site.scss +267 -0
  222. package/src/scss/themes/tabulator_site_dark.scss +496 -0
@@ -0,0 +1,845 @@
1
+ import Module from '../../core/Module.js';
2
+ import Helpers from '../../core/tools/Helpers.js';
3
+
4
+ import defaultEditors from './defaults/editors.js';
5
+
6
+ export default class Edit extends Module{
7
+
8
+ static moduleName = "edit";
9
+
10
+ //load defaults
11
+ static editors = defaultEditors;
12
+
13
+ constructor(table){
14
+ super(table);
15
+
16
+ this.currentCell = false; //hold currently editing cell
17
+ this.mouseClick = false; //hold mousedown state to prevent click binding being overridden by editor opening
18
+ this.recursionBlock = false; //prevent focus recursion
19
+ this.invalidEdit = false;
20
+ this.editedCells = [];
21
+ this.convertEmptyValues = false;
22
+
23
+ this.editors = Edit.editors;
24
+
25
+ this.registerTableOption("editTriggerEvent", "focus");
26
+ this.registerTableOption("editorEmptyValue");
27
+ this.registerTableOption("editorEmptyValueFunc", this.emptyValueCheck.bind(this));
28
+
29
+ this.registerColumnOption("editable");
30
+ this.registerColumnOption("editor");
31
+ this.registerColumnOption("editorParams");
32
+ this.registerColumnOption("editorEmptyValue");
33
+ this.registerColumnOption("editorEmptyValueFunc");
34
+
35
+ this.registerColumnOption("cellEditing");
36
+ this.registerColumnOption("cellEdited");
37
+ this.registerColumnOption("cellEditCancelled");
38
+
39
+ this.registerTableFunction("getEditedCells", this.getEditedCells.bind(this));
40
+ this.registerTableFunction("clearCellEdited", this.clearCellEdited.bind(this));
41
+ this.registerTableFunction("navigatePrev", this.navigatePrev.bind(this));
42
+ this.registerTableFunction("navigateNext", this.navigateNext.bind(this));
43
+ this.registerTableFunction("navigateLeft", this.navigateLeft.bind(this));
44
+ this.registerTableFunction("navigateRight", this.navigateRight.bind(this));
45
+ this.registerTableFunction("navigateUp", this.navigateUp.bind(this));
46
+ this.registerTableFunction("navigateDown", this.navigateDown.bind(this));
47
+
48
+ this.registerComponentFunction("cell", "isEdited", this.cellIsEdited.bind(this));
49
+ this.registerComponentFunction("cell", "clearEdited", this.clearEdited.bind(this));
50
+ this.registerComponentFunction("cell", "edit", this.editCell.bind(this));
51
+ this.registerComponentFunction("cell", "cancelEdit", this.cellCancelEdit.bind(this));
52
+
53
+ this.registerComponentFunction("cell", "navigatePrev", this.navigatePrev.bind(this));
54
+ this.registerComponentFunction("cell", "navigateNext", this.navigateNext.bind(this));
55
+ this.registerComponentFunction("cell", "navigateLeft", this.navigateLeft.bind(this));
56
+ this.registerComponentFunction("cell", "navigateRight", this.navigateRight.bind(this));
57
+ this.registerComponentFunction("cell", "navigateUp", this.navigateUp.bind(this));
58
+ this.registerComponentFunction("cell", "navigateDown", this.navigateDown.bind(this));
59
+ }
60
+
61
+ initialize(){
62
+ this.subscribe("cell-init", this.bindEditor.bind(this));
63
+ this.subscribe("cell-delete", this.clearEdited.bind(this));
64
+ this.subscribe("cell-value-changed", this.updateCellClass.bind(this));
65
+ this.subscribe("column-layout", this.initializeColumnCheck.bind(this));
66
+ this.subscribe("column-delete", this.columnDeleteCheck.bind(this));
67
+ this.subscribe("row-deleting", this.rowDeleteCheck.bind(this));
68
+ this.subscribe("row-layout", this.rowEditableCheck.bind(this));
69
+ this.subscribe("data-refreshing", this.cancelEdit.bind(this));
70
+ this.subscribe("clipboard-paste", this.pasteBlocker.bind(this));
71
+
72
+ if (!this.confirm("edit-nav-disabled")) {
73
+ this.subscribe("keybinding-nav-prev", this.navigatePrev.bind(this, undefined));
74
+ this.subscribe("keybinding-nav-next", this.keybindingNavigateNext.bind(this));
75
+
76
+ // this.subscribe("keybinding-nav-left", this.navigateLeft.bind(this, undefined));
77
+ // this.subscribe("keybinding-nav-right", this.navigateRight.bind(this, undefined));
78
+ this.subscribe("keybinding-nav-up", this.navigateUp.bind(this, undefined));
79
+ this.subscribe("keybinding-nav-down", this.navigateDown.bind(this, undefined));
80
+ }
81
+
82
+ // Add event handlers for other modules to access editing state and functionality
83
+ this.subscribe("edit-check-editing", this.checkEditing.bind(this));
84
+ this.subscribe("edit-cancel-cell", this.cancelEditEvent.bind(this));
85
+
86
+ if(Object.keys(this.table.options).includes("editorEmptyValue")){
87
+ this.convertEmptyValues = true;
88
+ }
89
+ }
90
+
91
+
92
+ ///////////////////////////////////
93
+ ///////// Paste Negation //////////
94
+ ///////////////////////////////////
95
+
96
+ pasteBlocker(e){
97
+ if(this.currentCell){
98
+ return true;
99
+ }
100
+ }
101
+
102
+
103
+ ///////////////////////////////////
104
+ ////// Keybinding Functions ///////
105
+ ///////////////////////////////////
106
+
107
+ keybindingNavigateNext(e){
108
+ var cell = this.currentCell,
109
+ newRow = this.options("tabEndNewRow");
110
+
111
+ if(cell){
112
+ if(!this.navigateNext(cell, e)){
113
+ if(newRow){
114
+ cell.getElement().firstChild.blur();
115
+
116
+ if(!this.invalidEdit){
117
+
118
+ if(newRow === true){
119
+ newRow = this.table.addRow({});
120
+ }else{
121
+ if(typeof newRow == "function"){
122
+ newRow = this.table.addRow(newRow(cell.row.getComponent()));
123
+ }else{
124
+ newRow = this.table.addRow(Object.assign({}, newRow));
125
+ }
126
+ }
127
+
128
+ newRow.then(() => {
129
+ setTimeout(() => {
130
+ cell.getComponent().navigateNext();
131
+ });
132
+ });
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+
139
+ ///////////////////////////////////
140
+ ///////// Cell Functions //////////
141
+ ///////////////////////////////////
142
+
143
+ cellIsEdited(cell){
144
+ return !! cell.modules.edit && cell.modules.edit.edited;
145
+ }
146
+
147
+ cellCancelEdit(cell){
148
+ if(cell === this.currentCell){
149
+ this.table.modules.edit.cancelEdit();
150
+ }else{
151
+ console.warn("Cancel Editor Error - This cell is not currently being edited ");
152
+ }
153
+ }
154
+
155
+
156
+ ///////////////////////////////////
157
+ ///////// Table Functions /////////
158
+ ///////////////////////////////////
159
+ updateCellClass(cell){
160
+ if(this.allowEdit(cell)) {
161
+ cell.getElement().classList.add("tabulator-editable");
162
+ }
163
+ else {
164
+ cell.getElement().classList.remove("tabulator-editable");
165
+ }
166
+ }
167
+
168
+ clearCellEdited(cells){
169
+ if(!cells){
170
+ cells = this.table.modules.edit.getEditedCells();
171
+ }
172
+
173
+ if(!Array.isArray(cells)){
174
+ cells = [cells];
175
+ }
176
+
177
+ cells.forEach((cell) => {
178
+ this.table.modules.edit.clearEdited(cell._getSelf());
179
+ });
180
+ }
181
+
182
+ navigatePrev(cell = this.currentCell, e){
183
+ var nextCell, prevRow;
184
+
185
+ if(cell){
186
+
187
+ if(e){
188
+ e.preventDefault();
189
+ }
190
+
191
+ nextCell = this.navigateLeft();
192
+
193
+ if(nextCell){
194
+ return true;
195
+ }else{
196
+ prevRow = this.table.rowManager.prevDisplayRow(cell.row, true);
197
+
198
+ if(prevRow){
199
+ nextCell = this.findPrevEditableCell(prevRow, prevRow.cells.length);
200
+
201
+ if(nextCell){
202
+ nextCell.getComponent().edit();
203
+ return true;
204
+ }
205
+ }
206
+ }
207
+ }
208
+
209
+ return false;
210
+ }
211
+
212
+ navigateNext(cell = this.currentCell, e){
213
+ var nextCell, nextRow;
214
+
215
+ if(cell){
216
+
217
+ if(e){
218
+ e.preventDefault();
219
+ }
220
+
221
+ nextCell = this.navigateRight();
222
+
223
+ if(nextCell){
224
+ return true;
225
+ }else{
226
+ nextRow = this.table.rowManager.nextDisplayRow(cell.row, true);
227
+
228
+ if(nextRow){
229
+ nextCell = this.findNextEditableCell(nextRow, -1);
230
+
231
+ if(nextCell){
232
+ nextCell.getComponent().edit();
233
+ return true;
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ return false;
240
+ }
241
+
242
+ navigateLeft(cell = this.currentCell, e){
243
+ var index, nextCell;
244
+
245
+ if(cell){
246
+
247
+ if(e){
248
+ e.preventDefault();
249
+ }
250
+
251
+ index = cell.getIndex();
252
+ nextCell = this.findPrevEditableCell(cell.row, index);
253
+
254
+ if(nextCell){
255
+ nextCell.getComponent().edit();
256
+ return true;
257
+ }
258
+ }
259
+
260
+ return false;
261
+ }
262
+
263
+ navigateRight(cell = this.currentCell, e){
264
+ var index, nextCell;
265
+
266
+ if(cell){
267
+
268
+ if(e){
269
+ e.preventDefault();
270
+ }
271
+
272
+ index = cell.getIndex();
273
+ nextCell = this.findNextEditableCell(cell.row, index);
274
+
275
+ if(nextCell){
276
+ nextCell.getComponent().edit();
277
+ return true;
278
+ }
279
+ }
280
+
281
+ return false;
282
+ }
283
+
284
+ navigateUp(cell = this.currentCell, e){
285
+ var index, nextRow;
286
+
287
+ if(cell){
288
+
289
+ if(e){
290
+ e.preventDefault();
291
+ }
292
+
293
+ index = cell.getIndex();
294
+ nextRow = this.table.rowManager.prevDisplayRow(cell.row, true);
295
+
296
+ if(nextRow){
297
+ nextRow.cells[index].getComponent().edit();
298
+ return true;
299
+ }
300
+ }
301
+
302
+ return false;
303
+ }
304
+
305
+ navigateDown(cell = this.currentCell, e){
306
+ var index, nextRow;
307
+
308
+ if(cell){
309
+
310
+ if(e){
311
+ e.preventDefault();
312
+ }
313
+
314
+ index = cell.getIndex();
315
+ nextRow = this.table.rowManager.nextDisplayRow(cell.row, true);
316
+
317
+ if(nextRow){
318
+ nextRow.cells[index].getComponent().edit();
319
+ return true;
320
+ }
321
+ }
322
+
323
+ return false;
324
+ }
325
+
326
+ findNextEditableCell(row, index){
327
+ var nextCell = false;
328
+
329
+ if(index < row.cells.length-1){
330
+ for(var i = index+1; i < row.cells.length; i++){
331
+ let cell = row.cells[i];
332
+
333
+ if(cell.column.modules.edit && Helpers.elVisible(cell.getElement())){
334
+ let allowEdit = this.allowEdit(cell);
335
+
336
+ if(allowEdit){
337
+ nextCell = cell;
338
+ break;
339
+ }
340
+ }
341
+ }
342
+ }
343
+
344
+ return nextCell;
345
+ }
346
+
347
+ findPrevEditableCell(row, index){
348
+ var prevCell = false;
349
+
350
+ if(index > 0){
351
+ for(var i = index-1; i >= 0; i--){
352
+ let cell = row.cells[i];
353
+
354
+ if(cell.column.modules.edit && Helpers.elVisible(cell.getElement())){
355
+ let allowEdit = this.allowEdit(cell);
356
+
357
+ if(allowEdit){
358
+ prevCell = cell;
359
+ break;
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ return prevCell;
366
+ }
367
+
368
+ ///////////////////////////////////
369
+ ///////// Internal Logic //////////
370
+ ///////////////////////////////////
371
+
372
+ initializeColumnCheck(column){
373
+ if(typeof column.definition.editor !== "undefined"){
374
+ this.initializeColumn(column);
375
+ }
376
+ }
377
+
378
+ columnDeleteCheck(column){
379
+ if(this.currentCell && this.currentCell.column === column){
380
+ this.cancelEdit();
381
+ }
382
+ }
383
+
384
+ rowDeleteCheck(row){
385
+ if(this.currentCell && this.currentCell.row === row){
386
+ this.cancelEdit();
387
+ }
388
+ }
389
+
390
+ rowEditableCheck(row){
391
+ row.getCells().forEach((cell) => {
392
+ if(cell.column.modules.edit && typeof cell.column.modules.edit.check === "function"){
393
+ this.updateCellClass(cell);
394
+ }
395
+ });
396
+ }
397
+
398
+ //initialize column editor
399
+ initializeColumn(column){
400
+ var convertEmpty = Object.keys(column.definition).includes("editorEmptyValue");
401
+
402
+ var config = {
403
+ editor:false,
404
+ blocked:false,
405
+ check:column.definition.editable,
406
+ params:column.definition.editorParams || {},
407
+ convertEmptyValues:convertEmpty,
408
+ editorEmptyValue:column.definition.editorEmptyValue,
409
+ editorEmptyValueFunc:column.definition.editorEmptyValueFunc,
410
+ };
411
+
412
+ //set column editor
413
+ config.editor = this.lookupEditor(column.definition.editor, column);
414
+
415
+ if(config.editor){
416
+ column.modules.edit = config;
417
+ }
418
+ }
419
+
420
+ lookupEditor(editor, column){
421
+ var editorFunc;
422
+
423
+ switch(typeof editor){
424
+ case "string":
425
+ if(this.editors[editor]){
426
+ editorFunc = this.editors[editor];
427
+ }else{
428
+ console.warn("Editor Error - No such editor found: ", editor);
429
+ }
430
+ break;
431
+
432
+ case "function":
433
+ editorFunc = editor;
434
+ break;
435
+
436
+ case "boolean":
437
+ if(editor === true){
438
+ if(typeof column.definition.formatter !== "function"){
439
+ if(this.editors[column.definition.formatter]){
440
+ editorFunc = this.editors[column.definition.formatter];
441
+ }else{
442
+ editorFunc = this.editors["input"];
443
+ }
444
+ }else{
445
+ console.warn("Editor Error - Cannot auto lookup editor for a custom formatter: ", column.definition.formatter);
446
+ }
447
+ }
448
+ break;
449
+ }
450
+
451
+ return editorFunc;
452
+ }
453
+
454
+ getCurrentCell(){
455
+ return this.currentCell ? this.currentCell.getComponent() : false;
456
+ }
457
+
458
+ checkEditing(){
459
+ return !!this.currentCell;
460
+ }
461
+
462
+ cancelEditEvent(){
463
+ if(this.currentCell){
464
+ this.cancelEdit();
465
+ return true;
466
+ }
467
+ return false;
468
+ }
469
+
470
+
471
+ clearEditor(cancel){
472
+ var cell = this.currentCell,
473
+ cellEl;
474
+
475
+ this.invalidEdit = false;
476
+
477
+ if(cell){
478
+ this.currentCell = false;
479
+
480
+ cellEl = cell.getElement();
481
+
482
+ this.dispatch("edit-editor-clear", cell, cancel);
483
+
484
+ cellEl.classList.remove("tabulator-editing");
485
+
486
+ while(cellEl.firstChild) cellEl.removeChild(cellEl.firstChild);
487
+
488
+ cell.row.getElement().classList.remove("tabulator-editing");
489
+
490
+ cell.table.element.classList.remove("tabulator-editing");
491
+ }
492
+ }
493
+
494
+ cancelEdit(){
495
+ if(this.currentCell){
496
+ var cell = this.currentCell;
497
+ var component = this.currentCell.getComponent();
498
+
499
+ this.clearEditor(true);
500
+ cell.setValueActual(cell.getValue());
501
+ cell.cellRendered();
502
+
503
+ if(cell.column.definition.editor == "textarea" || cell.column.definition.variableHeight){
504
+ cell.row.normalizeHeight(true);
505
+ }
506
+
507
+ if(cell.column.definition.cellEditCancelled){
508
+ cell.column.definition.cellEditCancelled.call(this.table, component);
509
+ }
510
+
511
+ this.dispatch("edit-cancelled", cell);
512
+ this.dispatchExternal("cellEditCancelled", component);
513
+ }
514
+ }
515
+
516
+ //return a formatted value for a cell
517
+ bindEditor(cell){
518
+ if(cell.column.modules.edit){
519
+ var self = this,
520
+ element = cell.getElement(true);
521
+
522
+ this.updateCellClass(cell);
523
+ element.setAttribute("tabindex", 0);
524
+
525
+ element.addEventListener("mousedown", function(e){
526
+ if (e.button === 2) {
527
+ e.preventDefault();
528
+ }else{
529
+ self.mouseClick = true;
530
+ }
531
+ });
532
+
533
+ if(this.options("editTriggerEvent") === "dblclick"){
534
+ element.addEventListener("dblclick", function(e){
535
+ if(!element.classList.contains("tabulator-editing")){
536
+ element.focus({preventScroll: true});
537
+ self.edit(cell, e, false);
538
+ }
539
+ });
540
+ }
541
+
542
+
543
+ if(this.options("editTriggerEvent") === "focus" || this.options("editTriggerEvent") === "click"){
544
+ element.addEventListener("click", function(e){
545
+ if(!element.classList.contains("tabulator-editing")){
546
+ element.focus({preventScroll: true});
547
+ self.edit(cell, e, false);
548
+ }
549
+ });
550
+ }
551
+
552
+ if(this.options("editTriggerEvent") === "focus"){
553
+ element.addEventListener("focus", function(e){
554
+ if(!self.recursionBlock){
555
+ self.edit(cell, e, false);
556
+ }
557
+ });
558
+ }
559
+ }
560
+ }
561
+
562
+ focusCellNoEvent(cell, block){
563
+ this.recursionBlock = true;
564
+
565
+ if(!(block && this.table.browser === "ie")){
566
+ cell.getElement().focus({preventScroll: true});
567
+ }
568
+
569
+ this.recursionBlock = false;
570
+ }
571
+
572
+ editCell(cell, forceEdit){
573
+ this.focusCellNoEvent(cell);
574
+ this.edit(cell, false, forceEdit);
575
+ }
576
+
577
+ focusScrollAdjust(cell){
578
+ if(this.table.rowManager.getRenderMode() == "virtual"){
579
+ var topEdge = this.table.rowManager.element.scrollTop,
580
+ bottomEdge = this.table.rowManager.element.clientHeight + this.table.rowManager.element.scrollTop,
581
+ rowEl = cell.row.getElement();
582
+
583
+ if(rowEl.offsetTop < topEdge){
584
+ this.table.rowManager.element.scrollTop -= (topEdge - rowEl.offsetTop);
585
+ }else{
586
+ if(rowEl.offsetTop + rowEl.offsetHeight > bottomEdge){
587
+ this.table.rowManager.element.scrollTop += (rowEl.offsetTop + rowEl.offsetHeight - bottomEdge);
588
+ }
589
+ }
590
+
591
+ var leftEdge = this.table.rowManager.element.scrollLeft,
592
+ rightEdge = this.table.rowManager.element.clientWidth + this.table.rowManager.element.scrollLeft,
593
+ cellEl = cell.getElement();
594
+
595
+ if(this.table.modExists("frozenColumns")){
596
+ leftEdge += parseInt(this.table.modules.frozenColumns.leftMargin || 0);
597
+ rightEdge -= parseInt(this.table.modules.frozenColumns.rightMargin || 0);
598
+ }
599
+
600
+ if(this.table.options.renderHorizontal === "virtual"){
601
+ leftEdge -= parseInt(this.table.columnManager.renderer.vDomPadLeft);
602
+ rightEdge -= parseInt(this.table.columnManager.renderer.vDomPadLeft);
603
+ }
604
+
605
+ if(cellEl.offsetLeft < leftEdge){
606
+ this.table.rowManager.element.scrollLeft -= (leftEdge - cellEl.offsetLeft);
607
+ }else{
608
+ if(cellEl.offsetLeft + cellEl.offsetWidth > rightEdge){
609
+ this.table.rowManager.element.scrollLeft += (cellEl.offsetLeft + cellEl.offsetWidth - rightEdge);
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ allowEdit(cell) {
616
+ var check = cell.column.modules.edit ? true : false;
617
+
618
+ if(cell.column.modules.edit){
619
+ switch(typeof cell.column.modules.edit.check){
620
+ case "function":
621
+ if(cell.row.initialized){
622
+ check = cell.column.modules.edit.check(cell.getComponent());
623
+ }
624
+ break;
625
+
626
+ case "string":
627
+ check = !!cell.row.data[cell.column.modules.edit.check];
628
+ break;
629
+
630
+ case "boolean":
631
+ check = cell.column.modules.edit.check;
632
+ break;
633
+ }
634
+ }
635
+
636
+ return check;
637
+ }
638
+
639
+ edit(cell, e, forceEdit){
640
+ var self = this,
641
+ allowEdit = true,
642
+ rendered = function(){},
643
+ element = cell.getElement(),
644
+ editFinished = false,
645
+ cellEditor, component, params;
646
+
647
+ //prevent editing if another cell is refusing to leave focus (eg. validation fail)
648
+
649
+ if(this.currentCell){
650
+ if(!this.invalidEdit && this.currentCell !== cell){
651
+ this.cancelEdit();
652
+ }
653
+ return;
654
+ }
655
+
656
+ //handle successful value change
657
+ function success(value){
658
+ if(self.currentCell === cell && !editFinished){
659
+ var valid = self.chain("edit-success", [cell, value], true, true);
660
+
661
+ if(valid === true || self.table.options.validationMode === "highlight"){
662
+
663
+ editFinished = true;
664
+
665
+ self.clearEditor();
666
+
667
+ if(!cell.modules.edit){
668
+ cell.modules.edit = {};
669
+ }
670
+
671
+ cell.modules.edit.edited = true;
672
+
673
+ if(self.editedCells.indexOf(cell) == -1){
674
+ self.editedCells.push(cell);
675
+ }
676
+
677
+ value = self.transformEmptyValues(value, cell);
678
+
679
+ cell.setValue(value, true);
680
+
681
+ return valid === true;
682
+ }else{
683
+ editFinished = true;
684
+ self.invalidEdit = true;
685
+ self.focusCellNoEvent(cell, true);
686
+ rendered();
687
+
688
+ setTimeout(() => {
689
+ editFinished = false;
690
+ }, 10);
691
+ return false;
692
+ }
693
+ }else{
694
+ // console.warn("Edit Success Error - cannot call success on a cell that is no longer being edited");
695
+ }
696
+ }
697
+
698
+ //handle aborted edit
699
+ function cancel(){
700
+ // editFinished = true;
701
+
702
+ if(self.currentCell === cell && !editFinished){
703
+ self.cancelEdit();
704
+ }else{
705
+ // console.warn("Edit Success Error - cannot call cancel on a cell that is no longer being edited");
706
+ }
707
+ }
708
+
709
+ function onRendered(callback){
710
+ rendered = callback;
711
+ }
712
+
713
+ if(!cell.column.modules.edit.blocked){
714
+ allowEdit = this.allowEdit(cell);
715
+
716
+ if(allowEdit || forceEdit){
717
+ //only stop event propagation once we know the cell will be edited,
718
+ //otherwise non-editable cells would swallow clicks meant for other
719
+ //handlers such as the cellClick callback (#4421)
720
+ if(e){
721
+ e.stopPropagation();
722
+ }
723
+
724
+ self.cancelEdit();
725
+
726
+ self.currentCell = cell;
727
+
728
+ this.focusScrollAdjust(cell);
729
+
730
+ component = cell.getComponent();
731
+
732
+ if(this.mouseClick){
733
+ this.mouseClick = false;
734
+
735
+ if(cell.column.definition.cellClick){
736
+ cell.column.definition.cellClick.call(this.table, e, component);
737
+ }
738
+ }
739
+
740
+ if(cell.column.definition.cellEditing){
741
+ cell.column.definition.cellEditing.call(this.table, component);
742
+ }
743
+
744
+ this.dispatch("cell-editing", cell);
745
+ this.dispatchExternal("cellEditing", component);
746
+
747
+ params = typeof cell.column.modules.edit.params === "function" ? cell.column.modules.edit.params(component) : cell.column.modules.edit.params;
748
+
749
+ cellEditor = cell.column.modules.edit.editor.call(self, component, onRendered, success, cancel, params);
750
+
751
+ //if editor returned, add to DOM, if false, abort edit
752
+ if(this.currentCell && cellEditor !== false){
753
+ if(cellEditor instanceof Node){
754
+ element.classList.add("tabulator-editing");
755
+ cell.row.getElement().classList.add("tabulator-editing");
756
+ cell.table.element.classList.add("tabulator-editing");
757
+ while(element.firstChild) element.removeChild(element.firstChild);
758
+ element.appendChild(cellEditor);
759
+
760
+ //trigger onRendered Callback
761
+ rendered();
762
+
763
+ //prevent editing from triggering rowClick event
764
+ var children = element.children;
765
+
766
+ for (var i = 0; i < children.length; i++) {
767
+ children[i].addEventListener("click", function(e){
768
+ e.stopPropagation();
769
+ });
770
+ }
771
+ }else{
772
+ console.warn("Edit Error - Editor should return an instance of Node, the editor returned:", cellEditor);
773
+ this.blur(element);
774
+ return false;
775
+ }
776
+ }else{
777
+ this.blur(element);
778
+ return false;
779
+ }
780
+
781
+ return true;
782
+ }else{
783
+ this.mouseClick = false;
784
+ this.blur(element);
785
+ return false;
786
+ }
787
+ }else{
788
+ this.mouseClick = false;
789
+ this.blur(element);
790
+ return false;
791
+ }
792
+ }
793
+
794
+ emptyValueCheck(value){
795
+ return value === "" || value === null || typeof value === "undefined";
796
+ }
797
+
798
+ transformEmptyValues(value, cell){
799
+ var mod = cell.column.modules.edit,
800
+ convert = mod.convertEmptyValues || this.convertEmptyValues,
801
+ checkFunc;
802
+
803
+ if(convert){
804
+ checkFunc = mod.editorEmptyValueFunc || this.options("editorEmptyValueFunc");
805
+
806
+ if(checkFunc && checkFunc(value)){
807
+ value = mod.convertEmptyValues ? mod.editorEmptyValue : this.options("editorEmptyValue");
808
+ }
809
+ }
810
+
811
+ return value;
812
+ }
813
+
814
+ blur(element){
815
+ if(!this.confirm("edit-blur", [element]) ){
816
+ element.blur();
817
+ }
818
+ }
819
+
820
+ getEditedCells(){
821
+ var output = [];
822
+
823
+ this.editedCells.forEach((cell) => {
824
+ output.push(cell.getComponent());
825
+ });
826
+
827
+ return output;
828
+ }
829
+
830
+ clearEdited(cell){
831
+ var editIndex;
832
+
833
+ if(cell.modules.edit && cell.modules.edit.edited){
834
+ cell.modules.edit.edited = false;
835
+
836
+ this.dispatch("edit-edited-clear", cell);
837
+ }
838
+
839
+ editIndex = this.editedCells.indexOf(cell);
840
+
841
+ if(editIndex > -1){
842
+ this.editedCells.splice(editIndex, 1);
843
+ }
844
+ }
845
+ }