tabulator-tables 5.4.2 → 5.4.4

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 (253) hide show
  1. package/.babelrc.json +3 -3
  2. package/.editorconfig +6 -6
  3. package/.eslintignore +3 -3
  4. package/.eslintrc.js +28 -28
  5. package/.github/ISSUE_TEMPLATE/bug_report.md +58 -58
  6. package/.github/ISSUE_TEMPLATE/documentation.md +14 -14
  7. package/.github/ISSUE_TEMPLATE/feature_request.md +24 -24
  8. package/.github/ISSUE_TEMPLATE/question.md +12 -12
  9. package/.github/workflows/bad-files-check.yml +39 -39
  10. package/.github/workflows/lint-and-test.yml +30 -30
  11. package/CODE_OF_CONDUCT.md +46 -46
  12. package/CONTRIBUTING.md +22 -22
  13. package/LICENSE +20 -20
  14. package/README.md +76 -76
  15. package/bower.json +40 -40
  16. package/build/Bundler.js +185 -185
  17. package/build/rollup.js +6 -6
  18. package/dist/css/tabulator.css +1 -5
  19. package/dist/css/tabulator.css.map +1 -1
  20. package/dist/css/tabulator.min.css +1 -1
  21. package/dist/css/tabulator.min.css.map +1 -1
  22. package/dist/css/tabulator_bootstrap3.css +1 -5
  23. package/dist/css/tabulator_bootstrap3.css.map +1 -1
  24. package/dist/css/tabulator_bootstrap3.min.css +1 -1
  25. package/dist/css/tabulator_bootstrap3.min.css.map +1 -1
  26. package/dist/css/tabulator_bootstrap4.css +1 -5
  27. package/dist/css/tabulator_bootstrap4.css.map +1 -1
  28. package/dist/css/tabulator_bootstrap4.min.css +1 -1
  29. package/dist/css/tabulator_bootstrap4.min.css.map +1 -1
  30. package/dist/css/tabulator_bootstrap5.css +1 -5
  31. package/dist/css/tabulator_bootstrap5.css.map +1 -1
  32. package/dist/css/tabulator_bootstrap5.min.css +1 -1
  33. package/dist/css/tabulator_bootstrap5.min.css.map +1 -1
  34. package/dist/css/tabulator_bulma.css +1 -5
  35. package/dist/css/tabulator_bulma.css.map +1 -1
  36. package/dist/css/tabulator_bulma.min.css +1 -1
  37. package/dist/css/tabulator_bulma.min.css.map +1 -1
  38. package/dist/css/tabulator_materialize.css +1 -5
  39. package/dist/css/tabulator_materialize.css.map +1 -1
  40. package/dist/css/tabulator_materialize.min.css +1 -1
  41. package/dist/css/tabulator_materialize.min.css.map +1 -1
  42. package/dist/css/tabulator_midnight.css +1 -5
  43. package/dist/css/tabulator_midnight.css.map +1 -1
  44. package/dist/css/tabulator_midnight.min.css +1 -1
  45. package/dist/css/tabulator_midnight.min.css.map +1 -1
  46. package/dist/css/tabulator_modern.css +1 -5
  47. package/dist/css/tabulator_modern.css.map +1 -1
  48. package/dist/css/tabulator_modern.min.css +1 -1
  49. package/dist/css/tabulator_modern.min.css.map +1 -1
  50. package/dist/css/tabulator_semanticui.css +103 -107
  51. package/dist/css/tabulator_semanticui.css.map +1 -1
  52. package/dist/css/tabulator_semanticui.min.css +1 -1
  53. package/dist/css/tabulator_semanticui.min.css.map +1 -1
  54. package/dist/css/tabulator_simple.css +1 -5
  55. package/dist/css/tabulator_simple.css.map +1 -1
  56. package/dist/css/tabulator_simple.min.css +1 -1
  57. package/dist/css/tabulator_simple.min.css.map +1 -1
  58. package/dist/css/tabulator_site.css +1 -5
  59. package/dist/css/tabulator_site.css.map +1 -1
  60. package/dist/css/tabulator_site.min.css +1 -1
  61. package/dist/css/tabulator_site.min.css.map +1 -1
  62. package/dist/js/jquery_wrapper.js +55 -55
  63. package/dist/js/tabulator.js +25847 -25653
  64. package/dist/js/tabulator.js.map +1 -1
  65. package/dist/js/tabulator.min.js +2 -2
  66. package/dist/js/tabulator.min.js.map +1 -1
  67. package/dist/js/tabulator_esm.js +25926 -25732
  68. package/dist/js/tabulator_esm.js.map +1 -1
  69. package/dist/js/tabulator_esm.min.js +2 -2
  70. package/dist/js/tabulator_esm.min.js.map +1 -1
  71. package/package.json +65 -65
  72. package/src/js/builds/esm.js +14 -14
  73. package/src/js/builds/jquery_wrapper.js +55 -55
  74. package/src/js/core/ColumnManager.js +730 -730
  75. package/src/js/core/CoreFeature.js +138 -138
  76. package/src/js/core/FooterManager.js +101 -101
  77. package/src/js/core/Module.js +141 -141
  78. package/src/js/core/RowManager.js +1112 -1082
  79. package/src/js/core/Tabulator.js +895 -893
  80. package/src/js/core/TabulatorFull.js +10 -10
  81. package/src/js/core/cell/Cell.js +295 -295
  82. package/src/js/core/cell/CellComponent.js +76 -76
  83. package/src/js/core/column/Column.js +949 -949
  84. package/src/js/core/column/ColumnComponent.js +152 -152
  85. package/src/js/core/column/defaults/options.js +17 -17
  86. package/src/js/core/defaults/options.js +65 -65
  87. package/src/js/core/modules/core.js +2 -2
  88. package/src/js/core/modules/optional.js +34 -34
  89. package/src/js/core/rendering/Renderer.js +203 -203
  90. package/src/js/core/rendering/renderers/BasicHorizontal.js +19 -19
  91. package/src/js/core/rendering/renderers/BasicVertical.js +79 -78
  92. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +577 -577
  93. package/src/js/core/rendering/renderers/VirtualDomVertical.js +579 -579
  94. package/src/js/core/row/PseudoRow.js +44 -44
  95. package/src/js/core/row/Row.js +457 -457
  96. package/src/js/core/row/RowComponent.js +93 -93
  97. package/src/js/core/tools/Alert.js +61 -61
  98. package/src/js/core/tools/ComponentFunctionBinder.js +32 -32
  99. package/src/js/core/tools/DataLoader.js +119 -119
  100. package/src/js/core/tools/DeprecationAdvisor.js +46 -46
  101. package/src/js/core/tools/ExternalEventBus.js +104 -104
  102. package/src/js/core/tools/Helpers.js +46 -46
  103. package/src/js/core/tools/InteractionMonitor.js +321 -321
  104. package/src/js/core/tools/InternalEventBus.js +161 -161
  105. package/src/js/core/tools/ModuleBinder.js +104 -104
  106. package/src/js/core/tools/OptionsList.js +44 -40
  107. package/src/js/core/tools/Popup.js +304 -304
  108. package/src/js/core/tools/TableRegistry.js +61 -61
  109. package/src/js/modules/Accessor/Accessor.js +115 -115
  110. package/src/js/modules/Ajax/Ajax.js +143 -143
  111. package/src/js/modules/Ajax/defaults/config.js +2 -2
  112. package/src/js/modules/Ajax/defaults/contentTypeFormatters.js +44 -44
  113. package/src/js/modules/Ajax/defaults/loaderPromise.js +86 -86
  114. package/src/js/modules/Ajax/defaults/urlGenerator.js +43 -43
  115. package/src/js/modules/Clipboard/Clipboard.js +279 -279
  116. package/src/js/modules/Clipboard/defaults/pasteActions.js +10 -10
  117. package/src/js/modules/Clipboard/defaults/pasteParsers.js +74 -74
  118. package/src/js/modules/ColumnCalcs/CalcComponent.js +47 -47
  119. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +581 -568
  120. package/src/js/modules/ColumnCalcs/defaults/calculations.js +85 -85
  121. package/src/js/modules/Comms/Comms.js +51 -51
  122. package/src/js/modules/DataTree/DataTree.js +603 -603
  123. package/src/js/modules/Download/Download.js +148 -148
  124. package/src/js/modules/Download/defaults/downloaders/csv.js +61 -61
  125. package/src/js/modules/Download/defaults/downloaders/html.js +4 -4
  126. package/src/js/modules/Download/defaults/downloaders/json.js +33 -33
  127. package/src/js/modules/Download/defaults/downloaders/jsonLines.js +31 -31
  128. package/src/js/modules/Download/defaults/downloaders/pdf.js +111 -111
  129. package/src/js/modules/Download/defaults/downloaders/xlsx.js +98 -98
  130. package/src/js/modules/Download/defaults/downloaders.js +14 -14
  131. package/src/js/modules/Edit/Edit.js +735 -736
  132. package/src/js/modules/Edit/List.js +1037 -1033
  133. package/src/js/modules/Edit/defaults/editors/autocomplete.js +11 -11
  134. package/src/js/modules/Edit/defaults/editors/date.js +138 -110
  135. package/src/js/modules/Edit/defaults/editors/datetime.js +125 -97
  136. package/src/js/modules/Edit/defaults/editors/input.js +76 -74
  137. package/src/js/modules/Edit/defaults/editors/list.js +6 -6
  138. package/src/js/modules/Edit/defaults/editors/number.js +109 -107
  139. package/src/js/modules/Edit/defaults/editors/progress.js +126 -126
  140. package/src/js/modules/Edit/defaults/editors/range.js +80 -78
  141. package/src/js/modules/Edit/defaults/editors/select.js +9 -9
  142. package/src/js/modules/Edit/defaults/editors/star.js +145 -145
  143. package/src/js/modules/Edit/defaults/editors/textarea.js +122 -120
  144. package/src/js/modules/Edit/defaults/editors/tickCross.js +94 -96
  145. package/src/js/modules/Edit/defaults/editors/time.js +126 -98
  146. package/src/js/modules/Edit/defaults/editors.js +28 -28
  147. package/src/js/modules/Edit/inputMask.js +73 -73
  148. package/src/js/modules/Export/Export.js +623 -617
  149. package/src/js/modules/Export/ExportColumn.js +10 -10
  150. package/src/js/modules/Export/ExportRow.js +9 -9
  151. package/src/js/modules/Filter/Filter.js +892 -889
  152. package/src/js/modules/Filter/defaults/filters.js +107 -107
  153. package/src/js/modules/Format/Format.js +212 -212
  154. package/src/js/modules/Format/defaults/formatters/buttonCross.js +2 -2
  155. package/src/js/modules/Format/defaults/formatters/buttonTick.js +2 -2
  156. package/src/js/modules/Format/defaults/formatters/color.js +3 -3
  157. package/src/js/modules/Format/defaults/formatters/datetime.js +36 -36
  158. package/src/js/modules/Format/defaults/formatters/datetimediff.js +40 -40
  159. package/src/js/modules/Format/defaults/formatters/handle.js +3 -3
  160. package/src/js/modules/Format/defaults/formatters/html.js +2 -2
  161. package/src/js/modules/Format/defaults/formatters/image.js +39 -39
  162. package/src/js/modules/Format/defaults/formatters/link.js +77 -77
  163. package/src/js/modules/Format/defaults/formatters/lookup.js +9 -9
  164. package/src/js/modules/Format/defaults/formatters/money.js +36 -36
  165. package/src/js/modules/Format/defaults/formatters/plaintext.js +2 -2
  166. package/src/js/modules/Format/defaults/formatters/progress.js +132 -132
  167. package/src/js/modules/Format/defaults/formatters/responsiveCollapse.js +43 -43
  168. package/src/js/modules/Format/defaults/formatters/rowSelection.js +59 -59
  169. package/src/js/modules/Format/defaults/formatters/rownum.js +9 -9
  170. package/src/js/modules/Format/defaults/formatters/star.js +37 -37
  171. package/src/js/modules/Format/defaults/formatters/textarea.js +3 -3
  172. package/src/js/modules/Format/defaults/formatters/tickCross.js +21 -21
  173. package/src/js/modules/Format/defaults/formatters/traffic.js +46 -46
  174. package/src/js/modules/Format/defaults/formatters.js +42 -42
  175. package/src/js/modules/FrozenColumns/FrozenColumns.js +299 -299
  176. package/src/js/modules/FrozenRows/FrozenRows.js +169 -159
  177. package/src/js/modules/GroupRows/Group.js +597 -595
  178. package/src/js/modules/GroupRows/GroupComponent.js +66 -66
  179. package/src/js/modules/GroupRows/GroupRows.js +639 -623
  180. package/src/js/modules/History/History.js +171 -171
  181. package/src/js/modules/History/defaults/redoers.js +24 -24
  182. package/src/js/modules/History/defaults/undoers.js +24 -24
  183. package/src/js/modules/HtmlTableImport/HtmlTableImport.js +181 -181
  184. package/src/js/modules/Import/Import.js +193 -193
  185. package/src/js/modules/Import/defaults/importers/array.js +4 -4
  186. package/src/js/modules/Import/defaults/importers/csv.js +62 -62
  187. package/src/js/modules/Import/defaults/importers/json.js +7 -7
  188. package/src/js/modules/Import/defaults/importers.js +8 -8
  189. package/src/js/modules/Interaction/Interaction.js +325 -325
  190. package/src/js/modules/Keybindings/Keybindings.js +172 -172
  191. package/src/js/modules/Keybindings/defaults/actions.js +118 -118
  192. package/src/js/modules/Keybindings/defaults/bindings.js +12 -12
  193. package/src/js/modules/Layout/Layout.js +49 -49
  194. package/src/js/modules/Layout/defaults/modes/fitColumns.js +171 -171
  195. package/src/js/modules/Layout/defaults/modes/fitData.js +9 -9
  196. package/src/js/modules/Layout/defaults/modes/fitDataGeneral.js +9 -9
  197. package/src/js/modules/Layout/defaults/modes/fitDataStretch.js +39 -39
  198. package/src/js/modules/Layout/defaults/modes.js +11 -11
  199. package/src/js/modules/Localize/Localize.js +185 -194
  200. package/src/js/modules/Localize/defaults/langs.js +36 -36
  201. package/src/js/modules/Menu/Menu.js +302 -302
  202. package/src/js/modules/MoveColumns/MoveColumns.js +299 -299
  203. package/src/js/modules/MoveRows/MoveRows.js +635 -635
  204. package/src/js/modules/Mutator/Mutator.js +161 -161
  205. package/src/js/modules/Page/Page.js +881 -881
  206. package/src/js/modules/Page/defaults/pageCounters/pages.js +32 -32
  207. package/src/js/modules/Page/defaults/pageCounters/rows.js +39 -39
  208. package/src/js/modules/Page/defaults/pageCounters.js +7 -7
  209. package/src/js/modules/Persistence/Persistence.js +458 -458
  210. package/src/js/modules/Persistence/defaults/readers.js +29 -29
  211. package/src/js/modules/Persistence/defaults/writers.js +12 -12
  212. package/src/js/modules/Popup/Popup.js +231 -231
  213. package/src/js/modules/Print/Print.js +137 -124
  214. package/src/js/modules/ReactiveData/ReactiveData.js +408 -408
  215. package/src/js/modules/ResizeColumns/ResizeColumns.js +309 -309
  216. package/src/js/modules/ResizeRows/ResizeRows.js +111 -111
  217. package/src/js/modules/ResizeTable/ResizeTable.js +159 -159
  218. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +345 -345
  219. package/src/js/modules/SelectRow/SelectRow.js +446 -436
  220. package/src/js/modules/Sort/Sort.js +470 -470
  221. package/src/js/modules/Sort/defaults/sorters/alphanum.js +43 -43
  222. package/src/js/modules/Sort/defaults/sorters/array.js +53 -53
  223. package/src/js/modules/Sort/defaults/sorters/boolean.js +6 -6
  224. package/src/js/modules/Sort/defaults/sorters/date.js +9 -9
  225. package/src/js/modules/Sort/defaults/sorters/datetime.js +43 -43
  226. package/src/js/modules/Sort/defaults/sorters/exists.js +6 -6
  227. package/src/js/modules/Sort/defaults/sorters/number.js +39 -39
  228. package/src/js/modules/Sort/defaults/sorters/string.js +33 -33
  229. package/src/js/modules/Sort/defaults/sorters/time.js +9 -9
  230. package/src/js/modules/Sort/defaults/sorters.js +20 -20
  231. package/src/js/modules/Tooltip/Tooltip.js +130 -130
  232. package/src/js/modules/Validate/Validate.js +305 -305
  233. package/src/js/modules/Validate/defaults/validators.js +138 -138
  234. package/src/scss/tabulator.scss +1464 -1466
  235. package/src/scss/themes/bootstrap/functions4.scss +118 -118
  236. package/src/scss/themes/bootstrap/functions5.scss +302 -302
  237. package/src/scss/themes/bootstrap/tabulator_bootstrap3.scss +284 -284
  238. package/src/scss/themes/bootstrap/tabulator_bootstrap4.scss +544 -544
  239. package/src/scss/themes/bootstrap/tabulator_bootstrap5.scss +574 -574
  240. package/src/scss/themes/bootstrap/variables3.scss +870 -870
  241. package/src/scss/themes/bootstrap/variables4.scss +930 -930
  242. package/src/scss/themes/bootstrap/variables5.scss +1641 -1641
  243. package/src/scss/themes/bulma/tabulator_bulma.scss +252 -252
  244. package/src/scss/themes/bulma/variables.scss +197 -197
  245. package/src/scss/themes/materialize/tabulator_materialize.scss +265 -265
  246. package/src/scss/themes/materialize/variables.scss +70 -70
  247. package/src/scss/themes/semanticui/tabulator_semanticui.scss +561 -561
  248. package/src/scss/themes/semanticui/variables.scss +839 -839
  249. package/src/scss/themes/semanticui/variables_table.scss +247 -247
  250. package/src/scss/themes/tabulator_midnight.scss +158 -158
  251. package/src/scss/themes/tabulator_modern.scss +231 -231
  252. package/src/scss/themes/tabulator_simple.scss +102 -102
  253. package/src/scss/themes/tabulator_site.scss +189 -189
