tabulator-tables 5.4.4 → 5.5.0

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 (96) hide show
  1. package/bower.json +1 -1
  2. package/dist/css/tabulator.css +80 -48
  3. package/dist/css/tabulator.css.map +1 -1
  4. package/dist/css/tabulator.min.css +1 -1
  5. package/dist/css/tabulator.min.css.map +1 -1
  6. package/dist/css/tabulator_bootstrap3.css +89 -53
  7. package/dist/css/tabulator_bootstrap3.css.map +1 -1
  8. package/dist/css/tabulator_bootstrap3.min.css +1 -1
  9. package/dist/css/tabulator_bootstrap3.min.css.map +1 -1
  10. package/dist/css/tabulator_bootstrap4.css +106 -68
  11. package/dist/css/tabulator_bootstrap4.css.map +1 -1
  12. package/dist/css/tabulator_bootstrap4.min.css +1 -1
  13. package/dist/css/tabulator_bootstrap4.min.css.map +1 -1
  14. package/dist/css/tabulator_bootstrap5.css +110 -70
  15. package/dist/css/tabulator_bootstrap5.css.map +1 -1
  16. package/dist/css/tabulator_bootstrap5.min.css +1 -1
  17. package/dist/css/tabulator_bootstrap5.min.css.map +1 -1
  18. package/dist/css/tabulator_bulma.css +95 -57
  19. package/dist/css/tabulator_bulma.css.map +1 -1
  20. package/dist/css/tabulator_bulma.min.css +1 -1
  21. package/dist/css/tabulator_bulma.min.css.map +1 -1
  22. package/dist/css/tabulator_materialize.css +93 -58
  23. package/dist/css/tabulator_materialize.css.map +1 -1
  24. package/dist/css/tabulator_materialize.min.css +1 -1
  25. package/dist/css/tabulator_materialize.min.css.map +1 -1
  26. package/dist/css/tabulator_midnight.css +90 -54
  27. package/dist/css/tabulator_midnight.css.map +1 -1
  28. package/dist/css/tabulator_midnight.min.css +1 -1
  29. package/dist/css/tabulator_midnight.min.css.map +1 -1
  30. package/dist/css/tabulator_modern.css +96 -57
  31. package/dist/css/tabulator_modern.css.map +1 -1
  32. package/dist/css/tabulator_modern.min.css +1 -1
  33. package/dist/css/tabulator_modern.min.css.map +1 -1
  34. package/dist/css/tabulator_semanticui.css +131 -75
  35. package/dist/css/tabulator_semanticui.css.map +1 -1
  36. package/dist/css/tabulator_semanticui.min.css +1 -1
  37. package/dist/css/tabulator_semanticui.min.css.map +1 -1
  38. package/dist/css/tabulator_simple.css +80 -48
  39. package/dist/css/tabulator_simple.css.map +1 -1
  40. package/dist/css/tabulator_simple.min.css +1 -1
  41. package/dist/css/tabulator_simple.min.css.map +1 -1
  42. package/dist/css/tabulator_site.css +88 -52
  43. package/dist/css/tabulator_site.css.map +1 -1
  44. package/dist/css/tabulator_site.min.css +1 -1
  45. package/dist/css/tabulator_site.min.css.map +1 -1
  46. package/dist/js/tabulator.js +363 -158
  47. package/dist/js/tabulator.js.map +1 -1
  48. package/dist/js/tabulator.min.js +2 -2
  49. package/dist/js/tabulator.min.js.map +1 -1
  50. package/dist/js/tabulator_esm.js +363 -158
  51. package/dist/js/tabulator_esm.js.map +1 -1
  52. package/dist/js/tabulator_esm.min.js +2 -2
  53. package/dist/js/tabulator_esm.min.js.map +1 -1
  54. package/package.json +1 -1
  55. package/src/js/core/ColumnManager.js +15 -0
  56. package/src/js/core/RowManager.js +57 -41
  57. package/src/js/core/cell/CellComponent.js +5 -3
  58. package/src/js/core/column/ColumnComponent.js +2 -2
  59. package/src/js/core/rendering/renderers/BasicHorizontal.js +7 -2
  60. package/src/js/core/rendering/renderers/BasicVertical.js +8 -5
  61. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +6 -1
  62. package/src/js/core/rendering/renderers/VirtualDomVertical.js +85 -31
  63. package/src/js/core/row/RowComponent.js +2 -2
  64. package/src/js/modules/ColumnCalcs/defaults/calculations.js +7 -0
  65. package/src/js/modules/DataTree/DataTree.js +1 -1
  66. package/src/js/modules/Download/defaults/downloaders/xlsx.js +5 -2
  67. package/src/js/modules/Edit/Edit.js +2 -3
  68. package/src/js/modules/Edit/List.js +14 -3
  69. package/src/js/modules/Edit/defaults/editors/date.js +1 -1
  70. package/src/js/modules/Edit/defaults/editors/datetime.js +1 -1
  71. package/src/js/modules/Edit/defaults/editors/input.js +1 -1
  72. package/src/js/modules/Edit/defaults/editors/number.js +1 -1
  73. package/src/js/modules/Edit/defaults/editors/range.js +1 -1
  74. package/src/js/modules/Edit/defaults/editors/textarea.js +1 -1
  75. package/src/js/modules/Edit/defaults/editors/tickCross.js +1 -1
  76. package/src/js/modules/Edit/defaults/editors/time.js +1 -1
  77. package/src/js/modules/Export/Export.js +3 -0
  78. package/src/js/modules/Filter/Filter.js +11 -0
  79. package/src/js/modules/Format/Format.js +3 -0
  80. package/src/js/modules/Format/defaults/formatters/money.js +9 -2
  81. package/src/js/modules/FrozenColumns/FrozenColumns.js +1 -1
  82. package/src/js/modules/GroupRows/GroupComponent.js +4 -0
  83. package/src/js/modules/Interaction/Interaction.js +12 -0
  84. package/src/js/modules/Persistence/Persistence.js +15 -1
  85. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +3 -0
  86. package/src/js/modules/SelectRow/SelectRow.js +82 -54
  87. package/src/scss/tabulator.scss +82 -50
  88. package/src/scss/themes/bootstrap/tabulator_bootstrap3.scss +9 -5
  89. package/src/scss/themes/bootstrap/tabulator_bootstrap4.scss +27 -19
  90. package/src/scss/themes/bootstrap/tabulator_bootstrap5.scss +29 -19
  91. package/src/scss/themes/bulma/tabulator_bulma.scss +15 -9
  92. package/src/scss/themes/materialize/tabulator_materialize.scss +14 -10
  93. package/src/scss/themes/semanticui/tabulator_semanticui.scss +52 -27
  94. package/src/scss/themes/tabulator_midnight.scss +10 -6
  95. package/src/scss/themes/tabulator_modern.scss +16 -8
  96. package/src/scss/themes/tabulator_site.scss +8 -4
