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,1082 +1,1112 @@
1
- import CoreFeature from './CoreFeature.js';
2
- import Row from './row/Row.js';
3
- import RowComponent from './row/RowComponent.js';
4
- import Helpers from './tools/Helpers.js';
5
-
6
- import RendererBasicVertical from './rendering/renderers/BasicVertical.js';
7
- import RendererVirtualDomVertical from './rendering/renderers/VirtualDomVertical.js';
8
-
9
- export default class RowManager extends CoreFeature{
10
-
11
- constructor(table){
12
- super(table);
13
-
14
- this.element = this.createHolderElement(); //containing element
15
- this.tableElement = this.createTableElement(); //table element
16
- this.heightFixer = this.createTableElement(); //table element
17
- this.placeholder = null; //placeholder element
18
- this.placeholderContents = null; //placeholder element
19
-
20
- this.firstRender = false; //handle first render
21
- this.renderMode = "virtual"; //current rendering mode
22
- this.fixedHeight = false; //current rendering mode
23
-
24
- this.rows = []; //hold row data objects
25
- this.activeRowsPipeline = []; //hold calculation of active rows
26
- this.activeRows = []; //rows currently available to on display in the table
27
- this.activeRowsCount = 0; //count of active rows
28
-
29
- this.displayRows = []; //rows currently on display in the table
30
- this.displayRowsCount = 0; //count of display rows
31
-
32
- this.scrollTop = 0;
33
- this.scrollLeft = 0;
34
-
35
- this.redrawBlock = false; //prevent redraws to allow multiple data manipulations before continuing
36
- this.redrawBlockRestoreConfig = false; //store latest redraw function calls for when redraw is needed
37
- this.redrawBlockRenderInPosition = false; //store latest redraw function calls for when redraw is needed
38
-
39
- this.dataPipeline = []; //hold data pipeline tasks
40
- this.displayPipeline = []; //hold data display pipeline tasks
41
-
42
- this.scrollbarWidth = 0;
43
-
44
- this.renderer = null;
45
- }
46
-
47
- //////////////// Setup Functions /////////////////
48
-
49
- createHolderElement (){
50
- var el = document.createElement("div");
51
-
52
- el.classList.add("tabulator-tableholder");
53
- el.setAttribute("tabindex", 0);
54
- // el.setAttribute("role", "rowgroup");
55
-
56
- return el;
57
- }
58
-
59
- createTableElement (){
60
- var el = document.createElement("div");
61
-
62
- el.classList.add("tabulator-table");
63
- el.setAttribute("role", "rowgroup");
64
-
65
- return el;
66
- }
67
-
68
- initializePlaceholder(){
69
- //configure placeholder element
70
- if(typeof this.table.options.placeholder == "string"){
71
- let el = document.createElement("div");
72
- el.classList.add("tabulator-placeholder");
73
-
74
- let contents = document.createElement("div");
75
- contents.classList.add("tabulator-placeholder-contents");
76
- contents.innerHTML = this.table.options.placeholder;
77
-
78
- el.appendChild(contents);
79
-
80
- this.placeholderContents = contents;
81
- this.placeholder = el;
82
- }
83
- }
84
-
85
- //return containing element
86
- getElement(){
87
- return this.element;
88
- }
89
-
90
- //return table element
91
- getTableElement(){
92
- return this.tableElement;
93
- }
94
-
95
- initialize(){
96
- this.initializePlaceholder();
97
- this.initializeRenderer();
98
-
99
- //initialize manager
100
- this.element.appendChild(this.tableElement);
101
-
102
- this.firstRender = true;
103
-
104
- //scroll header along with table body
105
- this.element.addEventListener("scroll", () => {
106
- var left = this.element.scrollLeft,
107
- leftDir = this.scrollLeft > left,
108
- top = this.element.scrollTop,
109
- topDir = this.scrollTop > top;
110
-
111
- //handle horizontal scrolling
112
- if(this.scrollLeft != left){
113
- this.scrollLeft = left;
114
-
115
- this.dispatch("scroll-horizontal", left, leftDir);
116
- this.dispatchExternal("scrollHorizontal", left, leftDir);
117
-
118
- this._positionPlaceholder();
119
- }
120
-
121
- //handle vertical scrolling
122
- if(this.scrollTop != top){
123
- this.scrollTop = top;
124
-
125
- this.renderer.scrollRows(top, topDir);
126
-
127
- this.dispatch("scroll-vertical", top, topDir);
128
- this.dispatchExternal("scrollVertical", top, topDir);
129
- }
130
- });
131
- }
132
-
133
- ////////////////// Row Manipulation //////////////////
134
- findRow(subject){
135
- if(typeof subject == "object"){
136
- if(subject instanceof Row){
137
- //subject is row element
138
- return subject;
139
- }else if(subject instanceof RowComponent){
140
- //subject is public row component
141
- return subject._getSelf() || false;
142
- }else if(typeof HTMLElement !== "undefined" && subject instanceof HTMLElement){
143
- //subject is a HTML element of the row
144
- let match = this.rows.find((row) => {
145
- return row.getElement() === subject;
146
- });
147
-
148
- return match || false;
149
- }else if(subject === null){
150
- return false;
151
- }
152
- }else if(typeof subject == "undefined"){
153
- return false;
154
- }else{
155
- //subject should be treated as the index of the row
156
- let match = this.rows.find((row) => {
157
- return row.data[this.table.options.index] == subject;
158
- });
159
-
160
- return match || false;
161
- }
162
-
163
- //catch all for any other type of input
164
- return false;
165
- }
166
-
167
- getRowFromDataObject(data){
168
- var match = this.rows.find((row) => {
169
- return row.data === data;
170
- });
171
-
172
- return match || false;
173
- }
174
-
175
- getRowFromPosition(position){
176
- return this.getDisplayRows().find((row) => {
177
- return row.getPosition() === position && row.isDisplayed();
178
- });
179
- }
180
-
181
- scrollToRow(row, position, ifVisible){
182
- return this.renderer.scrollToRowPosition(row, position, ifVisible);
183
- }
184
-
185
- ////////////////// Data Handling //////////////////
186
- setData(data, renderInPosition, columnsChanged){
187
- return new Promise((resolve, reject)=>{
188
- if(renderInPosition && this.getDisplayRows().length){
189
- if(this.table.options.pagination){
190
- this._setDataActual(data, true);
191
- }else{
192
- this.reRenderInPosition(() => {
193
- this._setDataActual(data);
194
- });
195
- }
196
- }else{
197
- if(this.table.options.autoColumns && columnsChanged && this.table.initialized){
198
- this.table.columnManager.generateColumnsFromRowData(data);
199
- }
200
- this.resetScroll();
201
-
202
- this._setDataActual(data);
203
- }
204
-
205
- resolve();
206
- });
207
- }
208
-
209
- _setDataActual(data, renderInPosition){
210
- this.dispatchExternal("dataProcessing", data);
211
-
212
- this._wipeElements();
213
-
214
- if(Array.isArray(data)){
215
- this.dispatch("data-processing", data);
216
-
217
- data.forEach((def, i) => {
218
- if(def && typeof def === "object"){
219
- var row = new Row(def, this);
220
- this.rows.push(row);
221
- }else{
222
- console.warn("Data Loading Warning - Invalid row data detected and ignored, expecting object but received:", def);
223
- }
224
- });
225
-
226
- this.refreshActiveData(false, false, renderInPosition);
227
-
228
- this.dispatch("data-processed", data);
229
- this.dispatchExternal("dataProcessed", data);
230
- }else{
231
- console.error("Data Loading Error - Unable to process data due to invalid data type \nExpecting: array \nReceived: ", typeof data, "\nData: ", data);
232
- }
233
- }
234
-
235
- _wipeElements(){
236
- this.dispatch("rows-wipe");
237
-
238
- this.rows.forEach((row) => {
239
- row.wipe();
240
- });
241
-
242
- this.rows = [];
243
- this.activeRows = [];
244
- this.activeRowsPipeline = [];
245
- this.activeRowsCount = 0;
246
- this.displayRows = [];
247
- this.displayRowsCount = 0;
248
-
249
- this.adjustTableSize();
250
- }
251
-
252
- deleteRow(row, blockRedraw){
253
- var allIndex = this.rows.indexOf(row),
254
- activeIndex = this.activeRows.indexOf(row);
255
-
256
- if(activeIndex > -1){
257
- this.activeRows.splice(activeIndex, 1);
258
- }
259
-
260
- if(allIndex > -1){
261
- this.rows.splice(allIndex, 1);
262
- }
263
-
264
- this.setActiveRows(this.activeRows);
265
-
266
- this.displayRowIterator((rows) => {
267
- var displayIndex = rows.indexOf(row);
268
-
269
- if(displayIndex > -1){
270
- rows.splice(displayIndex, 1);
271
- }
272
- });
273
-
274
- if(!blockRedraw){
275
- this.reRenderInPosition();
276
- }
277
-
278
- this.regenerateRowPositions();
279
-
280
- this.dispatchExternal("rowDeleted", row.getComponent());
281
-
282
- if(!this.displayRowsCount){
283
- this._showPlaceholder();
284
- }
285
-
286
- if(this.subscribedExternal("dataChanged")){
287
- this.dispatchExternal("dataChanged", this.getData());
288
- }
289
- }
290
-
291
- addRow(data, pos, index, blockRedraw){
292
- var row = this.addRowActual(data, pos, index, blockRedraw);
293
- return row;
294
- }
295
-
296
- //add multiple rows
297
- addRows(data, pos, index){
298
- var rows = [];
299
-
300
- return new Promise((resolve, reject) => {
301
- pos = this.findAddRowPos(pos);
302
-
303
- if(!Array.isArray(data)){
304
- data = [data];
305
- }
306
-
307
- if((typeof index == "undefined" && pos) || (typeof index !== "undefined" && !pos)){
308
- data.reverse();
309
- }
310
-
311
- data.forEach((item, i) => {
312
- var row = this.addRow(item, pos, index, true);
313
- rows.push(row);
314
- this.dispatch("row-added", row, data, pos, index);
315
- });
316
-
317
- this.refreshActiveData(false, false, true);
318
-
319
- this.regenerateRowPositions();
320
-
321
- if(rows.length){
322
- this._clearPlaceholder();
323
- }
324
-
325
- resolve(rows);
326
- });
327
- }
328
-
329
- findAddRowPos(pos){
330
- if(typeof pos === "undefined"){
331
- pos = this.table.options.addRowPos;
332
- }
333
-
334
- if(pos === "pos"){
335
- pos = true;
336
- }
337
-
338
- if(pos === "bottom"){
339
- pos = false;
340
- }
341
-
342
- return pos;
343
- }
344
-
345
- addRowActual(data, pos, index, blockRedraw){
346
- var row = data instanceof Row ? data : new Row(data || {}, this),
347
- top = this.findAddRowPos(pos),
348
- allIndex = -1,
349
- activeIndex, chainResult;
350
-
351
- if(!index){
352
- chainResult = this.chain("row-adding-position", [row, top], null, {index, top});
353
-
354
- index = chainResult.index;
355
- top = chainResult.top;
356
- }
357
-
358
- if(typeof index !== "undefined"){
359
- index = this.findRow(index);
360
- }
361
-
362
- index = this.chain("row-adding-index", [row, index, top], null, index);
363
-
364
- if(index){
365
- allIndex = this.rows.indexOf(index);
366
- }
367
-
368
- if(index && allIndex > -1){
369
- activeIndex = this.activeRows.indexOf(index);
370
-
371
- this.displayRowIterator(function(rows){
372
- var displayIndex = rows.indexOf(index);
373
-
374
- if(displayIndex > -1){
375
- rows.splice((top ? displayIndex : displayIndex + 1), 0, row);
376
- }
377
- });
378
-
379
- if(activeIndex > -1){
380
- this.activeRows.splice((top ? activeIndex : activeIndex + 1), 0, row);
381
- }
382
-
383
- this.rows.splice((top ? allIndex : allIndex + 1), 0, row);
384
-
385
- }else{
386
-
387
- if(top){
388
-
389
- this.displayRowIterator(function(rows){
390
- rows.unshift(row);
391
- });
392
-
393
- this.activeRows.unshift(row);
394
- this.rows.unshift(row);
395
- }else{
396
- this.displayRowIterator(function(rows){
397
- rows.push(row);
398
- });
399
-
400
- this.activeRows.push(row);
401
- this.rows.push(row);
402
- }
403
- }
404
-
405
- this.setActiveRows(this.activeRows);
406
-
407
- this.dispatchExternal("rowAdded", row.getComponent());
408
-
409
- if(this.subscribedExternal("dataChanged")){
410
- this.dispatchExternal("dataChanged", this.table.rowManager.getData());
411
- }
412
-
413
- if(!blockRedraw){
414
- this.reRenderInPosition();
415
- }
416
-
417
- return row;
418
- }
419
-
420
- moveRow(from, to, after){
421
- this.dispatch("row-move", from, to, after);
422
-
423
- this.moveRowActual(from, to, after);
424
-
425
- this.regenerateRowPositions();
426
-
427
- this.dispatch("row-moved", from, to, after);
428
- this.dispatchExternal("rowMoved", from.getComponent());
429
- }
430
-
431
- moveRowActual(from, to, after){
432
- this.moveRowInArray(this.rows, from, to, after);
433
- this.moveRowInArray(this.activeRows, from, to, after);
434
-
435
- this.displayRowIterator((rows) => {
436
- this.moveRowInArray(rows, from, to, after);
437
- });
438
-
439
- this.dispatch("row-moving", from, to, after);
440
- }
441
-
442
- moveRowInArray(rows, from, to, after){
443
- var fromIndex, toIndex, start, end;
444
-
445
- if(from !== to){
446
-
447
- fromIndex = rows.indexOf(from);
448
-
449
- if (fromIndex > -1) {
450
-
451
- rows.splice(fromIndex, 1);
452
-
453
- toIndex = rows.indexOf(to);
454
-
455
- if (toIndex > -1) {
456
-
457
- if(after){
458
- rows.splice(toIndex+1, 0, from);
459
- }else{
460
- rows.splice(toIndex, 0, from);
461
- }
462
-
463
- }else{
464
- rows.splice(fromIndex, 0, from);
465
- }
466
- }
467
-
468
- //restyle rows
469
- if(rows === this.getDisplayRows()){
470
-
471
- start = fromIndex < toIndex ? fromIndex : toIndex;
472
- end = toIndex > fromIndex ? toIndex : fromIndex +1;
473
-
474
- for(let i = start; i <= end; i++){
475
- if(rows[i]){
476
- this.styleRow(rows[i], i);
477
- }
478
- }
479
- }
480
- }
481
- }
482
-
483
- clearData(){
484
- this.setData([]);
485
- }
486
-
487
- getRowIndex(row){
488
- return this.findRowIndex(row, this.rows);
489
- }
490
-
491
- getDisplayRowIndex(row){
492
- var index = this.getDisplayRows().indexOf(row);
493
- return index > -1 ? index : false;
494
- }
495
-
496
- nextDisplayRow(row, rowOnly){
497
- var index = this.getDisplayRowIndex(row),
498
- nextRow = false;
499
-
500
-
501
- if(index !== false && index < this.displayRowsCount -1){
502
- nextRow = this.getDisplayRows()[index+1];
503
- }
504
-
505
- if(nextRow && (!(nextRow instanceof Row) || nextRow.type != "row")){
506
- return this.nextDisplayRow(nextRow, rowOnly);
507
- }
508
-
509
- return nextRow;
510
- }
511
-
512
- prevDisplayRow(row, rowOnly){
513
- var index = this.getDisplayRowIndex(row),
514
- prevRow = false;
515
-
516
- if(index){
517
- prevRow = this.getDisplayRows()[index-1];
518
- }
519
-
520
- if(rowOnly && prevRow && (!(prevRow instanceof Row) || prevRow.type != "row")){
521
- return this.prevDisplayRow(prevRow, rowOnly);
522
- }
523
-
524
- return prevRow;
525
- }
526
-
527
- findRowIndex(row, list){
528
- var rowIndex;
529
-
530
- row = this.findRow(row);
531
-
532
- if(row){
533
- rowIndex = list.indexOf(row);
534
-
535
- if(rowIndex > -1){
536
- return rowIndex;
537
- }
538
- }
539
-
540
- return false;
541
- }
542
-
543
- getData(active, transform){
544
- var output = [],
545
- rows = this.getRows(active);
546
-
547
- rows.forEach(function(row){
548
- if(row.type == "row"){
549
- output.push(row.getData(transform || "data"));
550
- }
551
- });
552
-
553
- return output;
554
- }
555
-
556
- getComponents(active){
557
- var output = [],
558
- rows = this.getRows(active);
559
-
560
- rows.forEach(function(row){
561
- output.push(row.getComponent());
562
- });
563
-
564
- return output;
565
- }
566
-
567
- getDataCount(active){
568
- var rows = this.getRows(active);
569
-
570
- return rows.length;
571
- }
572
-
573
- scrollHorizontal(left){
574
- this.scrollLeft = left;
575
- this.element.scrollLeft = left;
576
-
577
- this.dispatch("scroll-horizontal", left);
578
- }
579
-
580
- registerDataPipelineHandler(handler, priority){
581
- if(typeof priority !== "undefined"){
582
- this.dataPipeline.push({handler, priority});
583
- this.dataPipeline.sort((a, b) => {
584
- return a.priority - b.priority;
585
- });
586
- }else{
587
- console.error("Data pipeline handlers must have a priority in order to be registered");
588
- }
589
- }
590
-
591
- registerDisplayPipelineHandler(handler, priority){
592
- if(typeof priority !== "undefined"){
593
- this.displayPipeline.push({handler, priority});
594
- this.displayPipeline.sort((a, b) => {
595
- return a.priority - b.priority;
596
- });
597
- }else{
598
- console.error("Display pipeline handlers must have a priority in order to be registered");
599
- }
600
- }
601
-
602
- //set active data set
603
- refreshActiveData(handler, skipStage, renderInPosition){
604
- var table = this.table,
605
- stage = "",
606
- index = 0,
607
- cascadeOrder = ["all", "dataPipeline", "display", "displayPipeline", "end"];
608
-
609
- if(!this.table.destroyed){
610
- if(typeof handler === "function"){
611
- index = this.dataPipeline.findIndex((item) => {
612
- return item.handler === handler;
613
- });
614
-
615
- if(index > -1){
616
- stage = "dataPipeline";
617
-
618
- if(skipStage){
619
- if(index == this.dataPipeline.length - 1){
620
- stage = "display";
621
- }else{
622
- index++;
623
- }
624
- }
625
- }else{
626
- index = this.displayPipeline.findIndex((item) => {
627
- return item.handler === handler;
628
- });
629
-
630
- if(index > -1){
631
- stage = "displayPipeline";
632
-
633
- if(skipStage){
634
- if(index == this.displayPipeline.length - 1){
635
- stage = "end";
636
- }else{
637
- index++;
638
- }
639
- }
640
- }else{
641
- console.error("Unable to refresh data, invalid handler provided", handler);
642
- return;
643
- }
644
- }
645
- }else{
646
- stage = handler || "all";
647
- index = 0;
648
- }
649
-
650
- if(this.redrawBlock){
651
- if(!this.redrawBlockRestoreConfig || (this.redrawBlockRestoreConfig && ((this.redrawBlockRestoreConfig.stage === stage && index < this.redrawBlockRestoreConfig.index) || (cascadeOrder.indexOf(stage) < cascadeOrder.indexOf(this.redrawBlockRestoreConfig.stage))))){
652
- this.redrawBlockRestoreConfig = {
653
- handler: handler,
654
- skipStage: skipStage,
655
- renderInPosition: renderInPosition,
656
- stage:stage,
657
- index:index,
658
- };
659
- }
660
-
661
- return;
662
- }else{
663
- if(Helpers.elVisible(this.element)){
664
- if(renderInPosition){
665
- this.reRenderInPosition(this.refreshPipelines.bind(this, handler, stage, index, renderInPosition));
666
- }else{
667
- this.refreshPipelines(handler, stage, index, renderInPosition);
668
-
669
- if(!handler){
670
- this.table.columnManager.renderer.renderColumns();
671
- }
672
-
673
- this.renderTable();
674
-
675
- if(table.options.layoutColumnsOnNewData){
676
- this.table.columnManager.redraw(true);
677
- }
678
- }
679
- }else{
680
- this.refreshPipelines(handler, stage, index, renderInPosition);
681
- }
682
-
683
- this.dispatch("data-refreshed");
684
- }
685
- }
686
- }
687
-
688
- refreshPipelines(handler, stage, index, renderInPosition){
689
- this.dispatch("data-refreshing");
690
-
691
- if(!handler){
692
- this.activeRowsPipeline[0] = this.rows.slice(0);
693
- }
694
-
695
- //cascade through data refresh stages
696
- switch(stage){
697
- case "all":
698
- //handle case where all data needs refreshing
699
-
700
- case "dataPipeline":
701
-
702
- for(let i = index; i < this.dataPipeline.length; i++){
703
- let result = this.dataPipeline[i].handler(this.activeRowsPipeline[i].slice(0));
704
-
705
- this.activeRowsPipeline[i + 1] = result || this.activeRowsPipeline[i].slice(0);
706
- }
707
-
708
- this.setActiveRows(this.activeRowsPipeline[this.dataPipeline.length]);
709
-
710
- case "display":
711
- index = 0;
712
- this.resetDisplayRows();
713
-
714
- case "displayPipeline":
715
- for(let i = index; i < this.displayPipeline.length; i++){
716
- let result = this.displayPipeline[i].handler((i ? this.getDisplayRows(i - 1) : this.activeRows).slice(0), renderInPosition);
717
-
718
- this.setDisplayRows(result || this.getDisplayRows(i - 1).slice(0), i);
719
- }
720
-
721
- case "end":
722
- //case to handle scenario when trying to skip past end stage
723
- this.regenerateRowPositions();
724
- }
725
-
726
- if(this.getDisplayRows().length){
727
- this._clearPlaceholder();
728
- }
729
- }
730
-
731
- //regenerate row positions
732
- regenerateRowPositions(){
733
- var rows = this.getDisplayRows();
734
- var index = 1;
735
-
736
- rows.forEach((row) => {
737
- if (row.type === "row"){
738
- row.setPosition(index);
739
- index++;
740
- }
741
- });
742
- }
743
-
744
- setActiveRows(activeRows){
745
- this.activeRows = activeRows;
746
- this.activeRowsCount = this.activeRows.length;
747
- }
748
-
749
- //reset display rows array
750
- resetDisplayRows(){
751
- this.displayRows = [];
752
-
753
- this.displayRows.push(this.activeRows.slice(0));
754
-
755
- this.displayRowsCount = this.displayRows[0].length;
756
- }
757
-
758
- //set display row pipeline data
759
- setDisplayRows(displayRows, index){
760
- this.displayRows[index] = displayRows;
761
-
762
- if(index == this.displayRows.length -1){
763
- this.displayRowsCount = this.displayRows[this.displayRows.length -1].length;
764
- }
765
- }
766
-
767
- getDisplayRows(index){
768
- if(typeof index == "undefined"){
769
- return this.displayRows.length ? this.displayRows[this.displayRows.length -1] : [];
770
- }else{
771
- return this.displayRows[index] || [];
772
- }
773
- }
774
-
775
- getVisibleRows(chain, viewable){
776
- var rows = Object.assign([], this.renderer.visibleRows(!viewable));
777
-
778
- if(chain){
779
- rows = this.chain("rows-visible", [viewable], rows, rows);
780
- }
781
-
782
- return rows;
783
- }
784
-
785
- //repeat action across display rows
786
- displayRowIterator(callback){
787
- this.activeRowsPipeline.forEach(callback);
788
- this.displayRows.forEach(callback);
789
-
790
- this.displayRowsCount = this.displayRows[this.displayRows.length -1].length;
791
- }
792
-
793
- //return only actual rows (not group headers etc)
794
- getRows(type){
795
- var rows = [];
796
-
797
- if(!type || type === true){
798
- rows = this.chain("rows-retrieve", type, null, this.rows) || this.rows;
799
- }else{
800
- switch(type){
801
- case "active":
802
- rows = this.activeRows;
803
- break;
804
-
805
- case "display":
806
- rows = this.table.rowManager.getDisplayRows();
807
- break;
808
-
809
- case "visible":
810
- rows = this.getVisibleRows(false, true);
811
- break;
812
- }
813
- }
814
-
815
- return rows;
816
- }
817
-
818
- ///////////////// Table Rendering /////////////////
819
- //trigger rerender of table in current position
820
- reRenderInPosition(callback){
821
- if(this.redrawBlock){
822
- if(callback){
823
- callback();
824
- }else{
825
- this.redrawBlockRenderInPosition = true;
826
- }
827
- }else{
828
- this.dispatchExternal("renderStarted");
829
-
830
- this.renderer.rerenderRows(callback);
831
-
832
- if(!this.fixedHeight){
833
- this.adjustTableSize();
834
- }
835
-
836
- this.scrollBarCheck();
837
-
838
- this.dispatchExternal("renderComplete");
839
- }
840
- }
841
-
842
- scrollBarCheck(){
843
- var scrollbarWidth = 0;
844
-
845
- //adjust for vertical scrollbar moving table when present
846
- if(this.element.scrollHeight > this.element.clientHeight){
847
- scrollbarWidth = this.element.offsetWidth - this.element.clientWidth;
848
- }
849
-
850
- if(scrollbarWidth !== this.scrollbarWidth){
851
- this.scrollbarWidth = scrollbarWidth;
852
- this.dispatch("scrollbar-vertical", scrollbarWidth);
853
- }
854
- }
855
-
856
- initializeRenderer(){
857
- var renderClass;
858
-
859
- var renderers = {
860
- "virtual": RendererVirtualDomVertical,
861
- "basic": RendererBasicVertical,
862
- };
863
-
864
- if(typeof this.table.options.renderVertical === "string"){
865
- renderClass = renderers[this.table.options.renderVertical];
866
- }else{
867
- renderClass = this.table.options.renderVertical;
868
- }
869
-
870
- if(renderClass){
871
- this.renderMode = this.table.options.renderVertical;
872
-
873
- this.renderer = new renderClass(this.table, this.element, this.tableElement);
874
- this.renderer.initialize();
875
-
876
- if((this.table.element.clientHeight || this.table.options.height)){
877
- this.fixedHeight = true;
878
- }else{
879
- this.fixedHeight = false;
880
- }
881
- }else{
882
- console.error("Unable to find matching renderer:", this.table.options.renderVertical);
883
- }
884
- }
885
-
886
- getRenderMode(){
887
- return this.renderMode;
888
- }
889
-
890
- renderTable(){
891
- this.dispatchExternal("renderStarted");
892
-
893
- this.element.scrollTop = 0;
894
-
895
- this._clearTable();
896
-
897
- if(this.displayRowsCount){
898
- this.renderer.renderRows();
899
-
900
- if(this.firstRender){
901
- this.firstRender = false;
902
- this.layoutRefresh(true);
903
- }
904
- }else{
905
- this.renderEmptyScroll();
906
- }
907
-
908
- if(!this.fixedHeight){
909
- this.adjustTableSize();
910
- }
911
-
912
- this.dispatch("table-layout");
913
-
914
- if(!this.displayRowsCount){
915
- this._showPlaceholder();
916
- }
917
-
918
- this.scrollBarCheck();
919
-
920
- this.dispatchExternal("renderComplete");
921
- }
922
-
923
- //show scrollbars on empty table div
924
- renderEmptyScroll(){
925
- if(this.placeholder){
926
- this.tableElement.style.display = "none";
927
- }else{
928
- this.tableElement.style.minWidth = this.table.columnManager.getWidth() + "px";
929
- // this.tableElement.style.minHeight = "1px";
930
- // this.tableElement.style.visibility = "hidden";
931
- }
932
- }
933
-
934
- _clearTable(){
935
- this._clearPlaceholder();
936
-
937
- this.scrollTop = 0;
938
- this.scrollLeft = 0;
939
-
940
- this.renderer.clearRows();
941
- }
942
-
943
- _showPlaceholder(){
944
- if(this.placeholder){
945
- this.placeholder.setAttribute("tabulator-render-mode", this.renderMode);
946
-
947
- this.getElement().appendChild(this.placeholder);
948
- this._positionPlaceholder();
949
- }
950
- }
951
-
952
- _clearPlaceholder(){
953
- if(this.placeholder && this.placeholder.parentNode){
954
- this.placeholder.parentNode.removeChild(this.placeholder);
955
- }
956
-
957
- // clear empty table placeholder min
958
- this.tableElement.style.minWidth = "";
959
- }
960
-
961
- _positionPlaceholder(){
962
- if(this.placeholder && this.placeholder.parentNode){
963
- this.placeholder.style.width = this.table.columnManager.getWidth() + "px";
964
- this.placeholderContents.style.width = this.table.rowManager.element.clientWidth + "px";
965
- this.placeholderContents.style.marginLeft = this.scrollLeft + "px";
966
- }
967
- }
968
-
969
- styleRow(row, index){
970
- var rowEl = row.getElement();
971
-
972
- if(index % 2){
973
- rowEl.classList.add("tabulator-row-even");
974
- rowEl.classList.remove("tabulator-row-odd");
975
- }else{
976
- rowEl.classList.add("tabulator-row-odd");
977
- rowEl.classList.remove("tabulator-row-even");
978
- }
979
- }
980
-
981
- //normalize height of active rows
982
- normalizeHeight(){
983
- this.activeRows.forEach(function(row){
984
- row.normalizeHeight();
985
- });
986
- }
987
-
988
- //adjust the height of the table holder to fit in the Tabulator element
989
- adjustTableSize(){
990
- var initialHeight = this.element.clientHeight, minHeight;
991
-
992
- if(this.renderer.verticalFillMode === "fill"){
993
- let otherHeight = Math.floor(this.table.columnManager.getElement().getBoundingClientRect().height + (this.table.footerManager && this.table.footerManager.active && !this.table.footerManager.external ? this.table.footerManager.getElement().getBoundingClientRect().height : 0));
994
-
995
- if(this.fixedHeight){
996
- minHeight = isNaN(this.table.options.minHeight) ? this.table.options.minHeight : this.table.options.minHeight + "px";
997
-
998
- this.element.style.minHeight = minHeight || "calc(100% - " + otherHeight + "px)";
999
- this.element.style.height = "calc(100% - " + otherHeight + "px)";
1000
- this.element.style.maxHeight = "calc(100% - " + otherHeight + "px)";
1001
- }else{
1002
- this.element.style.height = "";
1003
- this.element.style.height = (this.table.element.clientHeight - otherHeight) + "px";
1004
- this.element.scrollTop = this.scrollTop;
1005
- }
1006
-
1007
- this.renderer.resize();
1008
-
1009
- //check if the table has changed size when dealing with variable height tables
1010
- if(!this.fixedHeight && initialHeight != this.element.clientHeight){
1011
- if(this.subscribed("table-resize")){
1012
- this.dispatch("table-resize");
1013
- }else{
1014
- this.redraw();
1015
- }
1016
- }
1017
-
1018
- this.scrollBarCheck();
1019
- }
1020
-
1021
- this._positionPlaceholder();
1022
- }
1023
-
1024
- //reinitialize all rows
1025
- reinitialize(){
1026
- this.rows.forEach(function(row){
1027
- row.reinitialize(true);
1028
- });
1029
- }
1030
-
1031
- //prevent table from being redrawn
1032
- blockRedraw (){
1033
- this.redrawBlock = true;
1034
- this.redrawBlockRestoreConfig = false;
1035
- }
1036
-
1037
- //restore table redrawing
1038
- restoreRedraw (){
1039
- this.redrawBlock = false;
1040
-
1041
- if(this.redrawBlockRestoreConfig){
1042
- this.refreshActiveData(this.redrawBlockRestoreConfig.handler, this.redrawBlockRestoreConfig.skipStage, this.redrawBlockRestoreConfig.renderInPosition);
1043
-
1044
- this.redrawBlockRestoreConfig = false;
1045
- }else{
1046
- if(this.redrawBlockRenderInPosition){
1047
- this.reRenderInPosition();
1048
- }
1049
- }
1050
-
1051
- this.redrawBlockRenderInPosition = false;
1052
- }
1053
-
1054
- //redraw table
1055
- redraw (force){
1056
- var left = this.scrollLeft;
1057
-
1058
- this.adjustTableSize();
1059
-
1060
- this.table.tableWidth = this.table.element.clientWidth;
1061
-
1062
- if(!force){
1063
- this.reRenderInPosition();
1064
- this.scrollHorizontal(left);
1065
- }else{
1066
- this.renderTable();
1067
- }
1068
- }
1069
-
1070
- resetScroll(){
1071
- this.element.scrollLeft = 0;
1072
- this.element.scrollTop = 0;
1073
-
1074
- if(this.table.browser === "ie"){
1075
- var event = document.createEvent("Event");
1076
- event.initEvent("scroll", false, true);
1077
- this.element.dispatchEvent(event);
1078
- }else{
1079
- this.element.dispatchEvent(new Event('scroll'));
1080
- }
1081
- }
1082
- }
1
+ import CoreFeature from './CoreFeature.js';
2
+ import Row from './row/Row.js';
3
+ import RowComponent from './row/RowComponent.js';
4
+ import Helpers from './tools/Helpers.js';
5
+
6
+ import RendererBasicVertical from './rendering/renderers/BasicVertical.js';
7
+ import RendererVirtualDomVertical from './rendering/renderers/VirtualDomVertical.js';
8
+
9
+ export default class RowManager extends CoreFeature{
10
+
11
+ constructor(table){
12
+ super(table);
13
+
14
+ this.element = this.createHolderElement(); //containing element
15
+ this.tableElement = this.createTableElement(); //table element
16
+ this.heightFixer = this.createTableElement(); //table element
17
+ this.placeholder = null; //placeholder element
18
+ this.placeholderContents = null; //placeholder element
19
+
20
+ this.firstRender = false; //handle first render
21
+ this.renderMode = "virtual"; //current rendering mode
22
+ this.fixedHeight = false; //current rendering mode
23
+
24
+ this.rows = []; //hold row data objects
25
+ this.activeRowsPipeline = []; //hold calculation of active rows
26
+ this.activeRows = []; //rows currently available to on display in the table
27
+ this.activeRowsCount = 0; //count of active rows
28
+
29
+ this.displayRows = []; //rows currently on display in the table
30
+ this.displayRowsCount = 0; //count of display rows
31
+
32
+ this.scrollTop = 0;
33
+ this.scrollLeft = 0;
34
+
35
+ this.redrawBlock = false; //prevent redraws to allow multiple data manipulations before continuing
36
+ this.redrawBlockRestoreConfig = false; //store latest redraw function calls for when redraw is needed
37
+ this.redrawBlockRenderInPosition = false; //store latest redraw function calls for when redraw is needed
38
+
39
+ this.dataPipeline = []; //hold data pipeline tasks
40
+ this.displayPipeline = []; //hold data display pipeline tasks
41
+
42
+ this.scrollbarWidth = 0;
43
+
44
+ this.renderer = null;
45
+ }
46
+
47
+ //////////////// Setup Functions /////////////////
48
+
49
+ createHolderElement (){
50
+ var el = document.createElement("div");
51
+
52
+ el.classList.add("tabulator-tableholder");
53
+ el.setAttribute("tabindex", 0);
54
+ // el.setAttribute("role", "rowgroup");
55
+
56
+ return el;
57
+ }
58
+
59
+ createTableElement (){
60
+ var el = document.createElement("div");
61
+
62
+ el.classList.add("tabulator-table");
63
+ el.setAttribute("role", "rowgroup");
64
+
65
+ return el;
66
+ }
67
+
68
+ initializePlaceholder(){
69
+ var placeholder = this.table.options.placeholder;
70
+
71
+ //configure placeholder element
72
+ if(placeholder){
73
+ let el = document.createElement("div");
74
+ el.classList.add("tabulator-placeholder");
75
+
76
+ if(typeof placeholder == "string"){
77
+ let contents = document.createElement("div");
78
+ contents.classList.add("tabulator-placeholder-contents");
79
+ contents.innerHTML = placeholder;
80
+
81
+ el.appendChild(contents);
82
+
83
+ this.placeholderContents = contents;
84
+
85
+ }else if(typeof HTMLElement !== "undefined" && placeholder instanceof HTMLElement){
86
+
87
+ el.appendChild(placeholder);
88
+ this.placeholderContents = placeholder;
89
+ }else{
90
+ console.warn("Invalid placeholder provided, must be string or HTML Element", placeholder);
91
+
92
+ this.el = null;
93
+ }
94
+
95
+ this.placeholder = el;
96
+ }
97
+ }
98
+
99
+ //return containing element
100
+ getElement(){
101
+ return this.element;
102
+ }
103
+
104
+ //return table element
105
+ getTableElement(){
106
+ return this.tableElement;
107
+ }
108
+
109
+ initialize(){
110
+ this.initializePlaceholder();
111
+ this.initializeRenderer();
112
+
113
+ //initialize manager
114
+ this.element.appendChild(this.tableElement);
115
+
116
+ this.firstRender = true;
117
+
118
+ //scroll header along with table body
119
+ this.element.addEventListener("scroll", () => {
120
+ var left = this.element.scrollLeft,
121
+ leftDir = this.scrollLeft > left,
122
+ top = this.element.scrollTop,
123
+ topDir = this.scrollTop > top;
124
+
125
+ //handle horizontal scrolling
126
+ if(this.scrollLeft != left){
127
+ this.scrollLeft = left;
128
+
129
+ this.dispatch("scroll-horizontal", left, leftDir);
130
+ this.dispatchExternal("scrollHorizontal", left, leftDir);
131
+
132
+ this._positionPlaceholder();
133
+ }
134
+
135
+ //handle vertical scrolling
136
+ if(this.scrollTop != top){
137
+ this.scrollTop = top;
138
+
139
+ this.renderer.scrollRows(top, topDir);
140
+
141
+ this.dispatch("scroll-vertical", top, topDir);
142
+ this.dispatchExternal("scrollVertical", top, topDir);
143
+ }
144
+ });
145
+ }
146
+
147
+ ////////////////// Row Manipulation //////////////////
148
+ findRow(subject){
149
+ if(typeof subject == "object"){
150
+ if(subject instanceof Row){
151
+ //subject is row element
152
+ return subject;
153
+ }else if(subject instanceof RowComponent){
154
+ //subject is public row component
155
+ return subject._getSelf() || false;
156
+ }else if(typeof HTMLElement !== "undefined" && subject instanceof HTMLElement){
157
+ //subject is a HTML element of the row
158
+ let match = this.rows.find((row) => {
159
+ return row.getElement() === subject;
160
+ });
161
+
162
+ return match || false;
163
+ }else if(subject === null){
164
+ return false;
165
+ }
166
+ }else if(typeof subject == "undefined"){
167
+ return false;
168
+ }else{
169
+ //subject should be treated as the index of the row
170
+ let match = this.rows.find((row) => {
171
+ return row.data[this.table.options.index] == subject;
172
+ });
173
+
174
+ return match || false;
175
+ }
176
+
177
+ //catch all for any other type of input
178
+ return false;
179
+ }
180
+
181
+ getRowFromDataObject(data){
182
+ var match = this.rows.find((row) => {
183
+ return row.data === data;
184
+ });
185
+
186
+ return match || false;
187
+ }
188
+
189
+ getRowFromPosition(position){
190
+ return this.getDisplayRows().find((row) => {
191
+ return row.getPosition() === position && row.isDisplayed();
192
+ });
193
+ }
194
+
195
+ scrollToRow(row, position, ifVisible){
196
+ return this.renderer.scrollToRowPosition(row, position, ifVisible);
197
+ }
198
+
199
+ ////////////////// Data Handling //////////////////
200
+ setData(data, renderInPosition, columnsChanged){
201
+ return new Promise((resolve, reject)=>{
202
+ if(renderInPosition && this.getDisplayRows().length){
203
+ if(this.table.options.pagination){
204
+ this._setDataActual(data, true);
205
+ }else{
206
+ this.reRenderInPosition(() => {
207
+ this._setDataActual(data);
208
+ });
209
+ }
210
+ }else{
211
+ if(this.table.options.autoColumns && columnsChanged && this.table.initialized){
212
+ this.table.columnManager.generateColumnsFromRowData(data);
213
+ }
214
+ this.resetScroll();
215
+
216
+ this._setDataActual(data);
217
+ }
218
+
219
+ resolve();
220
+ });
221
+ }
222
+
223
+ _setDataActual(data, renderInPosition){
224
+ this.dispatchExternal("dataProcessing", data);
225
+
226
+ this._wipeElements();
227
+
228
+ if(Array.isArray(data)){
229
+ this.dispatch("data-processing", data);
230
+
231
+ data.forEach((def, i) => {
232
+ if(def && typeof def === "object"){
233
+ var row = new Row(def, this);
234
+ this.rows.push(row);
235
+ }else{
236
+ console.warn("Data Loading Warning - Invalid row data detected and ignored, expecting object but received:", def);
237
+ }
238
+ });
239
+
240
+ this.refreshActiveData(false, false, renderInPosition);
241
+
242
+ this.dispatch("data-processed", data);
243
+ this.dispatchExternal("dataProcessed", data);
244
+ }else{
245
+ console.error("Data Loading Error - Unable to process data due to invalid data type \nExpecting: array \nReceived: ", typeof data, "\nData: ", data);
246
+ }
247
+ }
248
+
249
+ _wipeElements(){
250
+ this.dispatch("rows-wipe");
251
+
252
+ this.destroy();
253
+
254
+ this.adjustTableSize();
255
+
256
+ this.dispatch("rows-wiped");
257
+ }
258
+
259
+ destroy(){
260
+ this.rows.forEach((row) => {
261
+ row.wipe();
262
+ });
263
+
264
+ this.rows = [];
265
+ this.activeRows = [];
266
+ this.activeRowsPipeline = [];
267
+ this.activeRowsCount = 0;
268
+ this.displayRows = [];
269
+ this.displayRowsCount = 0;
270
+ }
271
+
272
+ deleteRow(row, blockRedraw){
273
+ var allIndex = this.rows.indexOf(row),
274
+ activeIndex = this.activeRows.indexOf(row);
275
+
276
+ if(activeIndex > -1){
277
+ this.activeRows.splice(activeIndex, 1);
278
+ }
279
+
280
+ if(allIndex > -1){
281
+ this.rows.splice(allIndex, 1);
282
+ }
283
+
284
+ this.setActiveRows(this.activeRows);
285
+
286
+ this.displayRowIterator((rows) => {
287
+ var displayIndex = rows.indexOf(row);
288
+
289
+ if(displayIndex > -1){
290
+ rows.splice(displayIndex, 1);
291
+ }
292
+ });
293
+
294
+ if(!blockRedraw){
295
+ this.reRenderInPosition();
296
+ }
297
+
298
+ this.regenerateRowPositions();
299
+
300
+ this.dispatchExternal("rowDeleted", row.getComponent());
301
+
302
+ if(!this.displayRowsCount){
303
+ this.tableEmpty();
304
+ }
305
+
306
+ if(this.subscribedExternal("dataChanged")){
307
+ this.dispatchExternal("dataChanged", this.getData());
308
+ }
309
+ }
310
+
311
+ addRow(data, pos, index, blockRedraw){
312
+ var row = this.addRowActual(data, pos, index, blockRedraw);
313
+ return row;
314
+ }
315
+
316
+ //add multiple rows
317
+ addRows(data, pos, index, refreshDisplayOnly){
318
+ var rows = [];
319
+
320
+ return new Promise((resolve, reject) => {
321
+ pos = this.findAddRowPos(pos);
322
+
323
+ if(!Array.isArray(data)){
324
+ data = [data];
325
+ }
326
+
327
+ if((typeof index == "undefined" && pos) || (typeof index !== "undefined" && !pos)){
328
+ data.reverse();
329
+ }
330
+
331
+ data.forEach((item, i) => {
332
+ var row = this.addRow(item, pos, index, true);
333
+ rows.push(row);
334
+ this.dispatch("row-added", row, item, pos, index);
335
+ });
336
+
337
+ this.refreshActiveData(refreshDisplayOnly ? "displayPipeline" : false, false, true);
338
+
339
+ this.regenerateRowPositions();
340
+
341
+ if(rows.length){
342
+ this._clearPlaceholder();
343
+ }
344
+
345
+ resolve(rows);
346
+ });
347
+ }
348
+
349
+ findAddRowPos(pos){
350
+ if(typeof pos === "undefined"){
351
+ pos = this.table.options.addRowPos;
352
+ }
353
+
354
+ if(pos === "pos"){
355
+ pos = true;
356
+ }
357
+
358
+ if(pos === "bottom"){
359
+ pos = false;
360
+ }
361
+
362
+ return pos;
363
+ }
364
+
365
+ addRowActual(data, pos, index, blockRedraw){
366
+ var row = data instanceof Row ? data : new Row(data || {}, this),
367
+ top = this.findAddRowPos(pos),
368
+ allIndex = -1,
369
+ activeIndex, chainResult;
370
+
371
+ if(!index){
372
+ chainResult = this.chain("row-adding-position", [row, top], null, {index, top});
373
+
374
+ index = chainResult.index;
375
+ top = chainResult.top;
376
+ }
377
+
378
+ if(typeof index !== "undefined"){
379
+ index = this.findRow(index);
380
+ }
381
+
382
+ index = this.chain("row-adding-index", [row, index, top], null, index);
383
+
384
+ if(index){
385
+ allIndex = this.rows.indexOf(index);
386
+ }
387
+
388
+ if(index && allIndex > -1){
389
+ activeIndex = this.activeRows.indexOf(index);
390
+
391
+ this.displayRowIterator(function(rows){
392
+ var displayIndex = rows.indexOf(index);
393
+
394
+ if(displayIndex > -1){
395
+ rows.splice((top ? displayIndex : displayIndex + 1), 0, row);
396
+ }
397
+ });
398
+
399
+ if(activeIndex > -1){
400
+ this.activeRows.splice((top ? activeIndex : activeIndex + 1), 0, row);
401
+ }
402
+
403
+ this.rows.splice((top ? allIndex : allIndex + 1), 0, row);
404
+
405
+ }else{
406
+
407
+ if(top){
408
+
409
+ this.displayRowIterator(function(rows){
410
+ rows.unshift(row);
411
+ });
412
+
413
+ this.activeRows.unshift(row);
414
+ this.rows.unshift(row);
415
+ }else{
416
+ this.displayRowIterator(function(rows){
417
+ rows.push(row);
418
+ });
419
+
420
+ this.activeRows.push(row);
421
+ this.rows.push(row);
422
+ }
423
+ }
424
+
425
+ this.setActiveRows(this.activeRows);
426
+
427
+ this.dispatchExternal("rowAdded", row.getComponent());
428
+
429
+ if(this.subscribedExternal("dataChanged")){
430
+ this.dispatchExternal("dataChanged", this.table.rowManager.getData());
431
+ }
432
+
433
+ if(!blockRedraw){
434
+ this.reRenderInPosition();
435
+ }
436
+
437
+ return row;
438
+ }
439
+
440
+ moveRow(from, to, after){
441
+ this.dispatch("row-move", from, to, after);
442
+
443
+ this.moveRowActual(from, to, after);
444
+
445
+ this.regenerateRowPositions();
446
+
447
+ this.dispatch("row-moved", from, to, after);
448
+ this.dispatchExternal("rowMoved", from.getComponent());
449
+ }
450
+
451
+ moveRowActual(from, to, after){
452
+ this.moveRowInArray(this.rows, from, to, after);
453
+ this.moveRowInArray(this.activeRows, from, to, after);
454
+
455
+ this.displayRowIterator((rows) => {
456
+ this.moveRowInArray(rows, from, to, after);
457
+ });
458
+
459
+ this.dispatch("row-moving", from, to, after);
460
+ }
461
+
462
+ moveRowInArray(rows, from, to, after){
463
+ var fromIndex, toIndex, start, end;
464
+
465
+ if(from !== to){
466
+
467
+ fromIndex = rows.indexOf(from);
468
+
469
+ if (fromIndex > -1) {
470
+
471
+ rows.splice(fromIndex, 1);
472
+
473
+ toIndex = rows.indexOf(to);
474
+
475
+ if (toIndex > -1) {
476
+
477
+ if(after){
478
+ rows.splice(toIndex+1, 0, from);
479
+ }else{
480
+ rows.splice(toIndex, 0, from);
481
+ }
482
+
483
+ }else{
484
+ rows.splice(fromIndex, 0, from);
485
+ }
486
+ }
487
+
488
+ //restyle rows
489
+ if(rows === this.getDisplayRows()){
490
+
491
+ start = fromIndex < toIndex ? fromIndex : toIndex;
492
+ end = toIndex > fromIndex ? toIndex : fromIndex +1;
493
+
494
+ for(let i = start; i <= end; i++){
495
+ if(rows[i]){
496
+ this.styleRow(rows[i], i);
497
+ }
498
+ }
499
+ }
500
+ }
501
+ }
502
+
503
+ clearData(){
504
+ this.setData([]);
505
+ }
506
+
507
+ getRowIndex(row){
508
+ return this.findRowIndex(row, this.rows);
509
+ }
510
+
511
+ getDisplayRowIndex(row){
512
+ var index = this.getDisplayRows().indexOf(row);
513
+ return index > -1 ? index : false;
514
+ }
515
+
516
+ nextDisplayRow(row, rowOnly){
517
+ var index = this.getDisplayRowIndex(row),
518
+ nextRow = false;
519
+
520
+
521
+ if(index !== false && index < this.displayRowsCount -1){
522
+ nextRow = this.getDisplayRows()[index+1];
523
+ }
524
+
525
+ if(nextRow && (!(nextRow instanceof Row) || nextRow.type != "row")){
526
+ return this.nextDisplayRow(nextRow, rowOnly);
527
+ }
528
+
529
+ return nextRow;
530
+ }
531
+
532
+ prevDisplayRow(row, rowOnly){
533
+ var index = this.getDisplayRowIndex(row),
534
+ prevRow = false;
535
+
536
+ if(index){
537
+ prevRow = this.getDisplayRows()[index-1];
538
+ }
539
+
540
+ if(rowOnly && prevRow && (!(prevRow instanceof Row) || prevRow.type != "row")){
541
+ return this.prevDisplayRow(prevRow, rowOnly);
542
+ }
543
+
544
+ return prevRow;
545
+ }
546
+
547
+ findRowIndex(row, list){
548
+ var rowIndex;
549
+
550
+ row = this.findRow(row);
551
+
552
+ if(row){
553
+ rowIndex = list.indexOf(row);
554
+
555
+ if(rowIndex > -1){
556
+ return rowIndex;
557
+ }
558
+ }
559
+
560
+ return false;
561
+ }
562
+
563
+ getData(active, transform){
564
+ var output = [],
565
+ rows = this.getRows(active);
566
+
567
+ rows.forEach(function(row){
568
+ if(row.type == "row"){
569
+ output.push(row.getData(transform || "data"));
570
+ }
571
+ });
572
+
573
+ return output;
574
+ }
575
+
576
+ getComponents(active){
577
+ var output = [],
578
+ rows = this.getRows(active);
579
+
580
+ rows.forEach(function(row){
581
+ output.push(row.getComponent());
582
+ });
583
+
584
+ return output;
585
+ }
586
+
587
+ getDataCount(active){
588
+ var rows = this.getRows(active);
589
+
590
+ return rows.length;
591
+ }
592
+
593
+ scrollHorizontal(left){
594
+ this.scrollLeft = left;
595
+ this.element.scrollLeft = left;
596
+
597
+ this.dispatch("scroll-horizontal", left);
598
+ }
599
+
600
+ registerDataPipelineHandler(handler, priority){
601
+ if(typeof priority !== "undefined"){
602
+ this.dataPipeline.push({handler, priority});
603
+ this.dataPipeline.sort((a, b) => {
604
+ return a.priority - b.priority;
605
+ });
606
+ }else{
607
+ console.error("Data pipeline handlers must have a priority in order to be registered");
608
+ }
609
+ }
610
+
611
+ registerDisplayPipelineHandler(handler, priority){
612
+ if(typeof priority !== "undefined"){
613
+ this.displayPipeline.push({handler, priority});
614
+ this.displayPipeline.sort((a, b) => {
615
+ return a.priority - b.priority;
616
+ });
617
+ }else{
618
+ console.error("Display pipeline handlers must have a priority in order to be registered");
619
+ }
620
+ }
621
+
622
+ //set active data set
623
+ refreshActiveData(handler, skipStage, renderInPosition){
624
+ var table = this.table,
625
+ stage = "",
626
+ index = 0,
627
+ cascadeOrder = ["all", "dataPipeline", "display", "displayPipeline", "end"];
628
+
629
+ if(!this.table.destroyed){
630
+ if(typeof handler === "function"){
631
+ index = this.dataPipeline.findIndex((item) => {
632
+ return item.handler === handler;
633
+ });
634
+
635
+ if(index > -1){
636
+ stage = "dataPipeline";
637
+
638
+ if(skipStage){
639
+ if(index == this.dataPipeline.length - 1){
640
+ stage = "display";
641
+ }else{
642
+ index++;
643
+ }
644
+ }
645
+ }else{
646
+ index = this.displayPipeline.findIndex((item) => {
647
+ return item.handler === handler;
648
+ });
649
+
650
+ if(index > -1){
651
+ stage = "displayPipeline";
652
+
653
+ if(skipStage){
654
+ if(index == this.displayPipeline.length - 1){
655
+ stage = "end";
656
+ }else{
657
+ index++;
658
+ }
659
+ }
660
+ }else{
661
+ console.error("Unable to refresh data, invalid handler provided", handler);
662
+ return;
663
+ }
664
+ }
665
+ }else{
666
+ stage = handler || "all";
667
+ index = 0;
668
+ }
669
+
670
+ if(this.redrawBlock){
671
+ if(!this.redrawBlockRestoreConfig || (this.redrawBlockRestoreConfig && ((this.redrawBlockRestoreConfig.stage === stage && index < this.redrawBlockRestoreConfig.index) || (cascadeOrder.indexOf(stage) < cascadeOrder.indexOf(this.redrawBlockRestoreConfig.stage))))){
672
+ this.redrawBlockRestoreConfig = {
673
+ handler: handler,
674
+ skipStage: skipStage,
675
+ renderInPosition: renderInPosition,
676
+ stage:stage,
677
+ index:index,
678
+ };
679
+ }
680
+
681
+ return;
682
+ }else{
683
+ if(Helpers.elVisible(this.element)){
684
+ if(renderInPosition){
685
+ this.reRenderInPosition(this.refreshPipelines.bind(this, handler, stage, index, renderInPosition));
686
+ }else{
687
+ this.refreshPipelines(handler, stage, index, renderInPosition);
688
+
689
+ if(!handler){
690
+ this.table.columnManager.renderer.renderColumns();
691
+ }
692
+
693
+ this.renderTable();
694
+
695
+ if(table.options.layoutColumnsOnNewData){
696
+ this.table.columnManager.redraw(true);
697
+ }
698
+ }
699
+ }else{
700
+ this.refreshPipelines(handler, stage, index, renderInPosition);
701
+ }
702
+
703
+ this.dispatch("data-refreshed");
704
+ }
705
+ }
706
+ }
707
+
708
+ refreshPipelines(handler, stage, index, renderInPosition){
709
+ this.dispatch("data-refreshing");
710
+
711
+ if(!handler){
712
+ this.activeRowsPipeline[0] = this.rows.slice(0);
713
+ }
714
+
715
+ //cascade through data refresh stages
716
+ switch(stage){
717
+ case "all":
718
+ //handle case where all data needs refreshing
719
+
720
+ case "dataPipeline":
721
+
722
+ for(let i = index; i < this.dataPipeline.length; i++){
723
+ let result = this.dataPipeline[i].handler(this.activeRowsPipeline[i].slice(0));
724
+
725
+ this.activeRowsPipeline[i + 1] = result || this.activeRowsPipeline[i].slice(0);
726
+ }
727
+
728
+ this.setActiveRows(this.activeRowsPipeline[this.dataPipeline.length]);
729
+
730
+ case "display":
731
+ index = 0;
732
+ this.resetDisplayRows();
733
+
734
+ case "displayPipeline":
735
+ for(let i = index; i < this.displayPipeline.length; i++){
736
+ let result = this.displayPipeline[i].handler((i ? this.getDisplayRows(i - 1) : this.activeRows).slice(0), renderInPosition);
737
+
738
+ this.setDisplayRows(result || this.getDisplayRows(i - 1).slice(0), i);
739
+ }
740
+
741
+ case "end":
742
+ //case to handle scenario when trying to skip past end stage
743
+ this.regenerateRowPositions();
744
+ }
745
+
746
+ if(this.getDisplayRows().length){
747
+ this._clearPlaceholder();
748
+ }
749
+ }
750
+
751
+ //regenerate row positions
752
+ regenerateRowPositions(){
753
+ var rows = this.getDisplayRows();
754
+ var index = 1;
755
+
756
+ rows.forEach((row) => {
757
+ if (row.type === "row"){
758
+ row.setPosition(index);
759
+ index++;
760
+ }
761
+ });
762
+ }
763
+
764
+ setActiveRows(activeRows){
765
+ this.activeRows = this.activeRows = Object.assign([], activeRows);
766
+ this.activeRowsCount = this.activeRows.length;
767
+ }
768
+
769
+ //reset display rows array
770
+ resetDisplayRows(){
771
+ this.displayRows = [];
772
+
773
+ this.displayRows.push(this.activeRows.slice(0));
774
+
775
+ this.displayRowsCount = this.displayRows[0].length;
776
+ }
777
+
778
+ //set display row pipeline data
779
+ setDisplayRows(displayRows, index){
780
+ this.displayRows[index] = displayRows;
781
+
782
+ if(index == this.displayRows.length -1){
783
+ this.displayRowsCount = this.displayRows[this.displayRows.length -1].length;
784
+ }
785
+ }
786
+
787
+ getDisplayRows(index){
788
+ if(typeof index == "undefined"){
789
+ return this.displayRows.length ? this.displayRows[this.displayRows.length -1] : [];
790
+ }else{
791
+ return this.displayRows[index] || [];
792
+ }
793
+ }
794
+
795
+ getVisibleRows(chain, viewable){
796
+ var rows = Object.assign([], this.renderer.visibleRows(!viewable));
797
+
798
+ if(chain){
799
+ rows = this.chain("rows-visible", [viewable], rows, rows);
800
+ }
801
+
802
+ return rows;
803
+ }
804
+
805
+ //repeat action across display rows
806
+ displayRowIterator(callback){
807
+ this.activeRowsPipeline.forEach(callback);
808
+ this.displayRows.forEach(callback);
809
+
810
+ this.displayRowsCount = this.displayRows[this.displayRows.length -1].length;
811
+ }
812
+
813
+ //return only actual rows (not group headers etc)
814
+ getRows(type){
815
+ var rows = [];
816
+
817
+ switch(type){
818
+ case "active":
819
+ rows = this.activeRows;
820
+ break;
821
+
822
+ case "display":
823
+ rows = this.table.rowManager.getDisplayRows();
824
+ break;
825
+
826
+ case "visible":
827
+ rows = this.getVisibleRows(false, true);
828
+ break;
829
+
830
+ default:
831
+ rows = this.chain("rows-retrieve", type, null, this.rows) || this.rows;
832
+ }
833
+
834
+ return rows;
835
+ }
836
+
837
+ ///////////////// Table Rendering /////////////////
838
+ //trigger rerender of table in current position
839
+ reRenderInPosition(callback){
840
+ if(this.redrawBlock){
841
+ if(callback){
842
+ callback();
843
+ }else{
844
+ this.redrawBlockRenderInPosition = true;
845
+ }
846
+ }else{
847
+ this.dispatchExternal("renderStarted");
848
+
849
+ this.renderer.rerenderRows(callback);
850
+
851
+ if(!this.fixedHeight){
852
+ this.adjustTableSize();
853
+ }
854
+
855
+ this.scrollBarCheck();
856
+
857
+ this.dispatchExternal("renderComplete");
858
+ }
859
+ }
860
+
861
+ scrollBarCheck(){
862
+ var scrollbarWidth = 0;
863
+
864
+ //adjust for vertical scrollbar moving table when present
865
+ if(this.element.scrollHeight > this.element.clientHeight){
866
+ scrollbarWidth = this.element.offsetWidth - this.element.clientWidth;
867
+ }
868
+
869
+ if(scrollbarWidth !== this.scrollbarWidth){
870
+ this.scrollbarWidth = scrollbarWidth;
871
+ this.dispatch("scrollbar-vertical", scrollbarWidth);
872
+ }
873
+ }
874
+
875
+ initializeRenderer(){
876
+ var renderClass;
877
+
878
+ var renderers = {
879
+ "virtual": RendererVirtualDomVertical,
880
+ "basic": RendererBasicVertical,
881
+ };
882
+
883
+ if(typeof this.table.options.renderVertical === "string"){
884
+ renderClass = renderers[this.table.options.renderVertical];
885
+ }else{
886
+ renderClass = this.table.options.renderVertical;
887
+ }
888
+
889
+ if(renderClass){
890
+ this.renderMode = this.table.options.renderVertical;
891
+
892
+ this.renderer = new renderClass(this.table, this.element, this.tableElement);
893
+ this.renderer.initialize();
894
+
895
+ if((this.table.element.clientHeight || this.table.options.height) && !(this.table.options.minHeight && this.table.options.maxHeight)){
896
+ this.fixedHeight = true;
897
+ }else{
898
+ this.fixedHeight = false;
899
+ }
900
+ }else{
901
+ console.error("Unable to find matching renderer:", this.table.options.renderVertical);
902
+ }
903
+ }
904
+
905
+ getRenderMode(){
906
+ return this.renderMode;
907
+ }
908
+
909
+ renderTable(){
910
+ this.dispatchExternal("renderStarted");
911
+
912
+ this.element.scrollTop = 0;
913
+
914
+ this._clearTable();
915
+
916
+ if(this.displayRowsCount){
917
+ this.renderer.renderRows();
918
+
919
+ if(this.firstRender){
920
+ this.firstRender = false;
921
+
922
+ if(!this.fixedHeight){
923
+ this.adjustTableSize();
924
+ }
925
+
926
+ this.layoutRefresh(true);
927
+ }
928
+ }else{
929
+ this.renderEmptyScroll();
930
+ }
931
+
932
+ if(!this.fixedHeight){
933
+ this.adjustTableSize();
934
+ }
935
+
936
+ this.dispatch("table-layout");
937
+
938
+ if(!this.displayRowsCount){
939
+ this._showPlaceholder();
940
+ }
941
+
942
+ this.scrollBarCheck();
943
+
944
+ this.dispatchExternal("renderComplete");
945
+ }
946
+
947
+ //show scrollbars on empty table div
948
+ renderEmptyScroll(){
949
+ if(this.placeholder){
950
+ this.tableElement.style.display = "none";
951
+ }else{
952
+ this.tableElement.style.minWidth = this.table.columnManager.getWidth() + "px";
953
+ // this.tableElement.style.minHeight = "1px";
954
+ // this.tableElement.style.visibility = "hidden";
955
+ }
956
+ }
957
+
958
+ _clearTable(){
959
+ this._clearPlaceholder();
960
+
961
+ this.scrollTop = 0;
962
+ this.scrollLeft = 0;
963
+
964
+ this.renderer.clearRows();
965
+ }
966
+
967
+ tableEmpty(){
968
+ this.renderEmptyScroll();
969
+ this._showPlaceholder();
970
+ }
971
+
972
+ _showPlaceholder(){
973
+ if(this.placeholder){
974
+ this.placeholder.setAttribute("tabulator-render-mode", this.renderMode);
975
+
976
+ this.getElement().appendChild(this.placeholder);
977
+ this._positionPlaceholder();
978
+ }
979
+ }
980
+
981
+ _clearPlaceholder(){
982
+ if(this.placeholder && this.placeholder.parentNode){
983
+ this.placeholder.parentNode.removeChild(this.placeholder);
984
+ }
985
+
986
+ // clear empty table placeholder min
987
+ this.tableElement.style.minWidth = "";
988
+ this.tableElement.style.display = "";
989
+ }
990
+
991
+ _positionPlaceholder(){
992
+ if(this.placeholder && this.placeholder.parentNode){
993
+ this.placeholder.style.width = this.table.columnManager.getWidth() + "px";
994
+ this.placeholderContents.style.width = this.table.rowManager.element.clientWidth + "px";
995
+ this.placeholderContents.style.marginLeft = this.scrollLeft + "px";
996
+ }
997
+ }
998
+
999
+ styleRow(row, index){
1000
+ var rowEl = row.getElement();
1001
+
1002
+ if(index % 2){
1003
+ rowEl.classList.add("tabulator-row-even");
1004
+ rowEl.classList.remove("tabulator-row-odd");
1005
+ }else{
1006
+ rowEl.classList.add("tabulator-row-odd");
1007
+ rowEl.classList.remove("tabulator-row-even");
1008
+ }
1009
+ }
1010
+
1011
+ //normalize height of active rows
1012
+ normalizeHeight(){
1013
+ this.activeRows.forEach(function(row){
1014
+ row.normalizeHeight();
1015
+ });
1016
+ }
1017
+
1018
+ //adjust the height of the table holder to fit in the Tabulator element
1019
+ adjustTableSize(){
1020
+ var initialHeight = this.element.clientHeight, minHeight;
1021
+
1022
+ if(this.renderer.verticalFillMode === "fill"){
1023
+ let otherHeight = Math.floor(this.table.columnManager.getElement().getBoundingClientRect().height + (this.table.footerManager && this.table.footerManager.active && !this.table.footerManager.external ? this.table.footerManager.getElement().getBoundingClientRect().height : 0));
1024
+
1025
+ if(this.fixedHeight){
1026
+ minHeight = isNaN(this.table.options.minHeight) ? this.table.options.minHeight : this.table.options.minHeight + "px";
1027
+
1028
+ this.element.style.minHeight = minHeight || "calc(100% - " + otherHeight + "px)";
1029
+ this.element.style.height = "calc(100% - " + otherHeight + "px)";
1030
+ this.element.style.maxHeight = "calc(100% - " + otherHeight + "px)";
1031
+ }else{
1032
+ this.element.style.height = "";
1033
+ this.element.style.height = (this.table.element.clientHeight - otherHeight) + "px";
1034
+ this.element.scrollTop = this.scrollTop;
1035
+ }
1036
+
1037
+ this.renderer.resize();
1038
+
1039
+ //check if the table has changed size when dealing with variable height tables
1040
+ if(!this.fixedHeight && initialHeight != this.element.clientHeight){
1041
+ if(this.subscribed("table-resize")){
1042
+ this.dispatch("table-resize");
1043
+ }else{
1044
+ this.redraw();
1045
+ }
1046
+ }
1047
+
1048
+ this.scrollBarCheck();
1049
+ }
1050
+
1051
+ this._positionPlaceholder();
1052
+ }
1053
+
1054
+ //reinitialize all rows
1055
+ reinitialize(){
1056
+ this.rows.forEach(function(row){
1057
+ row.reinitialize(true);
1058
+ });
1059
+ }
1060
+
1061
+ //prevent table from being redrawn
1062
+ blockRedraw (){
1063
+ this.redrawBlock = true;
1064
+ this.redrawBlockRestoreConfig = false;
1065
+ }
1066
+
1067
+ //restore table redrawing
1068
+ restoreRedraw (){
1069
+ this.redrawBlock = false;
1070
+
1071
+ if(this.redrawBlockRestoreConfig){
1072
+ this.refreshActiveData(this.redrawBlockRestoreConfig.handler, this.redrawBlockRestoreConfig.skipStage, this.redrawBlockRestoreConfig.renderInPosition);
1073
+
1074
+ this.redrawBlockRestoreConfig = false;
1075
+ }else{
1076
+ if(this.redrawBlockRenderInPosition){
1077
+ this.reRenderInPosition();
1078
+ }
1079
+ }
1080
+
1081
+ this.redrawBlockRenderInPosition = false;
1082
+ }
1083
+
1084
+ //redraw table
1085
+ redraw (force){
1086
+ var left = this.scrollLeft;
1087
+
1088
+ this.adjustTableSize();
1089
+
1090
+ this.table.tableWidth = this.table.element.clientWidth;
1091
+
1092
+ if(!force){
1093
+ this.reRenderInPosition();
1094
+ this.scrollHorizontal(left);
1095
+ }else{
1096
+ this.renderTable();
1097
+ }
1098
+ }
1099
+
1100
+ resetScroll(){
1101
+ this.element.scrollLeft = 0;
1102
+ this.element.scrollTop = 0;
1103
+
1104
+ if(this.table.browser === "ie"){
1105
+ var event = document.createEvent("Event");
1106
+ event.initEvent("scroll", false, true);
1107
+ this.element.dispatchEvent(event);
1108
+ }else{
1109
+ this.element.dispatchEvent(new Event('scroll'));
1110
+ }
1111
+ }
1112
+ }