@@ -1,604 +1,604 @@
1
- import Module from '../../core/Module.js';
2
-
3
- import Row from '../../core/row/Row.js';
4
-
5
- import RowComponent from '../../core/row/RowComponent.js';
6
-
7
- class DataTree extends Module{
8
-
9
- constructor(table){
10
- super(table);
11
-
12
- this.indent = 10;
13
- this.field = "";
14
- this.collapseEl = null;
15
- this.expandEl = null;
16
- this.branchEl = null;
17
- this.elementField = false;
18
-
19
- this.startOpen = function(){};
20
-
21
- this.registerTableOption("dataTree", false); //enable data tree
22
- this.registerTableOption("dataTreeFilter", true); //filter child rows
23
- this.registerTableOption("dataTreeSort", true); //sort child rows
24
- this.registerTableOption("dataTreeElementColumn", false);
25
- this.registerTableOption("dataTreeBranchElement", true);//show data tree branch element
26
- this.registerTableOption("dataTreeChildIndent", 9); //data tree child indent in px
27
- this.registerTableOption("dataTreeChildField", "_children");//data tre column field to look for child rows
28
- this.registerTableOption("dataTreeCollapseElement", false);//data tree row collapse element
29
- this.registerTableOption("dataTreeExpandElement", false);//data tree row expand element
30
- this.registerTableOption("dataTreeStartExpanded", false);
31
- this.registerTableOption("dataTreeChildColumnCalcs", false);//include visible data tree rows in column calculations
32
- this.registerTableOption("dataTreeSelectPropagate", false);//selecting a parent row selects its children
33
-
34
- //register component functions
35
- this.registerComponentFunction("row", "treeCollapse", this.collapseRow.bind(this));
36
- this.registerComponentFunction("row", "treeExpand", this.expandRow.bind(this));
37
- this.registerComponentFunction("row", "treeToggle", this.toggleRow.bind(this));
38
- this.registerComponentFunction("row", "getTreeParent", this.getTreeParent.bind(this));
39
- this.registerComponentFunction("row", "getTreeChildren", this.getRowChildren.bind(this));
40
- this.registerComponentFunction("row", "addTreeChild", this.addTreeChildRow.bind(this));
41
- this.registerComponentFunction("row", "isTreeExpanded", this.isRowExpanded.bind(this));
42
- }
43
-
44
- initialize(){
45
- if(this.table.options.dataTree){
46
- var dummyEl = null,
47
- options = this.table.options;
48
-
49
- this.field = options.dataTreeChildField;
50
- this.indent = options.dataTreeChildIndent;
51
-
52
- if(this.options("movableRows")){
53
- console.warn("The movableRows option is not available with dataTree enabled, moving of child rows could result in unpredictable behavior");
54
- }
55
-
56
- if(options.dataTreeBranchElement){
57
-
58
- if(options.dataTreeBranchElement === true){
59
- this.branchEl = document.createElement("div");
60
- this.branchEl.classList.add("tabulator-data-tree-branch");
61
- }else{
62
- if(typeof options.dataTreeBranchElement === "string"){
63
- dummyEl = document.createElement("div");
64
- dummyEl.innerHTML = options.dataTreeBranchElement;
65
- this.branchEl = dummyEl.firstChild;
66
- }else{
67
- this.branchEl = options.dataTreeBranchElement;
68
- }
69
- }
70
- }
71
-
72
- if(options.dataTreeCollapseElement){
73
- if(typeof options.dataTreeCollapseElement === "string"){
74
- dummyEl = document.createElement("div");
75
- dummyEl.innerHTML = options.dataTreeCollapseElement;
76
- this.collapseEl = dummyEl.firstChild;
77
- }else{
78
- this.collapseEl = options.dataTreeCollapseElement;
79
- }
80
- }else{
81
- this.collapseEl = document.createElement("div");
82
- this.collapseEl.classList.add("tabulator-data-tree-control");
83
- this.collapseEl.tabIndex = 0;
84
- this.collapseEl.innerHTML = "<div class='tabulator-data-tree-control-collapse'></div>";
85
- }
86
-
87
- if(options.dataTreeExpandElement){
88
- if(typeof options.dataTreeExpandElement === "string"){
89
- dummyEl = document.createElement("div");
90
- dummyEl.innerHTML = options.dataTreeExpandElement;
91
- this.expandEl = dummyEl.firstChild;
92
- }else{
93
- this.expandEl = options.dataTreeExpandElement;
94
- }
95
- }else{
96
- this.expandEl = document.createElement("div");
97
- this.expandEl.classList.add("tabulator-data-tree-control");
98
- this.expandEl.tabIndex = 0;
99
- this.expandEl.innerHTML = "<div class='tabulator-data-tree-control-expand'></div>";
100
- }
101
-
102
-
103
- switch(typeof options.dataTreeStartExpanded){
104
- case "boolean":
105
- this.startOpen = function(row, index){
106
- return options.dataTreeStartExpanded;
107
- };
108
- break;
109
-
110
- case "function":
111
- this.startOpen = options.dataTreeStartExpanded;
112
- break;
113
-
114
- default:
115
- this.startOpen = function(row, index){
116
- return options.dataTreeStartExpanded[index];
117
- };
118
- break;
119
- }
120
-
121
- this.subscribe("row-init", this.initializeRow.bind(this));
122
- this.subscribe("row-layout-after", this.layoutRow.bind(this));
123
- this.subscribe("row-deleted", this.rowDelete.bind(this),0);
124
- this.subscribe("row-data-changed", this.rowDataChanged.bind(this), 10);
125
- this.subscribe("cell-value-updated", this.cellValueChanged.bind(this));
126
- this.subscribe("edit-cancelled", this.cellValueChanged.bind(this));
127
- this.subscribe("column-moving-rows", this.columnMoving.bind(this));
128
- this.subscribe("table-built", this.initializeElementField.bind(this));
129
- this.subscribe("table-redrawing", this.tableRedrawing.bind(this));
130
-
131
- this.registerDisplayHandler(this.getRows.bind(this), 30);
132
- }
133
- }
134
-
135
- tableRedrawing(force){
136
- var rows;
137
-
138
- if(force){
139
- rows = this.table.rowManager.getRows();
140
-
141
- rows.forEach((row) => {
142
- this.reinitializeRowChildren(row);
143
- });
144
- }
145
- }
146
-
147
- initializeElementField(){
148
- var firstCol = this.table.columnManager.getFirstVisibleColumn();
149
-
150
- this.elementField = this.table.options.dataTreeElementColumn || (firstCol ? firstCol.field : false);
151
- }
152
-
153
- getRowChildren(row){
154
- return this.getTreeChildren(row, true);
155
- }
156
-
157
- columnMoving(){
158
- var rows = [];
159
-
160
- this.table.rowManager.rows.forEach((row) => {
161
- rows = rows.concat(this.getTreeChildren(row, false, true));
162
- });
163
-
164
- return rows;
165
- }
166
-
167
- rowDataChanged(row, visible, updatedData){
168
- if(this.redrawNeeded(updatedData)){
169
- this.initializeRow(row);
170
-
171
- if(visible){
172
- this.layoutRow(row);
173
- this.refreshData(true);
174
- }
175
- }
176
- }
177
-
178
- cellValueChanged(cell){
179
- var field = cell.column.getField();
180
-
181
- if(field === this.elementField){
182
- this.layoutRow(cell.row);
183
- }
184
- }
185
-
186
- initializeRow(row){
187
- var childArray = row.getData()[this.field];
188
- var isArray = Array.isArray(childArray);
189
-
190
- var children = isArray || (!isArray && typeof childArray === "object" && childArray !== null);
191
-
192
- if(!children && row.modules.dataTree && row.modules.dataTree.branchEl){
193
- row.modules.dataTree.branchEl.parentNode.removeChild(row.modules.dataTree.branchEl);
194
- }
195
-
196
- if(!children && row.modules.dataTree && row.modules.dataTree.controlEl){
197
- row.modules.dataTree.controlEl.parentNode.removeChild(row.modules.dataTree.controlEl);
198
- }
199
-
200
- row.modules.dataTree = {
201
- index: row.modules.dataTree ? row.modules.dataTree.index : 0,
202
- open: children ? (row.modules.dataTree ? row.modules.dataTree.open : this.startOpen(row.getComponent(), 0)) : false,
203
- controlEl: row.modules.dataTree && children ? row.modules.dataTree.controlEl : false,
204
- branchEl: row.modules.dataTree && children ? row.modules.dataTree.branchEl : false,
205
- parent: row.modules.dataTree ? row.modules.dataTree.parent : false,
206
- children:children,
207
- };
208
- }
209
-
210
- reinitializeRowChildren(row){
211
- var children = this.getTreeChildren(row, false, true);
212
-
213
- children.forEach(function(child){
214
- child.reinitialize(true);
215
- });
216
- }
217
-
218
- layoutRow(row){
219
- var cell = this.elementField ? row.getCell(this.elementField) : row.getCells()[0],
220
- el = cell.getElement(),
221
- config = row.modules.dataTree;
222
-
223
- if(config.branchEl){
224
- if(config.branchEl.parentNode){
225
- config.branchEl.parentNode.removeChild(config.branchEl);
226
- }
227
- config.branchEl = false;
228
- }
229
-
230
- if(config.controlEl){
231
- if(config.controlEl.parentNode){
232
- config.controlEl.parentNode.removeChild(config.controlEl);
233
- }
234
- config.controlEl = false;
235
- }
236
-
237
- this.generateControlElement(row, el);
238
-
239
- row.getElement().classList.add("tabulator-tree-level-" + config.index);
240
-
241
- if(config.index){
242
- if(this.branchEl){
243
- config.branchEl = this.branchEl.cloneNode(true);
244
- el.insertBefore(config.branchEl, el.firstChild);
245
-
246
- if(this.table.rtl){
247
- config.branchEl.style.marginRight = (((config.branchEl.offsetWidth + config.branchEl.style.marginLeft) * (config.index - 1)) + (config.index * this.indent)) + "px";
248
- }else{
249
- config.branchEl.style.marginLeft = (((config.branchEl.offsetWidth + config.branchEl.style.marginRight) * (config.index - 1)) + (config.index * this.indent)) + "px";
250
- }
251
- }else{
252
-
253
- if(this.table.rtl){
254
- el.style.paddingRight = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-right')) + (config.index * this.indent) + "px";
255
- }else{
256
- el.style.paddingLeft = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + (config.index * this.indent) + "px";
257
- }
258
- }
259
- }
260
- }
261
-
262
- generateControlElement(row, el){
263
- var config = row.modules.dataTree,
264
- oldControl = config.controlEl;
265
-
266
- el = el || row.getCells()[0].getElement();
267
-
268
- if(config.children !== false){
269
-
270
- if(config.open){
271
- config.controlEl = this.collapseEl.cloneNode(true);
272
- config.controlEl.addEventListener("click", (e) => {
273
- e.stopPropagation();
274
- this.collapseRow(row);
275
- });
276
- }else{
277
- config.controlEl = this.expandEl.cloneNode(true);
278
- config.controlEl.addEventListener("click", (e) => {
279
- e.stopPropagation();
280
- this.expandRow(row);
281
- });
282
- }
283
-
284
- config.controlEl.addEventListener("mousedown", (e) => {
285
- e.stopPropagation();
286
- });
287
-
288
- if(oldControl && oldControl.parentNode === el){
289
- oldControl.parentNode.replaceChild(config.controlEl,oldControl);
290
- }else{
291
- el.insertBefore(config.controlEl, el.firstChild);
292
- }
293
- }
294
- }
295
-
296
- getRows(rows){
297
- var output = [];
298
-
299
- rows.forEach((row, i) => {
300
- var config, children;
301
-
302
- output.push(row);
303
-
304
- if(row instanceof Row){
305
-
306
- row.create();
307
-
308
- config = row.modules.dataTree.children;
309
-
310
- if(!config.index && config.children !== false){
311
- children = this.getChildren(row);
312
-
313
- children.forEach((child) => {
314
- child.create();
315
- output.push(child);
316
- });
317
- }
318
- }
319
- });
320
-
321
- return output;
322
- }
323
-
324
- getChildren(row, allChildren){
325
- var config = row.modules.dataTree,
326
- children = [],
327
- output = [];
328
-
329
- if(config.children !== false && (config.open || allChildren)){
330
- if(!Array.isArray(config.children)){
331
- config.children = this.generateChildren(row);
332
- }
333
-
334
- if(this.table.modExists("filter") && this.table.options.dataTreeFilter){
335
- children = this.table.modules.filter.filter(config.children);
336
- }else{
337
- children = config.children;
338
- }
339
-
340
- if(this.table.modExists("sort") && this.table.options.dataTreeSort){
341
- this.table.modules.sort.sort(children);
342
- }
343
-
344
- children.forEach((child) => {
345
- output.push(child);
346
-
347
- var subChildren = this.getChildren(child);
348
-
349
- subChildren.forEach((sub) => {
350
- output.push(sub);
351
- });
352
- });
353
- }
354
-
355
- return output;
356
- }
357
-
358
- generateChildren(row){
359
- var children = [];
360
-
361
- var childArray = row.getData()[this.field];
362
-
363
- if(!Array.isArray(childArray)){
364
- childArray = [childArray];
365
- }
366
-
367
- childArray.forEach((childData) => {
368
- var childRow = new Row(childData || {}, this.table.rowManager);
369
-
370
- childRow.create();
371
-
372
- childRow.modules.dataTree.index = row.modules.dataTree.index + 1;
373
- childRow.modules.dataTree.parent = row;
374
-
375
- if(childRow.modules.dataTree.children){
376
- childRow.modules.dataTree.open = this.startOpen(childRow.getComponent(), childRow.modules.dataTree.index);
377
- }
378
- children.push(childRow);
379
- });
380
-
381
- return children;
382
- }
383
-
384
- expandRow(row, silent){
385
- var config = row.modules.dataTree;
386
-
387
- if(config.children !== false){
388
- config.open = true;
389
-
390
- row.reinitialize();
391
-
392
- this.refreshData(true);
393
-
394
- this.dispatchExternal("dataTreeRowExpanded", row.getComponent(), row.modules.dataTree.index);
395
- }
396
- }
397
-
398
- collapseRow(row){
399
- var config = row.modules.dataTree;
400
-
401
- if(config.children !== false){
402
- config.open = false;
403
-
404
- row.reinitialize();
405
-
406
- this.refreshData(true);
407
-
408
- this.dispatchExternal("dataTreeRowCollapsed", row.getComponent(), row.modules.dataTree.index);
409
- }
410
- }
411
-
412
- toggleRow(row){
413
- var config = row.modules.dataTree;
414
-
415
- if(config.children !== false){
416
- if(config.open){
417
- this.collapseRow(row);
418
- }else{
419
- this.expandRow(row);
420
- }
421
- }
422
- }
423
-
424
- isRowExpanded(row){
425
- return row.modules.dataTree.open;
426
- }
427
-
428
- getTreeParent(row){
429
- return row.modules.dataTree.parent ? row.modules.dataTree.parent.getComponent() : false;
430
- }
431
-
432
- getTreeParentRoot(row){
433
- return row.modules.dataTree && row.modules.dataTree.parent ? this.getTreeParentRoot(row.modules.dataTree.parent) : row;
434
- }
435
-
436
- getFilteredTreeChildren(row){
437
- var config = row.modules.dataTree,
438
- output = [], children;
439
-
440
- if(config.children){
441
-
442
- if(!Array.isArray(config.children)){
443
- config.children = this.generateChildren(row);
444
- }
445
-
446
- if(this.table.modExists("filter") && this.table.options.dataTreeFilter){
447
- children = this.table.modules.filter.filter(config.children);
448
- }else{
449
- children = config.children;
450
- }
451
-
452
- children.forEach((childRow) => {
453
- if(childRow instanceof Row){
454
- output.push(childRow);
455
- }
456
- });
457
- }
458
-
459
- return output;
460
- }
461
-
462
- rowDelete(row){
463
- var parent = row.modules.dataTree.parent,
464
- childIndex;
465
-
466
- if(parent){
467
- childIndex = this.findChildIndex(row, parent);
468
-
469
- if(childIndex !== false){
470
- parent.data[this.field].splice(childIndex, 1);
471
- }
472
-
473
- if(!parent.data[this.field].length){
474
- delete parent.data[this.field];
475
- }
476
-
477
- this.initializeRow(parent);
478
- this.layoutRow(parent);
479
- }
480
-
481
- this.refreshData(true);
482
- }
483
-
484
- addTreeChildRow(row, data, top, index){
485
- var childIndex = false;
486
-
487
- if(typeof data === "string"){
488
- data = JSON.parse(data);
489
- }
490
-
491
- if(!Array.isArray(row.data[this.field])){
492
- row.data[this.field] = [];
493
-
494
- row.modules.dataTree.open = this.startOpen(row.getComponent(), row.modules.dataTree.index);
495
- }
496
-
497
- if(typeof index !== "undefined"){
498
- childIndex = this.findChildIndex(index, row);
499
-
500
- if(childIndex !== false){
501
- row.data[this.field].splice((top ? childIndex : childIndex + 1), 0, data);
502
- }
503
- }
504
-
505
- if(childIndex === false){
506
- if(top){
507
- row.data[this.field].unshift(data);
508
- }else{
509
- row.data[this.field].push(data);
510
- }
511
- }
512
-
513
- this.initializeRow(row);
514
- this.layoutRow(row);
515
-
516
- this.refreshData(true);
517
- }
518
-
519
- findChildIndex(subject, parent){
520
- var match = false;
521
-
522
- if(typeof subject == "object"){
523
-
524
- if(subject instanceof Row){
525
- //subject is row element
526
- match = subject.data;
527
- }else if(subject instanceof RowComponent){
528
- //subject is public row component
529
- match = subject._getSelf().data;
530
- }else if(typeof HTMLElement !== "undefined" && subject instanceof HTMLElement){
531
- if(parent.modules.dataTree){
532
- match = parent.modules.dataTree.children.find((childRow) => {
533
- return childRow instanceof Row ? childRow.element === subject : false;
534
- });
535
-
536
- if(match){
537
- match = match.data;
538
- }
539
- }
540
- }else if(subject === null){
541
- match = false;
542
- }
543
-
544
- }else if(typeof subject == "undefined"){
545
- match = false;
546
- }else{
547
- //subject should be treated as the index of the row
548
- match = parent.data[this.field].find((row) => {
549
- return row.data[this.table.options.index] == subject;
550
- });
551
- }
552
-
553
- if(match){
554
-
555
- if(Array.isArray(parent.data[this.field])){
556
- match = parent.data[this.field].indexOf(match);
557
- }
558
-
559
- if(match == -1){
560
- match = false;
561
- }
562
- }
563
-
564
- //catch all for any other type of input
565
-
566
- return match;
567
- }
568
-
569
- getTreeChildren(row, component, recurse){
570
- var config = row.modules.dataTree,
571
- output = [];
572
-
573
- if(config.children){
574
-
575
- if(!Array.isArray(config.children)){
576
- config.children = this.generateChildren(row);
577
- }
578
-
579
- config.children.forEach((childRow) => {
580
- if(childRow instanceof Row){
581
- output.push(component ? childRow.getComponent() : childRow);
582
-
583
- if(recurse){
584
- output = output.concat(this.getTreeChildren(childRow, component, recurse));
585
- }
586
- }
587
- });
588
- }
589
-
590
- return output;
591
- }
592
-
593
- getChildField(){
594
- return this.field;
595
- }
596
-
597
- redrawNeeded(data){
598
- return (this.field ? typeof data[this.field] !== "undefined" : false) || (this.elementField ? typeof data[this.elementField] !== "undefined" : false);
599
- }
600
- }
601
-
602
- DataTree.moduleName = "dataTree";
603
-
1
+ import Module from '../../core/Module.js';
2
+
3
+ import Row from '../../core/row/Row.js';
4
+
5
+ import RowComponent from '../../core/row/RowComponent.js';
6
+
7
+ class DataTree extends Module{
8
+
9
+ constructor(table){
10
+ super(table);
11
+
12
+ this.indent = 10;
13
+ this.field = "";
14
+ this.collapseEl = null;
15
+ this.expandEl = null;
16
+ this.branchEl = null;
17
+ this.elementField = false;
18
+
19
+ this.startOpen = function(){};
20
+
21
+ this.registerTableOption("dataTree", false); //enable data tree
22
+ this.registerTableOption("dataTreeFilter", true); //filter child rows
23
+ this.registerTableOption("dataTreeSort", true); //sort child rows
24
+ this.registerTableOption("dataTreeElementColumn", false);
25
+ this.registerTableOption("dataTreeBranchElement", true);//show data tree branch element
26
+ this.registerTableOption("dataTreeChildIndent", 9); //data tree child indent in px
27
+ this.registerTableOption("dataTreeChildField", "_children");//data tre column field to look for child rows
28
+ this.registerTableOption("dataTreeCollapseElement", false);//data tree row collapse element
29
+ this.registerTableOption("dataTreeExpandElement", false);//data tree row expand element
30
+ this.registerTableOption("dataTreeStartExpanded", false);
31
+ this.registerTableOption("dataTreeChildColumnCalcs", false);//include visible data tree rows in column calculations
32
+ this.registerTableOption("dataTreeSelectPropagate", false);//selecting a parent row selects its children
33
+
34
+ //register component functions
35
+ this.registerComponentFunction("row", "treeCollapse", this.collapseRow.bind(this));
36
+ this.registerComponentFunction("row", "treeExpand", this.expandRow.bind(this));
37
+ this.registerComponentFunction("row", "treeToggle", this.toggleRow.bind(this));
38
+ this.registerComponentFunction("row", "getTreeParent", this.getTreeParent.bind(this));
39
+ this.registerComponentFunction("row", "getTreeChildren", this.getRowChildren.bind(this));
40
+ this.registerComponentFunction("row", "addTreeChild", this.addTreeChildRow.bind(this));
41
+ this.registerComponentFunction("row", "isTreeExpanded", this.isRowExpanded.bind(this));
42
+ }
43
+
44
+ initialize(){
45
+ if(this.table.options.dataTree){
46
+ var dummyEl = null,
47
+ options = this.table.options;
48
+
49
+ this.field = options.dataTreeChildField;
50
+ this.indent = options.dataTreeChildIndent;
51
+
52
+ if(this.options("movableRows")){
53
+ console.warn("The movableRows option is not available with dataTree enabled, moving of child rows could result in unpredictable behavior");
54
+ }
55
+
56
+ if(options.dataTreeBranchElement){
57
+
58
+ if(options.dataTreeBranchElement === true){
59
+ this.branchEl = document.createElement("div");
60
+ this.branchEl.classList.add("tabulator-data-tree-branch");
61
+ }else{
62
+ if(typeof options.dataTreeBranchElement === "string"){
63
+ dummyEl = document.createElement("div");
64
+ dummyEl.innerHTML = options.dataTreeBranchElement;
65
+ this.branchEl = dummyEl.firstChild;
66
+ }else{
67
+ this.branchEl = options.dataTreeBranchElement;
68
+ }
69
+ }
70
+ }
71
+
72
+ if(options.dataTreeCollapseElement){
73
+ if(typeof options.dataTreeCollapseElement === "string"){
74
+ dummyEl = document.createElement("div");
75
+ dummyEl.innerHTML = options.dataTreeCollapseElement;
76
+ this.collapseEl = dummyEl.firstChild;
77
+ }else{
78
+ this.collapseEl = options.dataTreeCollapseElement;
79
+ }
80
+ }else{
81
+ this.collapseEl = document.createElement("div");
82
+ this.collapseEl.classList.add("tabulator-data-tree-control");
83
+ this.collapseEl.tabIndex = 0;
84
+ this.collapseEl.innerHTML = "<div class='tabulator-data-tree-control-collapse'></div>";
85
+ }
86
+
87
+ if(options.dataTreeExpandElement){
88
+ if(typeof options.dataTreeExpandElement === "string"){
89
+ dummyEl = document.createElement("div");
90
+ dummyEl.innerHTML = options.dataTreeExpandElement;
91
+ this.expandEl = dummyEl.firstChild;
92
+ }else{
93
+ this.expandEl = options.dataTreeExpandElement;
94
+ }
95
+ }else{
96
+ this.expandEl = document.createElement("div");
97
+ this.expandEl.classList.add("tabulator-data-tree-control");
98
+ this.expandEl.tabIndex = 0;
99
+ this.expandEl.innerHTML = "<div class='tabulator-data-tree-control-expand'></div>";
100
+ }
101
+
102
+
103
+ switch(typeof options.dataTreeStartExpanded){
104
+ case "boolean":
105
+ this.startOpen = function(row, index){
106
+ return options.dataTreeStartExpanded;
107
+ };
108
+ break;
109
+
110
+ case "function":
111
+ this.startOpen = options.dataTreeStartExpanded;
112
+ break;
113
+
114
+ default:
115
+ this.startOpen = function(row, index){
116
+ return options.dataTreeStartExpanded[index];
117
+ };
118
+ break;
119
+ }
120
+
121
+ this.subscribe("row-init", this.initializeRow.bind(this));
122
+ this.subscribe("row-layout-after", this.layoutRow.bind(this));
123
+ this.subscribe("row-deleted", this.rowDelete.bind(this),0);
124
+ this.subscribe("row-data-changed", this.rowDataChanged.bind(this), 10);
125
+ this.subscribe("cell-value-updated", this.cellValueChanged.bind(this));
126
+ this.subscribe("edit-cancelled", this.cellValueChanged.bind(this));
127
+ this.subscribe("column-moving-rows", this.columnMoving.bind(this));
128
+ this.subscribe("table-built", this.initializeElementField.bind(this));
129
+ this.subscribe("table-redrawing", this.tableRedrawing.bind(this));
130
+
131
+ this.registerDisplayHandler(this.getRows.bind(this), 30);
132
+ }
133
+ }
134
+
135
+ tableRedrawing(force){
136
+ var rows;
137
+
138
+ if(force){
139
+ rows = this.table.rowManager.getRows();
140
+
141
+ rows.forEach((row) => {
142
+ this.reinitializeRowChildren(row);
143
+ });
144
+ }
145
+ }
146
+
147
+ initializeElementField(){
148
+ var firstCol = this.table.columnManager.getFirstVisibleColumn();
149
+
150
+ this.elementField = this.table.options.dataTreeElementColumn || (firstCol ? firstCol.field : false);
151
+ }
152
+
153
+ getRowChildren(row){
154
+ return this.getTreeChildren(row, true);
155
+ }
156
+
157
+ columnMoving(){
158
+ var rows = [];
159
+
160
+ this.table.rowManager.rows.forEach((row) => {
161
+ rows = rows.concat(this.getTreeChildren(row, false, true));
162
+ });
163
+
164
+ return rows;
165
+ }
166
+
167
+ rowDataChanged(row, visible, updatedData){
168
+ if(this.redrawNeeded(updatedData)){
169
+ this.initializeRow(row);
170
+
171
+ if(visible){
172
+ this.layoutRow(row);
173
+ this.refreshData(true);
174
+ }
175
+ }
176
+ }
177
+
178
+ cellValueChanged(cell){
179
+ var field = cell.column.getField();
180
+
181
+ if(field === this.elementField){
182
+ this.layoutRow(cell.row);
183
+ }
184
+ }
185
+
186
+ initializeRow(row){
187
+ var childArray = row.getData()[this.field];
188
+ var isArray = Array.isArray(childArray);
189
+
190
+ var children = isArray || (!isArray && typeof childArray === "object" && childArray !== null);
191
+
192
+ if(!children && row.modules.dataTree && row.modules.dataTree.branchEl){
193
+ row.modules.dataTree.branchEl.parentNode.removeChild(row.modules.dataTree.branchEl);
194
+ }
195
+
196
+ if(!children && row.modules.dataTree && row.modules.dataTree.controlEl){
197
+ row.modules.dataTree.controlEl.parentNode.removeChild(row.modules.dataTree.controlEl);
198
+ }
199
+
200
+ row.modules.dataTree = {
201
+ index: row.modules.dataTree ? row.modules.dataTree.index : 0,
202
+ open: children ? (row.modules.dataTree ? row.modules.dataTree.open : this.startOpen(row.getComponent(), 0)) : false,
203
+ controlEl: row.modules.dataTree && children ? row.modules.dataTree.controlEl : false,
204
+ branchEl: row.modules.dataTree && children ? row.modules.dataTree.branchEl : false,
205
+ parent: row.modules.dataTree ? row.modules.dataTree.parent : false,
206
+ children:children,
207
+ };
208
+ }
209
+
210
+ reinitializeRowChildren(row){
211
+ var children = this.getTreeChildren(row, false, true);
212
+
213
+ children.forEach(function(child){
214
+ child.reinitialize(true);
215
+ });
216
+ }
217
+
218
+ layoutRow(row){
219
+ var cell = this.elementField ? row.getCell(this.elementField) : row.getCells()[0],
220
+ el = cell.getElement(),
221
+ config = row.modules.dataTree;
222
+
223
+ if(config.branchEl){
224
+ if(config.branchEl.parentNode){
225
+ config.branchEl.parentNode.removeChild(config.branchEl);
226
+ }
227
+ config.branchEl = false;
228
+ }
229
+
230
+ if(config.controlEl){
231
+ if(config.controlEl.parentNode){
232
+ config.controlEl.parentNode.removeChild(config.controlEl);
233
+ }
234
+ config.controlEl = false;
235
+ }
236
+
237
+ this.generateControlElement(row, el);
238
+
239
+ row.getElement().classList.add("tabulator-tree-level-" + config.index);
240
+
241
+ if(config.index){
242
+ if(this.branchEl){
243
+ config.branchEl = this.branchEl.cloneNode(true);
244
+ el.insertBefore(config.branchEl, el.firstChild);
245
+
246
+ if(this.table.rtl){
247
+ config.branchEl.style.marginRight = (((config.branchEl.offsetWidth + config.branchEl.style.marginLeft) * (config.index - 1)) + (config.index * this.indent)) + "px";
248
+ }else{
249
+ config.branchEl.style.marginLeft = (((config.branchEl.offsetWidth + config.branchEl.style.marginRight) * (config.index - 1)) + (config.index * this.indent)) + "px";
250
+ }
251
+ }else{
252
+
253
+ if(this.table.rtl){
254
+ el.style.paddingRight = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-right')) + (config.index * this.indent) + "px";
255
+ }else{
256
+ el.style.paddingLeft = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + (config.index * this.indent) + "px";
257
+ }
258
+ }
259
+ }
260
+ }
261
+
262
+ generateControlElement(row, el){
263
+ var config = row.modules.dataTree,
264
+ oldControl = config.controlEl;
265
+
266
+ el = el || row.getCells()[0].getElement();
267
+
268
+ if(config.children !== false){
269
+
270
+ if(config.open){
271
+ config.controlEl = this.collapseEl.cloneNode(true);
272
+ config.controlEl.addEventListener("click", (e) => {
273
+ e.stopPropagation();
274
+ this.collapseRow(row);
275
+ });
276
+ }else{
277
+ config.controlEl = this.expandEl.cloneNode(true);
278
+ config.controlEl.addEventListener("click", (e) => {
279
+ e.stopPropagation();
280
+ this.expandRow(row);
281
+ });
282
+ }
283
+
284
+ config.controlEl.addEventListener("mousedown", (e) => {
285
+ e.stopPropagation();
286
+ });
287
+
288
+ if(oldControl && oldControl.parentNode === el){
289
+ oldControl.parentNode.replaceChild(config.controlEl,oldControl);
290
+ }else{
291
+ el.insertBefore(config.controlEl, el.firstChild);
292
+ }
293
+ }
294
+ }
295
+
296
+ getRows(rows){
297
+ var output = [];
298
+
299
+ rows.forEach((row, i) => {
300
+ var config, children;
301
+
302
+ output.push(row);
303
+
304
+ if(row instanceof Row){
305
+
306
+ row.create();
307
+
308
+ config = row.modules.dataTree.children;
309
+
310
+ if(!config.index && config.children !== false){
311
+ children = this.getChildren(row);
312
+
313
+ children.forEach((child) => {
314
+ child.create();
315
+ output.push(child);
316
+ });
317
+ }
318
+ }
319
+ });
320
+
321
+ return output;
322
+ }
323
+
324
+ getChildren(row, allChildren){
325
+ var config = row.modules.dataTree,
326
+ children = [],
327
+ output = [];
328
+
329
+ if(config.children !== false && (config.open || allChildren)){
330
+ if(!Array.isArray(config.children)){
331
+ config.children = this.generateChildren(row);
332
+ }
333
+
334
+ if(this.table.modExists("filter") && this.table.options.dataTreeFilter){
335
+ children = this.table.modules.filter.filter(config.children);
336
+ }else{
337
+ children = config.children;
338
+ }
339
+
340
+ if(this.table.modExists("sort") && this.table.options.dataTreeSort){
341
+ this.table.modules.sort.sort(children);
342
+ }
343
+
344
+ children.forEach((child) => {
345
+ output.push(child);
346
+
347
+ var subChildren = this.getChildren(child);
348
+
349
+ subChildren.forEach((sub) => {
350
+ output.push(sub);
351
+ });
352
+ });
353
+ }
354
+
355
+ return output;
356
+ }
357
+
358
+ generateChildren(row){
359
+ var children = [];
360
+
361
+ var childArray = row.getData()[this.field];
362
+
363
+ if(!Array.isArray(childArray)){
364
+ childArray = [childArray];
365
+ }
366
+
367
+ childArray.forEach((childData) => {
368
+ var childRow = new Row(childData || {}, this.table.rowManager);
369
+
370
+ childRow.create();
371
+
372
+ childRow.modules.dataTree.index = row.modules.dataTree.index + 1;
373
+ childRow.modules.dataTree.parent = row;
374
+
375
+ if(childRow.modules.dataTree.children){
376
+ childRow.modules.dataTree.open = this.startOpen(childRow.getComponent(), childRow.modules.dataTree.index);
377
+ }
378
+ children.push(childRow);
379
+ });
380
+
381
+ return children;
382
+ }
383
+
384
+ expandRow(row, silent){
385
+ var config = row.modules.dataTree;
386
+
387
+ if(config.children !== false){
388
+ config.open = true;
389
+
390
+ row.reinitialize();
391
+
392
+ this.refreshData(true);
393
+
394
+ this.dispatchExternal("dataTreeRowExpanded", row.getComponent(), row.modules.dataTree.index);
395
+ }
396
+ }
397
+
398
+ collapseRow(row){
399
+ var config = row.modules.dataTree;
400
+
401
+ if(config.children !== false){
402
+ config.open = false;
403
+
404
+ row.reinitialize();
405
+
406
+ this.refreshData(true);
407
+
408
+ this.dispatchExternal("dataTreeRowCollapsed", row.getComponent(), row.modules.dataTree.index);
409
+ }
410
+ }
411
+
412
+ toggleRow(row){
413
+ var config = row.modules.dataTree;
414
+
415
+ if(config.children !== false){
416
+ if(config.open){
417
+ this.collapseRow(row);
418
+ }else{
419
+ this.expandRow(row);
420
+ }
421
+ }
422
+ }
423
+
424
+ isRowExpanded(row){
425
+ return row.modules.dataTree.open;
426
+ }
427
+
428
+ getTreeParent(row){
429
+ return row.modules.dataTree.parent ? row.modules.dataTree.parent.getComponent() : false;
430
+ }
431
+
432
+ getTreeParentRoot(row){
433
+ return row.modules.dataTree && row.modules.dataTree.parent ? this.getTreeParentRoot(row.modules.dataTree.parent) : row;
434
+ }
435
+
436
+ getFilteredTreeChildren(row){
437
+ var config = row.modules.dataTree,
438
+ output = [], children;
439
+
440
+ if(config.children){
441
+
442
+ if(!Array.isArray(config.children)){
443
+ config.children = this.generateChildren(row);
444
+ }
445
+
446
+ if(this.table.modExists("filter") && this.table.options.dataTreeFilter){
447
+ children = this.table.modules.filter.filter(config.children);
448
+ }else{
449
+ children = config.children;
450
+ }
451
+
452
+ children.forEach((childRow) => {
453
+ if(childRow instanceof Row){
454
+ output.push(childRow);
455
+ }
456
+ });
457
+ }
458
+
459
+ return output;
460
+ }
461
+
462
+ rowDelete(row){
463
+ var parent = row.modules.dataTree.parent,
464
+ childIndex;
465
+
466
+ if(parent){
467
+ childIndex = this.findChildIndex(row, parent);
468
+
469
+ if(childIndex !== false){
470
+ parent.data[this.field].splice(childIndex, 1);
471
+ }
472
+
473
+ if(!parent.data[this.field].length){
474
+ delete parent.data[this.field];
475
+ }
476
+
477
+ this.initializeRow(parent);
478
+ this.layoutRow(parent);
479
+ }
480
+
481
+ this.refreshData(true);
482
+ }
483
+
484
+ addTreeChildRow(row, data, top, index){
485
+ var childIndex = false;
486
+
487
+ if(typeof data === "string"){
488
+ data = JSON.parse(data);
489
+ }
490
+
491
+ if(!Array.isArray(row.data[this.field])){
492
+ row.data[this.field] = [];
493
+
494
+ row.modules.dataTree.open = this.startOpen(row.getComponent(), row.modules.dataTree.index);
495
+ }
496
+
497
+ if(typeof index !== "undefined"){
498
+ childIndex = this.findChildIndex(index, row);
499
+
500
+ if(childIndex !== false){
501
+ row.data[this.field].splice((top ? childIndex : childIndex + 1), 0, data);
502
+ }
503
+ }
504
+
505
+ if(childIndex === false){
506
+ if(top){
507
+ row.data[this.field].unshift(data);
508
+ }else{
509
+ row.data[this.field].push(data);
510
+ }
511
+ }
512
+
513
+ this.initializeRow(row);
514
+ this.layoutRow(row);
515
+
516
+ this.refreshData(true);
517
+ }
518
+
519
+ findChildIndex(subject, parent){
520
+ var match = false;
521
+
522
+ if(typeof subject == "object"){
523
+
524
+ if(subject instanceof Row){
525
+ //subject is row element
526
+ match = subject.data;
527
+ }else if(subject instanceof RowComponent){
528
+ //subject is public row component
529
+ match = subject._getSelf().data;
530
+ }else if(typeof HTMLElement !== "undefined" && subject instanceof HTMLElement){
531
+ if(parent.modules.dataTree){
532
+ match = parent.modules.dataTree.children.find((childRow) => {
533
+ return childRow instanceof Row ? childRow.element === subject : false;
534
+ });
535
+
536
+ if(match){
537
+ match = match.data;
538
+ }
539
+ }
540
+ }else if(subject === null){
541
+ match = false;
542
+ }
543
+
544
+ }else if(typeof subject == "undefined"){
545
+ match = false;
546
+ }else{
547
+ //subject should be treated as the index of the row
548
+ match = parent.data[this.field].find((row) => {
549
+ return row.data[this.table.options.index] == subject;
550
+ });
551
+ }
552
+
553
+ if(match){
554
+
555
+ if(Array.isArray(parent.data[this.field])){
556
+ match = parent.data[this.field].indexOf(match);
557
+ }
558
+
559
+ if(match == -1){
560
+ match = false;
561
+ }
562
+ }
563
+
564
+ //catch all for any other type of input
565
+
566
+ return match;
567
+ }
568
+
569
+ getTreeChildren(row, component, recurse){
570
+ var config = row.modules.dataTree,
571
+ output = [];
572
+
573
+ if(config.children){
574
+
575
+ if(!Array.isArray(config.children)){
576
+ config.children = this.generateChildren(row);
577
+ }
578
+
579
+ config.children.forEach((childRow) => {
580
+ if(childRow instanceof Row){
581
+ output.push(component ? childRow.getComponent() : childRow);
582
+
583
+ if(recurse){
584
+ output = output.concat(this.getTreeChildren(childRow, component, recurse));
585
+ }
586
+ }
587
+ });
588
+ }
589
+
590
+ return output;
591
+ }
592
+
593
+ getChildField(){
594
+ return this.field;
595
+ }
596
+
597
+ redrawNeeded(data){
598
+ return (this.field ? typeof data[this.field] !== "undefined" : false) || (this.elementField ? typeof data[this.elementField] !== "undefined" : false);
599
+ }
600
+ }
601
+
602
+ DataTree.moduleName = "dataTree";
603
+
604
604
  export default DataTree;