tabulator-tables 5.0.8 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/.editorconfig +6 -0
  2. package/LICENSE +1 -1
  3. package/bower.json +1 -1
  4. package/build/rollup.js +2 -1
  5. package/dist/css/tabulator.css +26 -6
  6. package/dist/css/tabulator.css.map +1 -1
  7. package/dist/css/tabulator.min.css +1 -1
  8. package/dist/css/tabulator.min.css.map +1 -1
  9. package/dist/css/tabulator_bootstrap3.css +26 -6
  10. package/dist/css/tabulator_bootstrap3.css.map +1 -1
  11. package/dist/css/tabulator_bootstrap3.min.css +1 -1
  12. package/dist/css/tabulator_bootstrap3.min.css.map +1 -1
  13. package/dist/css/tabulator_bootstrap4.css +26 -6
  14. package/dist/css/tabulator_bootstrap4.css.map +1 -1
  15. package/dist/css/tabulator_bootstrap4.min.css +1 -1
  16. package/dist/css/tabulator_bootstrap4.min.css.map +1 -1
  17. package/dist/css/tabulator_bulma.css +26 -6
  18. package/dist/css/tabulator_bulma.css.map +1 -1
  19. package/dist/css/tabulator_bulma.min.css +1 -1
  20. package/dist/css/tabulator_bulma.min.css.map +1 -1
  21. package/dist/css/tabulator_materialize.css +33 -10
  22. package/dist/css/tabulator_materialize.css.map +1 -1
  23. package/dist/css/tabulator_materialize.min.css +1 -1
  24. package/dist/css/tabulator_materialize.min.css.map +1 -1
  25. package/dist/css/tabulator_midnight.css +30 -6
  26. package/dist/css/tabulator_midnight.css.map +1 -1
  27. package/dist/css/tabulator_midnight.min.css +1 -1
  28. package/dist/css/tabulator_midnight.min.css.map +1 -1
  29. package/dist/css/tabulator_modern.css +26 -6
  30. package/dist/css/tabulator_modern.css.map +1 -1
  31. package/dist/css/tabulator_modern.min.css +1 -1
  32. package/dist/css/tabulator_modern.min.css.map +1 -1
  33. package/dist/css/tabulator_semanticui.css +26 -6
  34. package/dist/css/tabulator_semanticui.css.map +1 -1
  35. package/dist/css/tabulator_semanticui.min.css +1 -1
  36. package/dist/css/tabulator_semanticui.min.css.map +1 -1
  37. package/dist/css/tabulator_simple.css +26 -6
  38. package/dist/css/tabulator_simple.css.map +1 -1
  39. package/dist/css/tabulator_simple.min.css +1 -1
  40. package/dist/css/tabulator_simple.min.css.map +1 -1
  41. package/dist/css/tabulator_site.css +30 -6
  42. package/dist/css/tabulator_site.css.map +1 -1
  43. package/dist/css/tabulator_site.min.css +1 -1
  44. package/dist/css/tabulator_site.min.css.map +1 -1
  45. package/dist/js/tabulator.js +1182 -548
  46. package/dist/js/tabulator.js.map +1 -1
  47. package/dist/js/tabulator.min.js +2 -2
  48. package/dist/js/tabulator.min.js.map +1 -1
  49. package/dist/js/tabulator_esm.js +1797 -1184
  50. package/dist/js/tabulator_esm.js.map +1 -1
  51. package/dist/js/tabulator_esm.min.js +2 -2
  52. package/dist/js/tabulator_esm.min.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/js/core/ColumnManager.js +1 -1
  55. package/src/js/core/CoreFeature.js +1 -5
  56. package/src/js/core/FooterManager.js +14 -2
  57. package/src/js/core/RowManager.js +325 -286
  58. package/src/js/core/Tabulator.js +0 -43
  59. package/src/js/core/cell/Cell.js +5 -1
  60. package/src/js/core/column/Column.js +21 -6
  61. package/src/js/core/column/ColumnComponent.js +6 -0
  62. package/src/js/core/column/defaults/options.js +1 -0
  63. package/src/js/core/defaults/options.js +3 -3
  64. package/src/js/core/modules/optional.js +1 -0
  65. package/src/js/core/rendering/Renderer.js +3 -2
  66. package/src/js/core/rendering/renderers/BasicVertical.js +2 -1
  67. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +165 -151
  68. package/src/js/core/rendering/renderers/VirtualDomVertical.js +1 -1
  69. package/src/js/core/row/Row.js +2 -2
  70. package/src/js/core/tools/DataLoader.js +6 -6
  71. package/src/js/core/tools/InteractionMonitor.js +157 -52
  72. package/src/js/modules/Ajax/Ajax.js +62 -82
  73. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +16 -3
  74. package/src/js/modules/DataTree/DataTree.js +22 -9
  75. package/src/js/modules/Download/defaults/downloaders/json.js +1 -1
  76. package/src/js/modules/Download/defaults/downloaders/jsonLines.js +32 -0
  77. package/src/js/modules/Download/defaults/downloaders/pdf.js +0 -2
  78. package/src/js/modules/Download/defaults/downloaders/xlsx.js +3 -2
  79. package/src/js/modules/Download/defaults/downloaders.js +2 -0
  80. package/src/js/modules/Edit/Edit.js +27 -39
  81. package/src/js/modules/Export/Export.js +1 -1
  82. package/src/js/modules/Filter/Filter.js +1 -1
  83. package/src/js/modules/Format/defaults/formatters/datetime.js +1 -1
  84. package/src/js/modules/Format/defaults/formatters/datetimediff.js +2 -1
  85. package/src/js/modules/FrozenColumns/FrozenColumns.js +1 -1
  86. package/src/js/modules/FrozenRows/FrozenRows.js +9 -0
  87. package/src/js/modules/GroupRows/Group.js +8 -63
  88. package/src/js/modules/GroupRows/GroupComponent.js +1 -1
  89. package/src/js/modules/GroupRows/GroupRows.js +2 -2
  90. package/src/js/modules/Import/Import.js +195 -0
  91. package/src/js/modules/Import/defaults/importers/csv.js +63 -0
  92. package/src/js/modules/Import/defaults/importers/json.js +8 -0
  93. package/src/js/modules/Import/defaults/importers.js +7 -0
  94. package/src/js/modules/Interaction/Interaction.js +5 -0
  95. package/src/js/modules/Keybindings/Keybindings.js +9 -14
  96. package/src/js/modules/Keybindings/defaults/bindings.js +3 -3
  97. package/src/js/modules/Localize/defaults/langs.js +6 -0
  98. package/src/js/modules/Menu/Menu.js +200 -155
  99. package/src/js/modules/MoveRows/MoveRows.js +4 -0
  100. package/src/js/modules/Page/Page.js +282 -185
  101. package/src/js/modules/Page/defaults/pageCounters/pages.js +33 -0
  102. package/src/js/modules/Page/defaults/pageCounters/rows.js +32 -0
  103. package/src/js/modules/Page/defaults/pageCounters.js +8 -0
  104. package/src/js/modules/ResizeRows/ResizeRows.js +1 -1
  105. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +7 -9
  106. package/src/js/modules/SelectRow/SelectRow.js +4 -9
  107. package/src/js/modules/Sort/defaults/sorters/datetime.js +2 -2
  108. package/src/js/modules/Validate/Validate.js +7 -5
  109. package/src/scss/tabulator.scss +31 -8
  110. package/src/scss/themes/materialize/tabulator_materialize.scss +5 -4
  111. package/src/scss/themes/tabulator_midnight.scss +4 -0
  112. package/src/scss/themes/tabulator_site.scss +4 -0