@@ -18,7 +18,7 @@ export default class Edit{
18
18
 
19
19
  this.initialValues = null;
20
20
 
21
- this.isFilter = !cell._getSelf;
21
+ this.isFilter = cell.getType() === "header";
22
22
 
23
23
  this.filterTimeout = null;
24
24
  this.filtered = false;
@@ -84,7 +84,7 @@ export default class Edit{
84
84
  function clickStop(e){
85
85
  e.stopPropagation();
86
86
  }
87
-
87
+
88
88
  if(!this.isFilter){
89
89
  this.input.style.height = "100%";
90
90
  this.input.focus({preventScroll: true});
@@ -308,6 +308,7 @@ export default class Edit{
308
308
  break;
309
309
 
310
310
  case 9: //tab
311
+ this._keyTab(e);
311
312
  break;
312
313
 
313
314
  default:
@@ -354,6 +355,16 @@ export default class Edit{
354
355
  //////// Keyboard Navigation /////////
355
356
  //////////////////////////////////////
356
357
 
358
+ _keyTab(e){
359
+ if(this.params.autocomplete && this.lastAction === "typing"){
360
+ this._resolveValue(true);
361
+ }else{
362
+ if(this.focusedItem){
363
+ this._chooseItem(this.focusedItem, true);
364
+ }
365
+ }
366
+ }
367
+
357
368
  _keyUp(e){
358
369
  var index = this.displayItems.indexOf(this.focusedItem);
359
370
 
@@ -991,7 +1002,7 @@ export default class Edit{
991
1002
 
992
1003
  _resolveValue(blur){
993
1004
  var output, initialValue;
994
-
1005
+
995
1006
  if(this.popup){
996
1007
  this.popup.hide(true);
997
1008
  }
@@ -59,7 +59,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
59
59
  input.value = cellValue;
60
60
 
61
61
  onRendered(function(){
62
- if(cell._getSelf){
62
+ if(cell.getType() === "cell"){
63
63
  input.focus({preventScroll: true});
64
64
  input.style.height = "100%";
65
65
 
@@ -46,7 +46,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
46
46
  input.value = cellValue;
47
47
 
48
48
  onRendered(function(){
49
- if(cell._getSelf){
49
+ if(cell.getType() === "cell"){
50
50
  input.focus({preventScroll: true});
51
51
  input.style.height = "100%";
52
52
 
@@ -26,7 +26,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
26
26
  input.value = typeof cellValue !== "undefined" ? cellValue : "";
27
27
 
28
28
  onRendered(function(){
29
- if(cell._getSelf){
29
+ if(cell.getType() === "cell"){
30
30
  input.focus({preventScroll: true});
31
31
  input.style.height = "100%";
32
32
 
@@ -43,7 +43,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
43
43
  };
44
44
 
45
45
  onRendered(function () {
46
- if(cell._getSelf){
46
+ if(cell.getType() === "cell"){
47
47
  //submit new value on blur
48
48
  input.removeEventListener("blur", blurFunc);
49
49
 
@@ -36,7 +36,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
36
36
  input.value = cellValue;
37
37
 
38
38
  onRendered(function () {
39
- if(cell._getSelf){
39
+ if(cell.getType() === "cell"){
40
40
  input.focus({preventScroll: true});
41
41
  input.style.height = "100%";
42
42
  }
@@ -31,7 +31,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
31
31
  input.value = value;
32
32
 
33
33
  onRendered(function(){
34
- if(cell._getSelf){
34
+ if(cell.getType() === "cell"){
35
35
  input.focus({preventScroll: true});
36
36
  input.style.height = "100%";
37
37
 
@@ -32,7 +32,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
32
32
 
33
33
  if(this.table.browser != "firefox" && this.table.browser != "safari"){ //prevent blur issue on mac firefox
34
34
  onRendered(function(){
35
- if(cell._getSelf){
35
+ if(cell.getType() === "cell"){
36
36
  input.focus({preventScroll: true});
37
37
  }
38
38
  });
@@ -47,7 +47,7 @@ export default function(cell, onRendered, success, cancel, editorParams){
47
47
  input.value = cellValue;
48
48
 
49
49
  onRendered(function(){
50
- if(cell._getSelf){
50
+ if(cell.getType() == "cell"){
51
51
  input.focus({preventScroll: true});
52
52
  input.style.height = "100%";
53
53
 
@@ -489,6 +489,9 @@ class Export extends Module{
489
489
  getElement:function(){
490
490
  return cellEl;
491
491
  },
492
+ getType:function(){
493
+ return "cell";
494
+ },
492
495
  getColumn:function(){
493
496
  return column.getComponent();
494
497
  },
@@ -22,6 +22,7 @@ class Filter extends Module{
22
22
  this.registerTableOption("initialFilter", false); //initial filtering criteria
23
23
  this.registerTableOption("initialHeaderFilter", false); //initial header filtering criteria
24
24
  this.registerTableOption("headerFilterLiveFilterDelay", 300); //delay before updating column after user types in header filter
25
+ this.registerTableOption("placeholderHeaderFilter", false); //placeholder when header filter is empty
25
26
 
26
27
  this.registerColumnOption("headerFilter");
27
28
  this.registerColumnOption("headerFilterPlaceholder");
@@ -57,6 +58,7 @@ class Filter extends Module{
57
58
  this.subscribe("column-width-fit-before", this.hideHeaderFilterElements.bind(this));
58
59
  this.subscribe("column-width-fit-after", this.showHeaderFilterElements.bind(this));
59
60
  this.subscribe("table-built", this.tableBuilt.bind(this));
61
+ this.subscribe("placeholder", this.generatePlaceholder.bind(this));
60
62
 
61
63
  if(this.table.options.filterMode === "remote"){
62
64
  this.subscribe("data-params", this.remoteFilterParams.bind(this));
@@ -92,6 +94,12 @@ class Filter extends Module{
92
94
  return params;
93
95
  }
94
96
 
97
+ generatePlaceholder(text){
98
+ if(this.table.options.placeholderHeaderFilter && Object.keys(this.headerFilters).length){
99
+ return this.table.options.placeholderHeaderFilter;
100
+ }
101
+ }
102
+
95
103
  ///////////////////////////////////
96
104
  ///////// Table Functions /////////
97
105
  ///////////////////////////////////
@@ -375,6 +383,9 @@ class Filter extends Module{
375
383
  getTable:() => {
376
384
  return this.table;
377
385
  },
386
+ getType:() => {
387
+ return "header";
388
+ },
378
389
  getRow:function(){
379
390
  return {
380
391
  normalizeHeight:function(){
@@ -96,6 +96,9 @@ class Format extends Module{
96
96
  getElement:function(){
97
97
  return el;
98
98
  },
99
+ getType:function(){
100
+ return "header";
101
+ },
99
102
  getColumn:function(){
100
103
  return column.getComponent();
101
104
  },
@@ -1,7 +1,7 @@
1
1
  export default function(cell, formatterParams, onRendered){
2
2
  var floatVal = parseFloat(cell.getValue()),
3
3
  sign = "",
4
- number, integer, decimal, rgx;
4
+ number, integer, decimal, rgx, value;
5
5
 
6
6
  var decimalSym = formatterParams.decimal || ".";
7
7
  var thousandSym = formatterParams.thousand || ",";
@@ -33,5 +33,12 @@ export default function(cell, formatterParams, onRendered){
33
33
  }
34
34
  }
35
35
 
36
- return after ? sign + integer + decimal + symbol : sign + symbol + integer + decimal;
36
+ value = integer + decimal;
37
+
38
+ if(sign === true){
39
+ value = "(" + value + ")";
40
+ return after ? value + symbol : symbol + value;
41
+ }else{
42
+ return after ? sign + value + symbol : sign + symbol + value;
43
+ }
37
44
  }
@@ -257,7 +257,7 @@ class FrozenColumns extends Module{
257
257
  layoutElement(element, column){
258
258
  var position;
259
259
 
260
- if(column.modules.frozen){
260
+ if(column.modules.frozen && element){
261
261
  element.style.position = "sticky";
262
262
 
263
263
  if(this.table.rtl){
@@ -55,6 +55,10 @@ class GroupComponent {
55
55
  this._group.toggleVisibility();
56
56
  }
57
57
 
58
+ scrollTo(position, ifVisible){
59
+ return this._group.groupManager.table.rowManager.scrollToRow(this._group, position, ifVisible);
60
+ }
61
+
58
62
  _getSelf(){
59
63
  return this._group;
60
64
  }
@@ -134,8 +134,20 @@ class Interaction extends Module{
134
134
 
135
135
  this.subscribe("column-init", this.initializeColumn.bind(this));
136
136
  this.subscribe("cell-dblclick", this.cellContentsSelectionFixer.bind(this));
137
+ this.subscribe("scroll-horizontal", this.clearTouchWatchers.bind(this));
138
+ this.subscribe("scroll-vertical", this.clearTouchWatchers.bind(this));
137
139
  }
138
140
 
141
+ clearTouchWatchers(){
142
+ var types = Object.values(this.touchWatchers);
143
+
144
+ types.forEach((type) => {
145
+ for(let key in type){
146
+ type[key] = null;
147
+ }
148
+ });
149
+ }
150
+
139
151
  cellContentsSelectionFixer(e, cell){
140
152
  var range;
141
153
 
@@ -88,6 +88,7 @@ class Persistence extends Module{
88
88
  this.config = {
89
89
  sort:this.table.options.persistence === true || this.table.options.persistence.sort,
90
90
  filter:this.table.options.persistence === true || this.table.options.persistence.filter,
91
+ headerFilter:this.table.options.persistence === true || this.table.options.persistence.headerFilter,
91
92
  group:this.table.options.persistence === true || this.table.options.persistence.group,
92
93
  page:this.table.options.persistence === true || this.table.options.persistence.page,
93
94
  columns:this.table.options.persistence === true ? ["title", "width", "visible"] : this.table.options.persistence.columns,
@@ -138,6 +139,7 @@ class Persistence extends Module{
138
139
  this.subscribe("table-redraw", this.tableRedraw.bind(this));
139
140
 
140
141
  this.subscribe("filter-changed", this.eventSave.bind(this, "filter"));
142
+ this.subscribe("filter-changed", this.eventSave.bind(this, "headerFilter"));
141
143
  this.subscribe("sort-changed", this.eventSave.bind(this, "sort"));
142
144
  this.subscribe("group-changed", this.eventSave.bind(this, "group"));
143
145
  this.subscribe("page-changed", this.eventSave.bind(this, "page"));
@@ -157,7 +159,7 @@ class Persistence extends Module{
157
159
  }
158
160
 
159
161
  tableBuilt(){
160
- var sorters, filters;
162
+ var sorters, filters, headerFilters;
161
163
 
162
164
  if(this.config.sort){
163
165
  sorters = this.load("sort");
@@ -174,6 +176,14 @@ class Persistence extends Module{
174
176
  this.table.options.initialFilter = filters;
175
177
  }
176
178
  }
179
+ if(this.config.headerFilter){
180
+ headerFilters = this.load("headerFilter");
181
+
182
+ if(!headerFilters === false){
183
+ this.table.options.initialHeaderFilter = headerFilters;
184
+ }
185
+ }
186
+
177
187
  }
178
188
 
179
189
  tableRedraw(force){
@@ -334,6 +344,10 @@ class Persistence extends Module{
334
344
  data = this.table.modules.filter.getFilters();
335
345
  break;
336
346
 
347
+ case "headerFilter":
348
+ data = this.table.modules.filter.getHeaderFilters();
349
+ break;
350
+
337
351
  case "sort":
338
352
  data = this.validateSorters(this.table.modules.sort.getSort());
339
353
  break;
@@ -272,6 +272,9 @@ class ResponsiveLayout extends Module{
272
272
  getData:function(){
273
273
  return data;
274
274
  },
275
+ getType:function(){
276
+ return "cell";
277
+ },
275
278
  getElement:function(){
276
279
  return document.createElement("div");
277
280
  },
@@ -194,7 +194,7 @@ class SelectRow extends Module{
194
194
  }
195
195
 
196
196
  checkRowSelectability(row){
197
- if(row.type === "row"){
197
+ if(row && row.type === "row"){
198
198
  return this.table.options.selectableCheck.call(this.table, row.getComponent());
199
199
  }
200
200
 
@@ -214,48 +214,44 @@ class SelectRow extends Module{
214
214
 
215
215
  //select a number of rows
216
216
  selectRows(rows){
217
- var rowMatch;
217
+ var changes = [],
218
+ rowMatch, change;
218
219
 
219
220
  switch(typeof rows){
220
221
  case "undefined":
221
- this.table.rowManager.rows.forEach((row) => {
222
- this._selectRow(row, true, true);
223
- });
224
-
225
- this._rowSelectionChanged();
222
+ rowMatch = this.table.rowManager.rows;
226
223
  break;
227
224
 
228
225
  case "string":
229
226
  rowMatch = this.table.rowManager.findRow(rows);
230
227
 
231
- if(rowMatch){
232
- this._selectRow(rowMatch, true, true);
233
- this._rowSelectionChanged();
234
- }else{
228
+ if(!rowMatch){
235
229
  rowMatch = this.table.rowManager.getRows(rows);
236
-
237
- rowMatch.forEach((row) => {
238
- this._selectRow(row, true, true);
239
- });
240
-
241
- if(rowMatch.length){
242
- this._rowSelectionChanged();
243
- }
244
230
  }
245
231
  break;
246
232
 
247
233
  default:
248
- if(Array.isArray(rows)){
249
- rows.forEach((row) => {
250
- this._selectRow(row, true, true);
251
- });
252
-
253
- this._rowSelectionChanged();
254
- }else{
255
- this._selectRow(rows, false, true);
256
- }
234
+ rowMatch = rows;
257
235
  break;
258
236
  }
237
+
238
+ if(Array.isArray(rowMatch)){
239
+ if(rowMatch.length){
240
+ rowMatch.forEach((row) => {
241
+ change = this._selectRow(row, true, true);
242
+
243
+ if(change){
244
+ changes.push(change);
245
+ }
246
+ });
247
+
248
+ this._rowSelectionChanged(false, changes);
249
+ }
250
+ }else{
251
+ if(rowMatch){
252
+ this._selectRow(rowMatch, false, true);
253
+ }
254
+ }
259
255
  }
260
256
 
261
257
  //select an individual row
@@ -293,7 +289,9 @@ class SelectRow extends Module{
293
289
 
294
290
  this.dispatchExternal("rowSelected", row.getComponent());
295
291
 
296
- this._rowSelectionChanged(silent);
292
+ this._rowSelectionChanged(silent, row);
293
+
294
+ return row;
297
295
  }
298
296
  }else{
299
297
  if(!silent){
@@ -308,39 +306,51 @@ class SelectRow extends Module{
308
306
 
309
307
  //deselect a number of rows
310
308
  deselectRows(rows, silent){
311
- var self = this,
312
- rowCount;
309
+ var changes = [],
310
+ rowMatch, change;
313
311
 
314
- if(typeof rows == "undefined"){
312
+ switch(typeof rows){
313
+ case "undefined":
314
+ rowMatch = Object.assign([], this.selectedRows);
315
+ break;
315
316
 
316
- rowCount = self.selectedRows.length;
317
+ case "string":
318
+ rowMatch = this.table.rowManager.findRow(rows);
317
319
 
318
- for(let i = 0; i < rowCount; i++){
319
- self._deselectRow(self.selectedRows[0], true);
320
- }
320
+ if(!rowMatch){
321
+ rowMatch = this.table.rowManager.getRows(rows);
322
+ }
323
+ break;
321
324
 
322
- if(rowCount){
323
- self._rowSelectionChanged(silent);
325
+ default:
326
+ rowMatch = rows;
327
+ break;
328
+ }
329
+
330
+ if(Array.isArray(rowMatch)){
331
+ if(rowMatch.length){
332
+ rowMatch.forEach((row) => {
333
+ change = this._deselectRow(row, true, true);
334
+
335
+ if(change){
336
+ changes.push(change);
337
+ }
338
+ });
339
+
340
+ this._rowSelectionChanged(silent, [], changes);
324
341
  }
325
-
326
342
  }else{
327
- if(Array.isArray(rows)){
328
- rows.forEach(function(row){
329
- self._deselectRow(row, true);
330
- });
331
-
332
- self._rowSelectionChanged(silent);
333
- }else{
334
- self._deselectRow(rows, silent);
343
+ if(rowMatch){
344
+ this._deselectRow(rowMatch, silent, true);
335
345
  }
336
- }
346
+ }
337
347
  }
338
348
 
339
349
  //deselect an individual row
340
350
  _deselectRow(rowInfo, silent){
341
351
  var self = this,
342
352
  row = self.table.rowManager.findRow(rowInfo),
343
- index;
353
+ index, element;
344
354
 
345
355
  if(row){
346
356
  index = self.selectedRows.findIndex(function(selectedRow){
@@ -348,8 +358,13 @@ class SelectRow extends Module{
348
358
  });
349
359
 
350
360
  if(index > -1){
361
+
362
+ element = row.getElement();
363
+
364
+ if(element){
365
+ element.classList.remove("tabulator-selected");
366
+ }
351
367
 
352
- row.getElement().classList.remove("tabulator-selected");
353
368
  if(!row.modules.select){
354
369
  row.modules.select = {};
355
370
  }
@@ -366,7 +381,9 @@ class SelectRow extends Module{
366
381
 
367
382
  this.dispatchExternal("rowDeselected", row.getComponent());
368
383
 
369
- self._rowSelectionChanged(silent);
384
+ self._rowSelectionChanged(silent, undefined, row);
385
+
386
+ return row;
370
387
  }
371
388
  }else{
372
389
  if(!silent){
@@ -386,7 +403,6 @@ class SelectRow extends Module{
386
403
  }
387
404
 
388
405
  getSelectedRows(){
389
-
390
406
  var rows = [];
391
407
 
392
408
  this.selectedRows.forEach(function(row){
@@ -396,7 +412,7 @@ class SelectRow extends Module{
396
412
  return rows;
397
413
  }
398
414
 
399
- _rowSelectionChanged(silent){
415
+ _rowSelectionChanged(silent, selected = [], deselected = []){
400
416
  if(this.headerCheckboxElement){
401
417
  if(this.selectedRows.length === 0){
402
418
  this.headerCheckboxElement.checked = false;
@@ -411,7 +427,19 @@ class SelectRow extends Module{
411
427
  }
412
428
 
413
429
  if(!silent){
414
- this.dispatchExternal("rowSelectionChanged", this.getSelectedData(), this.getSelectedRows());
430
+ if(!Array.isArray(selected)){
431
+ selected = [selected];
432
+ }
433
+
434
+ selected = selected.map(row => row.getComponent());
435
+
436
+ if(!Array.isArray(deselected)){
437
+ deselected = [deselected];
438
+ }
439
+
440
+ deselected = deselected.map(row => row.getComponent());
441
+
442
+ this.dispatchExternal("rowSelectionChanged", this.getSelectedData(), this.getSelectedRows(), selected, deselected);
415
443
  }
416
444
  }
417
445