@@ -0,0 +1,32 @@
1
+ export default function (list, options, setFileContents) {
2
+ const fileContents = [];
3
+
4
+ list.forEach((row) => {
5
+ const item = {};
6
+
7
+ switch (row.type) {
8
+ case "header":
9
+ break;
10
+
11
+ case "group":
12
+ console.warn("Download Warning - JSON downloader cannot process row groups");
13
+ break;
14
+
15
+ case "calc":
16
+ console.warn("Download Warning - JSON downloader cannot process column calculations");
17
+ break;
18
+
19
+ case "row":
20
+ row.columns.forEach((col) => {
21
+ if (col) {
22
+ item[col.component.getTitleDownload() || col.component.getField()] = col.value;
23
+ }
24
+ });
25
+
26
+ fileContents.push(JSON.stringify(item));
27
+ break;
28
+ }
29
+ });
30
+
31
+ setFileContents(fileContents.join("\n"), "application/x-ndjson");
32
+ };
@@ -77,8 +77,6 @@ export default function(list, options, setFileContents){
77
77
  }
78
78
 
79
79
  rowData.push(cell);
80
- }else{
81
- rowData.push("");
82
80
  }
83
81
  });
84
82
 
@@ -26,7 +26,9 @@ export default function(list, options, setFileContents){
26
26
  rowData.push(!(col.value instanceof Date) && typeof col.value === "object" ? JSON.stringify(col.value) : col.value);
27
27
 
28
28
  if(col.width > 1 || col.height > -1){
29
- merges.push({s:{r:i,c:j},e:{r:i + col.height - 1,c:j + col.width - 1}});
29
+ if(col.height > 1 || col.width > 1){
30
+ merges.push({s:{r:i,c:j},e:{r:i + col.height - 1,c:j + col.width - 1}});
31
+ }
30
32
  }
31
33
  }else{
32
34
  rowData.push("");
@@ -36,7 +38,6 @@ export default function(list, options, setFileContents){
36
38
  rows.push(rowData);
37
39
  });
38
40
 
39
-
40
41
  //convert rows to worksheet
41
42
  XLSX.utils.sheet_add_aoa(worksheet, rows);
42
43
 
@@ -3,10 +3,12 @@ import json from './downloaders/json.js';
3
3
  import pdf from './downloaders/pdf.js';
4
4
  import xlsx from './downloaders/xlsx.js';
5
5
  import html from './downloaders/html.js';
6
+ import jsonLines from './downloaders/jsonLines.js';
6
7
 
7
8
  export default {
8
9
  csv:csv,
9
10
  json:json,
11
+ jsonLines:jsonLines,
10
12
  pdf:pdf,
11
13
  xlsx:xlsx,
12
14
  html:html,
@@ -52,14 +52,14 @@ class Edit extends Module{
52
52
  this.subscribe("column-layout", this.initializeColumnCheck.bind(this));
53
53
  this.subscribe("column-delete", this.columnDeleteCheck.bind(this));
54
54
  this.subscribe("row-deleting", this.rowDeleteCheck.bind(this));
55
- this.subscribe("data-refeshing", this.cancelEdit.bind(this));
55
+ this.subscribe("data-refreshing", this.cancelEdit.bind(this));
56
56
 
57
- this.subscribe("keybinding-nav-prev", this.navigatePrev.bind(this));
57
+ this.subscribe("keybinding-nav-prev", this.navigatePrev.bind(this, undefined));
58
58
  this.subscribe("keybinding-nav-next", this.keybindingNavigateNext.bind(this));
59
- this.subscribe("keybinding-nav-left", this.navigateLeft.bind(this));
60
- this.subscribe("keybinding-nav-right", this.navigateRight.bind(this));
61
- this.subscribe("keybinding-nav-up", this.navigateUp.bind(this));
62
- this.subscribe("keybinding-nav-down", this.navigateDown.bind(this));
59
+ this.subscribe("keybinding-nav-left", this.navigateLeft.bind(this, undefined));
60
+ this.subscribe("keybinding-nav-right", this.navigateRight.bind(this, undefined));
61
+ this.subscribe("keybinding-nav-up", this.navigateUp.bind(this, undefined));
62
+ this.subscribe("keybinding-nav-down", this.navigateDown.bind(this, undefined));
63
63
  }
64
64
 
65
65
 
@@ -72,7 +72,7 @@ class Edit extends Module{
72
72
  newRow = this.options("tabEndNewRow");
73
73
 
74
74
  if(cell){
75
- if(!this.navigateNext(e)){
75
+ if(!this.navigateNext(cell, e)){
76
76
  if(newRow){
77
77
  cell.getElement().firstChild.blur();
78
78
 
@@ -88,7 +88,7 @@ class Edit extends Module{
88
88
 
89
89
  newRow.then(() => {
90
90
  setTimeout(() => {
91
- nav.next();
91
+ cell.getComponent().navigateNext();
92
92
  })
93
93
  });
94
94
  }
@@ -118,7 +118,7 @@ class Edit extends Module{
118
118
  ///////////////////////////////////
119
119
  clearCellEdited(cells){
120
120
  if(!cells){
121
- cells = this.modules.edit.getEditedCells();
121
+ cells = this.table.modules.edit.getEditedCells();
122
122
  }
123
123
 
124
124
  if(!Array.isArray(cells)){
@@ -126,13 +126,12 @@ class Edit extends Module{
126
126
  }
127
127
 
128
128
  cells.forEach((cell) => {
129
- this.modules.edit.clearEdited(cell._getSelf());
129
+ this.table.modules.edit.clearEdited(cell._getSelf());
130
130
  });
131
131
  }
132
132
 
133
- navigatePrev(e){
134
- var cell = this.currentCell,
135
- nextCell, prevRow;
133
+ navigatePrev(cell = this.currentCell, e){
134
+ var nextCell, prevRow;
136
135
 
137
136
  if(cell){
138
137
 
@@ -161,9 +160,8 @@ class Edit extends Module{
161
160
  return false;
162
161
  }
163
162
 
164
- navigateNext(e){
165
- var cell = this.currentCell,
166
- nextCell, nextRow;
163
+ navigateNext(cell = this.currentCell, e){
164
+ var nextCell, nextRow;
167
165
 
168
166
  if(cell){
169
167
 
@@ -192,9 +190,8 @@ class Edit extends Module{
192
190
  return false;
193
191
  }
194
192
 
195
- navigateLeft(e){
196
- var cell = this.currentCell,
197
- index, nextCell;
193
+ navigateLeft(cell = this.currentCell, e){
194
+ var index, nextCell;
198
195
 
199
196
  if(cell){
200
197
 
@@ -214,9 +211,8 @@ class Edit extends Module{
214
211
  return false;
215
212
  }
216
213
 
217
- navigateRight(e){
218
- var cell = this.currentCell,
219
- index, nextCell;
214
+ navigateRight(cell = this.currentCell, e){
215
+ var index, nextCell;
220
216
 
221
217
  if(cell){
222
218
 
@@ -236,9 +232,8 @@ class Edit extends Module{
236
232
  return false;
237
233
  }
238
234
 
239
- navigateUp(e){
240
- var cell = this.currentCell,
241
- index, nextRow;
235
+ navigateUp(cell = this.currentCell, e){
236
+ var index, nextRow;
242
237
 
243
238
  if(cell){
244
239
 
@@ -258,9 +253,8 @@ class Edit extends Module{
258
253
  return false;
259
254
  }
260
255
 
261
- navigateDown(e){
262
- var cell = this.currentCell,
263
- index, nextRow;
256
+ navigateDown(cell = this.currentCell, e){
257
+ var index, nextRow;
264
258
 
265
259
  if(cell){
266
260
 
@@ -411,14 +405,15 @@ class Edit extends Module{
411
405
  cellEl = cell.getElement();
412
406
 
413
407
  if(cancel){
414
- if(cell.validate){
415
- cell.validate();
408
+ if(cell.column.modules.validate && this.table.modExists("validate")){
409
+ this.table.modules.validate.cellValidate(cell);
416
410
  }
417
411
  }else{
418
412
  cellEl.classList.remove("tabulator-validation-fail");
419
413
  }
420
414
 
421
415
  cellEl.classList.remove("tabulator-editing");
416
+
422
417
  while(cellEl.firstChild) cellEl.removeChild(cellEl.firstChild);
423
418
 
424
419
  cell.row.getElement().classList.remove("tabulator-row-editing");
@@ -442,6 +437,7 @@ class Edit extends Module{
442
437
  cell.column.definition.cellEditCancelled.call(this.table, component);
443
438
  }
444
439
 
440
+ this.dispatch("edit-cancelled", cell);
445
441
  this.dispatchExternal("cellEditCancelled", component);
446
442
  }
447
443
  }
@@ -572,10 +568,6 @@ class Edit extends Module{
572
568
 
573
569
  cell.setValue(value, true);
574
570
 
575
- if(self.table.options.dataTree && self.table.modExists("dataTree")){
576
- self.table.modules.dataTree.checkForRestyle(cell);
577
- }
578
-
579
571
  if(valid !== true){
580
572
  element.classList.add("tabulator-validation-fail");
581
573
  self.table.externalEvents.dispatch("validationFailed", cell.getComponent(), value, valid);
@@ -600,10 +592,6 @@ class Edit extends Module{
600
592
  function cancel(){
601
593
  if(self.currentCell === cell){
602
594
  self.cancelEdit();
603
-
604
- if(self.table.options.dataTree && self.table.modExists("dataTree")){
605
- self.table.modules.dataTree.checkForRestyle(cell);
606
- }
607
595
  }else{
608
596
  // console.warn("Edit Success Error - cannot call cancel on a cell that is no longer being edited");
609
597
  }
@@ -735,4 +723,4 @@ Edit.moduleName = "edit";
735
723
  Edit.editors = defaultEditors;
736
724
 
737
725
 
738
- export default Edit;
726
+ export default Edit;
@@ -63,7 +63,7 @@ class Export extends Module{
63
63
  switch(range){
64
64
  case true:
65
65
  case "visible":
66
- rows = this.table.rowManager.getVisibleRows(true);
66
+ rows = this.table.rowManager.getVisibleRows(false, true);
67
67
  break;
68
68
 
69
69
  case "all":
@@ -382,7 +382,7 @@ class Filter extends Module{
382
382
 
383
383
  params = column.definition.headerFilterParams || {};
384
384
 
385
- params = typeof params === "function" ? params.call(self.table) : params;
385
+ params = typeof params === "function" ? params.call(self.table, cellWrapper) : params;
386
386
 
387
387
  editorElement = editor.call(this.table.modules.edit, cellWrapper, function(){}, success, cancel, params);
388
388
 
@@ -6,7 +6,7 @@ export default function(cell, formatterParams, onRendered){
6
6
  var value = cell.getValue();
7
7
 
8
8
  if(typeof DT != "undefined"){
9
- var newDatetime = DT.fromFormat(String(value), inputFormat);
9
+ var newDatetime = inputFormat === "iso" ? DT.fromISO(String(value)) : DT.fromFormat(String(value), inputFormat);
10
10
 
11
11
  if(newDatetime.isValid){
12
12
 
@@ -9,7 +9,8 @@ export default function (cell, formatterParams, onRendered) {
9
9
  var value = cell.getValue();
10
10
 
11
11
  if(typeof DT != "undefined"){
12
- var newDatetime = DT.fromFormat(String(value), inputFormat);
12
+
13
+ var newDatetime = inputFormat === "iso" ? DT.fromISO(String(value)) : DT.fromFormat(String(value), inputFormat);
13
14
 
14
15
  if (newDatetime.isValid){
15
16
  if(humanize){
@@ -35,7 +35,7 @@ class FrozenColumns extends Module{
35
35
  this.subscribe("cell-layout", this.layoutCell.bind(this));
36
36
  this.subscribe("column-init", this.initializeColumn.bind(this));
37
37
  this.subscribe("column-width", this.layout.bind(this));
38
- this.subscribe("row-layout-before", this.layoutRow.bind(this));
38
+ this.subscribe("row-layout-after", this.layoutRow.bind(this));
39
39
  this.subscribe("table-layout", this.layout.bind(this));
40
40
  this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this));
41
41
  this.subscribe("columns-loading", this.reset.bind(this));
@@ -23,6 +23,7 @@ class FrozenRows extends Module{
23
23
  this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
24
24
 
25
25
  this.subscribe("row-deleting", this.detachRow.bind(this));
26
+ this.subscribe("rows-visible", this.visibleRows.bind(this));
26
27
 
27
28
  this.registerDisplayHandler(this.getRows.bind(this), 10);
28
29
  }
@@ -36,6 +37,14 @@ class FrozenRows extends Module{
36
37
  return !!this.rows.length;
37
38
  }
38
39
 
40
+ visibleRows(viewable, rows){
41
+ this.rows.forEach((row) => {
42
+ rows.push(row);
43
+ });
44
+
45
+ return rows;
46
+ }
47
+
39
48
  //filter frozen rows out of display data
40
49
  getRows(rows){
41
50
  var self = this,
@@ -18,6 +18,7 @@ class Group{
18
18
  this.groups = [];
19
19
  this.groupList = [];
20
20
  this.generator = generator;
21
+ this.element = false;
21
22
  this.elementContents = false;
22
23
  this.height = 0;
23
24
  this.outerHeight = 0;
@@ -85,67 +86,7 @@ class Group{
85
86
  }
86
87
 
87
88
  addBindings(){
88
- var dblTap, tapHold, tap, toggleElement;
89
-
90
- if ((this.groupManager.table.options.groupContextMenu || this.groupManager.table.options.groupClickMenu) && this.groupManager.table.modExists("menu")){
91
- this.groupManager.table.modules.menu.initializeGroup.call(this.groupManager.table.modules.menu, this);
92
- }
93
-
94
- if (this.groupManager.table.options.groupTap){
95
- tap = false;
96
-
97
- this.element.addEventListener("touchstart", (e) => {
98
- tap = true;
99
- }, {passive: true});
100
-
101
- this.element.addEventListener("touchend", (e) => {
102
- if(tap){
103
- this.groupManager.table.options.groupTap(e, this.getComponent());
104
- }
105
-
106
- tap = false;
107
- });
108
- }
109
-
110
- if (this.groupManager.table.options.groupDblTap){
111
- dblTap = null;
112
-
113
- this.element.addEventListener("touchend", (e) => {
114
- if(dblTap){
115
- clearTimeout(dblTap);
116
- dblTap = null;
117
-
118
- this.groupManager.table.options.groupDblTap(e, this.getComponent());
119
- }else{
120
-
121
- dblTap = setTimeout(() => {
122
- clearTimeout(dblTap);
123
- dblTap = null;
124
- }, 300);
125
- }
126
- });
127
- }
128
-
129
- if (this.groupManager.table.options.groupTapHold){
130
- tapHold = null;
131
-
132
- this.element.addEventListener("touchstart", (e) => {
133
- clearTimeout(tapHold);
134
-
135
- tapHold = setTimeout(() => {
136
- clearTimeout(tapHold);
137
- tapHold = null;
138
- tap = false;
139
- this.groupManager.table.options.groupTapHold(e, this.getComponent());
140
- }, 1000);
141
-
142
- }, {passive: true});
143
-
144
- this.element.addEventListener("touchend", (e) => {
145
- clearTimeout(tapHold);
146
- tapHold = null;
147
- });
148
- }
89
+ var toggleElement;
149
90
 
150
91
  if(this.groupManager.table.options.groupToggleElement){
151
92
  toggleElement = this.groupManager.table.options.groupToggleElement == "arrow" ? this.arrowElement : this.element;
@@ -454,7 +395,7 @@ class Group{
454
395
 
455
396
  this.element.classList.add("tabulator-group-visible");
456
397
 
457
- var prev = this.getElement();
398
+ var prev = this.generateElement();
458
399
 
459
400
  if(this.groupList.length){
460
401
  this.groupList.forEach((group) => {
@@ -572,7 +513,11 @@ class Group{
572
513
  ////////////// Standard Row Functions //////////////
573
514
 
574
515
  getElement(){
575
- this.addBindingsd = false;
516
+ return this.elementContents ? this.element : this.generateElement();
517
+ }
518
+
519
+ generateElement(){
520
+ this.addBindings = false;
576
521
 
577
522
  this._visSet();
578
523
 
@@ -9,7 +9,7 @@ class GroupComponent {
9
9
  if (typeof target[name] !== "undefined") {
10
10
  return target[name];
11
11
  }else{
12
- return target._group.table.componentFunctionBinder.handle("row", target._group, name)
12
+ return target._group.groupManager.table.componentFunctionBinder.handle("row", target._group, name)
13
13
  }
14
14
  }
15
15
  })
@@ -47,13 +47,13 @@ class GroupRows extends Module{
47
47
  initialize(){
48
48
  if(this.table.options.groupBy){
49
49
 
50
- this.configureGroupSetup();
51
-
52
50
  if(this.table.options.groupUpdateOnCellEdit){
53
51
  this.subscribe("cell-value-updated", this.cellUpdated.bind(this));
54
52
  this.subscribe("row-data-changed", this.reassignRowToGroup.bind(this), 0);
55
53
  }
56
54
 
55
+ this.subscribe("table-built", this.configureGroupSetup.bind(this));
56
+
57
57
  this.subscribe("row-deleting", this.rowDeleting.bind(this));
58
58
  this.subscribe("row-deleted", this.rowsUpdated.bind(this));
59
59
  this.subscribe("scroll-horizontal", this.scrollHeaders.bind(this));
@@ -0,0 +1,195 @@
1
+ import Module from '../../core/Module.js';
2
+
3
+ import defaultImporters from './defaults/importers.js';
4
+
5
+ class Import extends Module{
6
+
7
+ constructor(table){
8
+ super(table);
9
+
10
+ this.registerTableOption("importFormat");
11
+ this.registerTableOption("importReader", "text");
12
+ }
13
+
14
+ initialize(){
15
+ this.registerTableFunction("import", this.importFromFile.bind(this));
16
+
17
+ if(this.table.options.importFormat){
18
+ this.subscribe("data-loading", this.loadDataCheck.bind(this), 10);
19
+ this.subscribe("data-load", this.loadData.bind(this), 10);
20
+ }
21
+ }
22
+
23
+ loadDataCheck(data){
24
+ return typeof data === "string";
25
+ }
26
+
27
+ loadData(data, params, config, silent, previousData){
28
+ return this.importData(this.lookupImporter(), data)
29
+ .then(this.structureData.bind(this))
30
+ .catch((err) => {
31
+ console.error("Import Error:", err || "Unable to import data")
32
+ return Promise.reject(err);
33
+ })
34
+ }
35
+
36
+ lookupImporter(importFormat){
37
+ var importer;
38
+
39
+ if(!importFormat){
40
+ importFormat = this.table.options.importFormat;
41
+ }
42
+
43
+ if(typeof importFormat === "string"){
44
+ importer = Import.importers[importFormat];
45
+ }else{
46
+ importer = importFormat;
47
+ }
48
+
49
+ if(!importer){
50
+ console.error("Import Error - Importer not found:", importFormat);
51
+ }
52
+
53
+ return importer;
54
+ }
55
+
56
+ importFromFile(importFormat, extension){
57
+ var importer = this.lookupImporter(importFormat);
58
+
59
+ if(importer){
60
+ return this.pickFile(extension)
61
+ .then(this.importData.bind(this, importer))
62
+ .then(this.structureData.bind(this))
63
+ .then(this.setData.bind(this))
64
+ .catch((err) => {
65
+ console.error("Import Error:", err || "Unable to import file")
66
+ return Promise.reject(err);
67
+ })
68
+ }
69
+ }
70
+
71
+ pickFile(extensions){
72
+ return new Promise((resolve, reject) => {
73
+ var input = document.createElement("input");
74
+ input.type = "file";
75
+ input.accept = extensions;
76
+
77
+ input.addEventListener("change", (e) => {
78
+ var file = input.files[0],
79
+ reader = new FileReader(),
80
+ data;
81
+
82
+ switch(this.table.options.importReader){
83
+ case "buffer":
84
+ reader.readAsArrayBuffer(file);
85
+ break;
86
+
87
+ case "binary":
88
+ reader.readAsBinaryString(file);
89
+ break;
90
+
91
+ case "url":
92
+ reader.readAsDataURL(file);
93
+ break;
94
+
95
+ case "text":
96
+ default:
97
+ reader.readAsText(file);
98
+ }
99
+
100
+ reader.onload = (e) => {
101
+ resolve(reader.result)
102
+ };
103
+
104
+ reader.onerror = (e) => {
105
+ console.warn("File Load Error - Unable to read file");
106
+ reject();
107
+ };
108
+ });
109
+
110
+ input.click();
111
+ });
112
+ }
113
+
114
+ importData(importer, fileContents){
115
+ var data = importer.call(this.table, fileContents);
116
+
117
+ if(data instanceof Promise){
118
+ return data;
119
+ }else{
120
+ return data ? Promise.resolve(data) : Promise.reject();
121
+ }
122
+ }
123
+
124
+ structureData(parsedData){
125
+ var data = [];
126
+
127
+ if(Array.isArray(parsedData) && parsedData.length && Array.isArray(parsedData[0])){
128
+ if(this.table.options.autoColumns){
129
+ data = this.structureArrayToObject(parsedData);
130
+ }else{
131
+ data = this.structureArrayToColumns(parsedData);
132
+ }
133
+
134
+ return data;
135
+ }else{
136
+ return parsedData;
137
+ }
138
+ }
139
+
140
+ structureArrayToObject(parsedData){
141
+ var columns = parsedData.shift();
142
+
143
+ var data = parsedData.map((values) => {
144
+ var row = {};
145
+
146
+ columns.forEach((key, i) => {
147
+ row[key] = values[i];
148
+ })
149
+
150
+ return row;
151
+ })
152
+
153
+ return data;
154
+ }
155
+
156
+ structureArrayToColumns(parsedData){
157
+ var data = [],
158
+ columns = this.table.getColumns();
159
+
160
+ //remove first row if it is the column names
161
+ if(columns[0] && parsedData[0][0]){
162
+ if(columns[0].getDefinition().title === parsedData[0][0]){
163
+ parsedData.shift();
164
+ }
165
+ }
166
+
167
+ //convert row arrays to objects
168
+ parsedData.forEach((rowData) => {
169
+ var row = {};
170
+
171
+ rowData.forEach((value, index) => {
172
+ var column = columns[index];
173
+
174
+ if(column){
175
+ row[column.getField()] = value;
176
+ }
177
+ })
178
+
179
+ data.push(row);
180
+ });
181
+
182
+ return data;
183
+ }
184
+
185
+ setData(data){
186
+ return this.table.setData(data);
187
+ }
188
+ }
189
+
190
+ Import.moduleName = "import";
191
+
192
+ //load defaults
193
+ Import.importers = defaultImporters;
194
+
195
+ export default Import;