@refinitiv-ui/efx-grid 6.0.52 → 6.0.54

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.
@@ -8,6 +8,8 @@ declare namespace FieldDefinition {
8
8
 
9
9
  function get(field: string): any;
10
10
 
11
+ function getFieldInfo(field: string): any;
12
+
11
13
  function hasFieldInfo(field: string): boolean;
12
14
 
13
15
  function getTimeSeriesChildren(field: string): any;
@@ -18,8 +20,6 @@ declare namespace FieldDefinition {
18
20
 
19
21
  function setSynapseConfig(config: Grid.SynapseConfig|null): void;
20
22
 
21
- function setFieldCaching(caching: boolean): void;
22
-
23
23
  function disableTimeSeriesExpansion(disabled: boolean): void;
24
24
 
25
25
  function isFormula(field: string): boolean;
@@ -10,9 +10,9 @@ import { Deferred } from "../../tr-grid-util/es6/Deferred.js";
10
10
  * @const
11
11
  */
12
12
  var SYNAPSE_URL =
13
- '/synapse/service/suggestions/suggest/?'
14
- + 'hits=1' // search only 1 result
15
- + '&profile=' + encodeURIComponent('Field Selector');
13
+ "/synapse/service/suggestions/suggest/?"
14
+ + "hits=1" // search only 1 result
15
+ + "&profile=" + encodeURIComponent("Field Selector");
16
16
 
17
17
  /* @namespace */
18
18
  var FieldDefinition = {};
@@ -129,18 +129,13 @@ FieldDefinition._timeSeriesChildren = {};
129
129
  * @private
130
130
  * @const
131
131
  */
132
- FieldDefinition._synapse = '';
132
+ FieldDefinition._synapse = "";
133
133
  /**
134
134
  * @type {string}
135
135
  * @private
136
136
  * @const
137
137
  */
138
- FieldDefinition._lang = 'en';
139
- /**
140
- * @type {boolean}
141
- * @private
142
- */
143
- FieldDefinition._caching = false;
138
+ FieldDefinition._lang = "en";
144
139
  /**
145
140
  * @type {boolean}
146
141
  * @private
@@ -167,17 +162,22 @@ FieldDefinition.set = function(field, def) {
167
162
  }
168
163
  }
169
164
  };
170
- /** @public
165
+ /** Get field definition object
166
+ * @public
171
167
  * @function
172
168
  * @param {string} field
173
169
  * @return {Object}
174
170
  */
175
171
  FieldDefinition.get = function(field) {
176
- if(this._caching) {
177
- return FieldDefinition._defs[field];
178
- }
179
- return null;
172
+ return FieldDefinition._defs[field] || null;
180
173
  };
174
+ /** Get field definition object
175
+ * @public
176
+ * @function
177
+ * @param {string} field
178
+ * @return {Object}
179
+ */
180
+ FieldDefinition.getFieldInfo = FieldDefinition.get;
181
181
 
182
182
  /** @public
183
183
  * @function
@@ -186,7 +186,7 @@ FieldDefinition.get = function(field) {
186
186
  */
187
187
  FieldDefinition.hasFieldInfo = function(field) {
188
188
  var val = FieldDefinition.get(field);
189
- return val && val.field; // Already preventing an error caused by accessing a property on a null value
189
+ return (val && val.field) ? true : false; // Already preventing an error caused by accessing a property on a null value
190
190
  };
191
191
 
192
192
  /** @public
@@ -222,15 +222,6 @@ FieldDefinition.remove = function(field) {
222
222
  */
223
223
  FieldDefinition.setSynapseConfig = function (config) {
224
224
  FieldDefinition._synapse = config;
225
-
226
- };
227
-
228
- /** @public
229
- * @function
230
- * @param {boolean} caching
231
- */
232
- FieldDefinition.setFieldCaching = function (caching) {
233
- FieldDefinition._caching = caching;
234
225
  };
235
226
 
236
227
  /** @public
@@ -355,7 +346,7 @@ FieldDefinition.getFieldProperty = function(field, propertyName) {
355
346
  return null;
356
347
  };
357
348
 
358
- /** to get more info about field via synapse service
349
+ /** To get more info about field via synapse service
359
350
  * @private
360
351
  * @param {string} field
361
352
  * @returns {Promise}
@@ -387,12 +378,12 @@ FieldDefinition.loadFieldInfo = function (field) {
387
378
  // everything fine, call synapse service
388
379
  else {
389
380
  var queryUrl = SYNAPSE_URL
390
- + '&api-key=' + encodeURIComponent(synapse.apiKey)
391
- + '&contextApp=' + encodeURIComponent(synapse.contextApp)
392
- + '&language=' + encodeURIComponent(FieldDefinition._lang)
393
- + '&query=' + encodeURIComponent(field);
381
+ + "&api-key=" + encodeURIComponent(synapse.apiKey)
382
+ + "&contextApp=" + encodeURIComponent(synapse.contextApp)
383
+ + "&language=" + encodeURIComponent(FieldDefinition._lang)
384
+ + "&query=" + encodeURIComponent(field);
394
385
  if (synapse.auth) {
395
- queryUrl += '&auth=' + encodeURIComponent(synapse.auth);
386
+ queryUrl += "&auth=" + encodeURIComponent(synapse.auth);
396
387
  }
397
388
  // TODO: handle client timeout
398
389
  var xmr = new XMLHttpRequest();
@@ -401,9 +392,9 @@ FieldDefinition.loadFieldInfo = function (field) {
401
392
  FieldDefinition._loadingField[field] = defer;
402
393
 
403
394
  // for now we care only successful case
404
- xmr.addEventListener('loadend', onLoadEnd);
405
- xmr.addEventListener('timeout', onError);
406
- xmr.addEventListener('error', onError);
395
+ xmr.addEventListener("loadend", onLoadEnd);
396
+ xmr.addEventListener("timeout", onError);
397
+ xmr.addEventListener("error", onError);
407
398
  xmr.open("GET", queryUrl, true); // true for asynchronous
408
399
  xmr.send();
409
400
  }
@@ -431,7 +422,7 @@ FieldDefinition._mockOnLoadEndData = function (field, defer) {
431
422
  var fieldUpperCase = field.toUpperCase();
432
423
  var fieldLowerCase = fieldUpperCase.toLowerCase();
433
424
  var label;
434
- if (fieldLowerCase.indexOf('_') === 2) { // transform XX_ABCD -> Abcd
425
+ if (fieldLowerCase.indexOf("_") === 2) { // transform XX_ABCD -> Abcd
435
426
  label = fieldUpperCase[3] + fieldLowerCase.substring(4);
436
427
  } else {
437
428
  label = fieldUpperCase[0] + fieldLowerCase.substring(1);
@@ -493,49 +484,49 @@ FieldDefinition._mockOnLoadEndData = function (field, defer) {
493
484
  function onLoadEnd(e) {
494
485
  var xmr = e.currentTarget;
495
486
  var defer = xmr._defer;
496
- var resolve = defer.resolve;
497
- var reject = defer.reject;
487
+ var field = xmr._field;
498
488
 
499
- delete FieldDefinition._loadingField[xmr._field];
489
+ delete FieldDefinition._loadingField[field];
500
490
 
501
491
  if (xmr.status === 200) { // case success
502
- var returnObj = {
503
- field: xmr._field,
504
- fieldDefinition: null
505
- };
506
492
  var res = JSON.parse(xmr.responseText);
493
+ var fieldDef = null;
507
494
 
508
495
  var result = res.result && res.result[0];
509
496
  if (result) {
510
497
  var item = result.hits && result.hits[0];
511
498
  if (item && item.p) {
512
499
  var profile = item.p;
513
- if (profile.fn.toUpperCase() === xmr._field.toUpperCase()) {
514
- var fieldDef = FieldDefinition.get(xmr._field) || {};
500
+ if (profile.fn.toUpperCase() === field.toUpperCase()) {
501
+ fieldDef = FieldDefinition.get(field) || {};
515
502
 
516
503
  fieldDef.field = profile.fn; // name
504
+ fieldDef.name = profile.fl; // label
517
505
  fieldDef.rank = profile.Rank;
518
506
  fieldDef.fieldDataType = profile.fdt; // data type
507
+ fieldDef.id = profile.fid;
519
508
  fieldDef.IsMonitorOnlyField = profile.fimo;
520
509
  fieldDef.IsRealtimePortfolioField = profile.firp;
521
510
  fieldDef.IsRealtimeField = profile.firt;
522
- fieldDef.name = profile.fl; // label
523
511
  fieldDef.source = profile.fsrc;
524
512
  fieldDef.sourceRank = profile.fsrnk;
525
513
  fieldDef.description = item.title;
526
514
 
527
- FieldDefinition.set(xmr._field, fieldDef);
528
- returnObj.fieldDefinition = fieldDef;
515
+ FieldDefinition.set(field, fieldDef);
529
516
  }
530
517
  }
531
518
  }
532
- resolve(returnObj);
519
+ if(fieldDef) {
520
+ defer.resolve(fieldDef);
521
+ } else {
522
+ defer.reject("No definition for " + field);
523
+ }
533
524
  } else if (xmr._error) { // case error && time out
534
- xmr._error.field = xmr._field;
535
- reject(xmr._error);
525
+ xmr._error.field = field;
526
+ defer.reject(xmr._error);
536
527
  } else { // case status not 200
537
- reject({
538
- field: xmr._field,
528
+ defer.reject({
529
+ field: field,
539
530
  status: xmr.status,
540
531
  statusText: xmr.statusText,
541
532
  request: xmr
@@ -133,9 +133,13 @@ declare class Grid extends EventDispatcher {
133
133
 
134
134
  public replaceColumn(columnOption: ColumnDefinition.Options|string|null, colRef: Grid.ColumnReference|null): void;
135
135
 
136
+ public getFieldInfo(field: string): any;
137
+
138
+ public loadFieldInfo(field: string): Promise<any>|null;
139
+
136
140
  public setColumns(columns: (any)[]|null): void;
137
141
 
138
- public restoreColumns(columns: (any)[]|null): void;
142
+ public restoreColumns(columns: (any)[]|null, byId?: boolean|null): void;
139
143
 
140
144
  public setFields(ary: (string)[]|null): void;
141
145
 
@@ -291,6 +291,19 @@ var _hasFieldOrId = function(colDef, str) {
291
291
  return (colDef.getField() === str) || (colDef.getId() === str);
292
292
  };
293
293
 
294
+ /** Compare the difference in the 'id' property.
295
+ * @private
296
+ * @param {Object} obj1
297
+ * @param {Object} obj2
298
+ * @returns {boolean} If the id property of two objects is equal, the return will be true, otherwise it will be false.
299
+ */
300
+ var _hasMatchingId = function(obj1, obj2) {
301
+ if(!obj1 || !obj2 || !obj1.id || !obj2.id) { // Handle nullable, if the object or id have null, it's means difference value
302
+ return false;
303
+ }
304
+ return obj1.id === obj2.id;
305
+ };
306
+
294
307
  /** @constructor
295
308
  * @extends {EventDispatcher}
296
309
  * @param {(Element|null)=} placeholder
@@ -840,7 +853,6 @@ Grid.prototype.initialize = function(gridOption) {
840
853
 
841
854
  if (gridOption["fieldCaching"]) {
842
855
  t._fieldCaching = gridOption["fieldCaching"];
843
- FieldDefinition.setFieldCaching(t._fieldCaching);
844
856
  }
845
857
 
846
858
  if(gridOption["timeSeriesExpansion"] != null) {
@@ -1590,8 +1602,8 @@ Grid.prototype.replaceColumn = function (columnOption, colRef) {
1590
1602
  * @param {Object} response
1591
1603
  */
1592
1604
  Grid.prototype._onFieldLoadedSuccess = function (field, colDef, response) {
1593
- if (response && response.fieldDefinition) {
1594
- var fieldDef = response.fieldDefinition;
1605
+ if (response && response.id) {
1606
+ var fieldDef = response;
1595
1607
  if (colDef && colDef.getField() === field) {
1596
1608
  if (colDef.isDefaultName() && fieldDef.name) {
1597
1609
  colDef.setName(fieldDef.name);
@@ -1639,6 +1651,34 @@ Grid.prototype._setScrollbarParent = function (host) {
1639
1651
  this._grid.getHScrollbar().attachToExternalElement(host);
1640
1652
  };
1641
1653
 
1654
+ /** Get stored field information. If field information has not been requested or no data has been received yet, null value is returned.
1655
+ * @public
1656
+ * @function
1657
+ * @param {string} field
1658
+ * @return {Object}
1659
+ */
1660
+ Grid.prototype.getFieldInfo = function(field) {
1661
+ return FieldDefinition.getFieldInfo(field);
1662
+ };
1663
+ /** Request field information from Synapse service. If field information already exists, a resolved promise is returned. Synapse config must be supplied before the request can be made.
1664
+ * @public
1665
+ * @function
1666
+ * @param {string} field
1667
+ * @return {Promise}
1668
+ * @example
1669
+ * var gridConfig = {
1670
+ * synapse: { // define synapse configuration
1671
+ * apiKey: "xxx",
1672
+ * contextApp: "xxx",
1673
+ * auth: "xxx" (optional)
1674
+ * }
1675
+ * };
1676
+ * var promise = grid.loadFieldInfo("CF_LAST");
1677
+ */
1678
+ Grid.prototype.loadFieldInfo = function(field) {
1679
+ return FieldDefinition.loadFieldInfo(field);
1680
+ };
1681
+
1642
1682
  /**
1643
1683
  * @private
1644
1684
  * @param {string} field
@@ -1697,8 +1737,9 @@ Grid.prototype.setColumns = function(columns) {
1697
1737
  /** Remove, add and keep column based on the given column data
1698
1738
  * @public
1699
1739
  * @param {Array.<Object>} columns Array of column options
1740
+ * @param {boolean=} byId=false, if enable it, this method will only check for differences in the 'id' property
1700
1741
  */
1701
- Grid.prototype.restoreColumns = function(columns) {
1742
+ Grid.prototype.restoreColumns = function(columns, byId) {
1702
1743
  var grid = this._grid;
1703
1744
  grid.startBatch("reset");
1704
1745
  var configObj = this.getConfigObject();
@@ -1707,6 +1748,7 @@ Grid.prototype.restoreColumns = function(columns) {
1707
1748
  var preColLen = previousColumns.length;
1708
1749
  var newColLen = columns.length;
1709
1750
 
1751
+ var compareLogic = byId ? _hasMatchingId : deepEqual;
1710
1752
  var removingFields = [];
1711
1753
  var keepingColumns = [];
1712
1754
  var columnOrdering = [];
@@ -1716,7 +1758,7 @@ Grid.prototype.restoreColumns = function(columns) {
1716
1758
  for (i = 0; i < preColLen; i++) {
1717
1759
  found = false;
1718
1760
  for (j = 0; j < newColLen; j++) {
1719
- if (deepEqual(previousColumns[i], columns[j])) {
1761
+ if(compareLogic(previousColumns[i], columns[j])) {
1720
1762
  keepingColumns.push(previousColumns[i]);
1721
1763
  found = true;
1722
1764
  break;
@@ -1737,7 +1779,7 @@ Grid.prototype.restoreColumns = function(columns) {
1737
1779
  for (i = 0; i < newColLen; i++) {
1738
1780
  found = false;
1739
1781
  for (j = 0; j < keepingLen; j++) { // loop only keeping column
1740
- if (deepEqual(columns[i], keepingColumns[j])) {
1782
+ if(compareLogic(columns[i], keepingColumns[j])) {
1741
1783
  found = true;
1742
1784
  var colIndex = this.getColumnIndex(columns[i].field); // We cannot use 'i' (colIndex) in this case, as it will sort the columns. Instead, we need to obtain a new column index from the field.
1743
1785
  columnOrdering.push(this.getColumnId(colIndex));
@@ -4,22 +4,22 @@ import { GridPlugin } from "../../tr-grid-util/es6/GridPlugin.js";
4
4
  declare namespace AutoTooltipPlugin {
5
5
 
6
6
  type Options = {
7
- header?: boolean,
8
- title?: boolean,
9
- footer?: boolean,
10
- content?: boolean,
11
- quickMode?: boolean
7
+ header?: boolean|null,
8
+ title?: boolean|null,
9
+ footer?: boolean|null,
10
+ content?: boolean|null,
11
+ quickMode?: boolean|null
12
12
  };
13
13
 
14
14
  type ColumnOptions = {
15
- autoTooltip?: boolean
15
+ autoTooltip?: boolean|null
16
16
  };
17
17
 
18
18
  }
19
19
 
20
20
  declare class AutoTooltipPlugin extends GridPlugin {
21
21
 
22
- constructor(options?: AutoTooltipPlugin.Options);
22
+ constructor(options?: AutoTooltipPlugin.Options|null);
23
23
 
24
24
  public getName(): string;
25
25
 
@@ -31,9 +31,9 @@ declare class AutoTooltipPlugin extends GridPlugin {
31
31
 
32
32
  public getConfigObject(gridOptions?: any): any;
33
33
 
34
- public applyTooltip(colIndex: number, fromR?: number, toR?: number): void;
34
+ public applyTooltip(colIndex: number, fromR?: number|null, toR?: number|null): void;
35
35
 
36
- public applyTooltipToColumns(colIndices?: (number)[]): void;
36
+ public applyTooltipToColumns(colIndices?: (number)[]|null): void;
37
37
 
38
38
  public applyTooltipToAllColumns(): void;
39
39
 
@@ -279,12 +279,14 @@ AutoTooltipPlugin.prototype.applyTooltipToAllColumns = function () {
279
279
  AutoTooltipPlugin.prototype._applyTooltipToSection = function (section, colIndex, fromR, toR) {
280
280
  if (!section) { return false; }
281
281
 
282
- if (!fromR) {
282
+ if (fromR == null) {
283
+ fromR = section.getFirstIndexInView();
284
+ } else if(!fromR) {
283
285
  fromR = 0;
284
286
  }
285
287
 
286
288
  if (toR == null) {
287
- toR = section.getRowCount();
289
+ toR = section.getLastIndexInView() + 1;
288
290
  }
289
291
 
290
292
  if (fromR >= toR) {
@@ -296,6 +298,10 @@ AutoTooltipPlugin.prototype._applyTooltipToSection = function (section, colIndex
296
298
  return false;
297
299
  }
298
300
 
301
+ if(columnObj.getVisibility && !columnObj.getVisibility()) {
302
+ return false;
303
+ }
304
+
299
305
  var colElem = columnObj.getElement();
300
306
  if (!colElem) {
301
307
  return false;
@@ -93,6 +93,8 @@ declare class ColumnGroupingPlugin extends GridPlugin {
93
93
 
94
94
  public unpinGroup(groupId: string, dest?: (number|string)|null): void;
95
95
 
96
+ public selectGroupHeaders(colIndices: (number)[]|null): void;
97
+
96
98
  public static getObjectIndex(column: any): number;
97
99
 
98
100
  public static getObjectId(column: any): string;
@@ -71,6 +71,10 @@ ColumnGroupingPlugin.prototype._rerenderTimerId = 0;
71
71
  /** @type {number}
72
72
  * @private
73
73
  */
74
+ ColumnGroupingPlugin.prototype._groupHeaderTimerId = 0;
75
+ /** @type {number}
76
+ * @private
77
+ */
74
78
  ColumnGroupingPlugin.prototype._addingTimerId = 0;
75
79
  /** @type {Array}
76
80
  * @private
@@ -84,6 +88,11 @@ ColumnGroupingPlugin.prototype._legacyColumnGroups = null;
84
88
  * @private
85
89
  */
86
90
  ColumnGroupingPlugin.prototype._inPinning = false;
91
+ /** @type {!Object.<string, boolean}
92
+ * @description A map of selected groups
93
+ * @private
94
+ */
95
+ ColumnGroupingPlugin.prototype._selectedColMap;
87
96
 
88
97
  /** @private
89
98
  * @param {number} a
@@ -298,6 +307,10 @@ ColumnGroupingPlugin.prototype.unload = function (host) {
298
307
  clearTimeout(this._rerenderTimerId);
299
308
  this._rerenderTimerId = 0;
300
309
  }
310
+ if (this._groupHeaderTimerId) {
311
+ clearTimeout(this._groupHeaderTimerId);
312
+ this._groupHeaderTimerId = 0;
313
+ }
301
314
  if (this._addingTimerId) {
302
315
  clearTimeout(this._addingTimerId);
303
316
  this._addingTimerId = 0;
@@ -485,6 +498,7 @@ ColumnGroupingPlugin.prototype._applyGrouping = function () {
485
498
  if (cell) {
486
499
  // TODO: The style and class from the user will not be reset, for example, the color or background
487
500
  cell.removeClass("no-sort");
501
+ cell.removeClass("selected-group");
488
502
  cell.removeAttribute("group-id");
489
503
  }
490
504
  }
@@ -655,6 +669,14 @@ ColumnGroupingPlugin.prototype._requestApplyGrouping = function () {
655
669
  this._rerenderTimerId = setTimeout(this._applyGrouping.bind(this), 10);
656
670
  }
657
671
  };
672
+ /** Set a timer to call renderGroups only once to avoid performance issue
673
+ * @private
674
+ */
675
+ ColumnGroupingPlugin.prototype._requestGroupRendering = function () {
676
+ if (!this._groupHeaderTimerId) {
677
+ this._groupHeaderTimerId = setTimeout(this.renderGroups.bind(this), 10);
678
+ }
679
+ };
658
680
  /** Apply nearest grouping to column.
659
681
  * @private
660
682
  * @param {number} colIndex
@@ -753,11 +775,16 @@ ColumnGroupingPlugin.prototype._spanGroupHorizontally = function (titleSection)
753
775
  spanIndices = [];
754
776
  groupDef = visibleGroupMap[id];
755
777
  colIds = GroupDefinitions.getLeafDescendants(visibleGroupMap, id);
778
+ var isAllSelected = this._selectedColMap ? true : false;
756
779
  for (i = 0; i < colIds.length; i++) {
757
- index = this._getColumnIndexById(colIds[i]);
780
+ var colId = colIds[i];
781
+ index = this._getColumnIndexById(colId);
758
782
  if (index > -1) {
759
783
  spanIndices.push(index);
760
784
  }
785
+ if (isAllSelected && this._selectedColMap) {
786
+ isAllSelected &= this._selectedColMap[colId];
787
+ }
761
788
  }
762
789
  spanIndices.sort(ColumnGroupingPlugin._ascSortLogic);
763
790
  len = spanIndices.length;
@@ -767,6 +794,10 @@ ColumnGroupingPlugin.prototype._spanGroupHorizontally = function (titleSection)
767
794
  var end = spanIndices[len - 1];
768
795
  section.setCellColSpan(start, groupDef["onRow"], end - start + 1);
769
796
  groupDef["colIndex"] = start;
797
+ if (isAllSelected) {
798
+ var cell = section.getCell(start, groupDef["onRow"]);
799
+ cell.addClass("selected-group");
800
+ }
770
801
  }
771
802
  }
772
803
  };
@@ -774,6 +805,7 @@ ColumnGroupingPlugin.prototype._spanGroupHorizontally = function (titleSection)
774
805
  * @public
775
806
  */
776
807
  ColumnGroupingPlugin.prototype.renderGroups = function () {
808
+ this._groupHeaderTimerId = 0;
777
809
  var hostCount = this._hosts.length;
778
810
  var groupMap = this._visibleGroupMap;
779
811
  for (var i = 0; i < hostCount; ++i) {
@@ -798,6 +830,17 @@ ColumnGroupingPlugin.prototype._renderGroup = function (groupDef, section) {
798
830
  }
799
831
  var rowIndex = groupDef["onRow"];
800
832
  var cell = section.getCell(colIndex, rowIndex);
833
+ var colIds = GroupDefinitions.getLeafDescendants(this._visibleGroupMap, groupDef["id"]);
834
+ var isAllSelected = false;
835
+ if (this._selectedColMap) {
836
+ isAllSelected = true;
837
+ for (var i = 0; i < colIds.length; i++) {
838
+ if (!this._selectedColMap[colIds[i]]) {
839
+ isAllSelected = false;
840
+ break;
841
+ }
842
+ }
843
+ }
801
844
  if (cell) {
802
845
  // Overide the defaults
803
846
  cell.setStyle("text-align", groupDef["alignment"] || "");
@@ -807,6 +850,11 @@ ColumnGroupingPlugin.prototype._renderGroup = function (groupDef, section) {
807
850
  // Additional cell settings must be removed in the _applyGrouping() method
808
851
  cell.addClass("no-sort");
809
852
  cell.setAttribute("group-id", groupDef["id"]);
853
+ if (isAllSelected) {
854
+ cell.addClass("selected-group");
855
+ } else {
856
+ cell.removeClass("selected-group");
857
+ }
810
858
  if (groupDef["legacyRender"]) {
811
859
  // Built-in version if render receive colIndex, cell, groupDefinition as arguments
812
860
  groupDef["legacyRender"](colIndex, cell, groupDef);
@@ -1710,6 +1758,26 @@ ColumnGroupingPlugin.prototype.unpinGroup = function (groupId, dest) {
1710
1758
  this.moveGroup(groupId, destId);
1711
1759
  }
1712
1760
  };
1761
+ /** @public
1762
+ * @param {Array<number>} colIndices
1763
+ */
1764
+ ColumnGroupingPlugin.prototype.selectGroupHeaders = function (colIndices) {
1765
+ var host = this._hosts[0];
1766
+ var count = colIndices.length;
1767
+ if (host && count) {
1768
+ var colIds = [];
1769
+ for (var i = 0; i < count; i++) {
1770
+ colIds.push(host.getColumnId(colIndices[i]));
1771
+ }
1772
+ var colMap = host.createColumnMap(colIds);
1773
+ if (colMap) {
1774
+ this._selectedColMap = colMap;
1775
+ }
1776
+ } else {
1777
+ this._selectedColMap = null;
1778
+ }
1779
+ this._requestGroupRendering();
1780
+ };
1713
1781
 
1714
1782
  /** Get column index from column object
1715
1783
  * @public
@@ -685,6 +685,8 @@ ColumnSelectionPlugin.prototype.clearAllSelections = function () {
685
685
 
686
686
  this._clearMenuIcon();
687
687
  }
688
+
689
+ this._updateGroupSelection();
688
690
  };
689
691
  /** Alias to clearAllSelections() method
690
692
  * @public
@@ -821,37 +823,14 @@ ColumnSelectionPlugin.prototype._isSelectedColumns = function (colIndices) {
821
823
 
822
824
  return isAllSelected;
823
825
  };
824
- /**
826
+ /** Update group selection according to current selected columns
825
827
  * @private
826
- * @param {Array<number>} colIndices
827
828
  */
828
829
 
829
830
 
830
831
  ColumnSelectionPlugin.prototype._updateGroupSelection = function () {
831
- var cgp = this._cgp;
832
- var grid = this._activeGrid;
833
-
834
- if (!cgp || !grid) {
835
- return;
836
- }
837
-
838
- var section = grid.getSection("title");
839
- var groupDefs = cgp.getGroupDefinitions();
840
- var count = groupDefs.length;
841
-
842
- for (var i = 0; i < count; i++) {
843
- var groupDef = groupDefs[i];
844
- var groupId = groupDef["id"];
845
- var childIndices = cgp.getChildColumnIndices(groupId);
846
- var rowIndex = cgp.getGroupLevel(groupId);
847
- var colIndex = childIndices[0];
848
- var cell = section.getCell(colIndex, rowIndex);
849
-
850
- if (this._isSelectedColumns(childIndices)) {
851
- cell.addClass("selected-group");
852
- } else {
853
- cell.removeClass("selected-group");
854
- }
832
+ if (this._cgp && this._cgp.selectGroupHeaders) {
833
+ this._cgp.selectGroupHeaders(this.getSelectedColumns());
855
834
  }
856
835
  };
857
836
  /** Left click on title causes selection change. <br>
@@ -1506,12 +1506,12 @@ ColumnStackPlugin.prototype._addRefToStack = function (stackOption, colIndex) {
1506
1506
  /** Remove unique ref of the specified index from the stack
1507
1507
  * @private
1508
1508
  * @param {Object} stackOption
1509
- * @param {string} colRef For removing state
1509
+ * @param {string} colId For removing state
1510
1510
  * @param {number} colIndex For updating UI
1511
1511
  * @return {boolean}
1512
1512
  */
1513
- ColumnStackPlugin.prototype._removeRefFromStack = function (stackOption, colRef, colIndex) {
1514
- if(!this._groupDefs.removeGroupChild(stackOption.id, colRef)) {
1513
+ ColumnStackPlugin.prototype._removeRefFromStack = function (stackOption, colId, colIndex) {
1514
+ if(!this._groupDefs.removeGroupChild(stackOption.id, colId)) {
1515
1515
  return false;
1516
1516
  }
1517
1517
 
@@ -1787,7 +1787,7 @@ ColumnStackPlugin.prototype.removeColumnFromStack = function(colRef) {
1787
1787
  }
1788
1788
 
1789
1789
  var colIndices = this.getColumnIndices(children);
1790
- this._removeRefFromStack(stack, colRef, colIndex);
1790
+ this._removeRefFromStack(stack, colId, colIndex);
1791
1791
 
1792
1792
  this.moveColumnById(colIndex, colIndices[memberCount - 1] + 1); // This assumes that the column order is already in correct position
1793
1793
 
@@ -1890,7 +1890,7 @@ ColumnStackPlugin.prototype.addStackChild = function(stackId, colRef) {
1890
1890
  */
1891
1891
  ColumnStackPlugin.prototype.removeStackChild = function(stackId, colRef) {
1892
1892
  if(stackId === this.getStackId(colRef)) {
1893
- this.removeColumnFromStack(colIndex);
1893
+ this.removeColumnFromStack(colRef);
1894
1894
  }
1895
1895
  };
1896
1896
  /** @public
@@ -24,6 +24,8 @@ declare class GroupDefinitions {
24
24
 
25
25
  public cloneGroupMap(): { [key: string]: any };
26
26
 
27
+ public rebuildMap(): void;
28
+
27
29
  public getGroupChildren(groupId: string): (string)[]|null;
28
30
 
29
31
  public getLeafDescendants(groupId: string): (string)[]|null;
@@ -46,10 +48,12 @@ declare class GroupDefinitions {
46
48
 
47
49
  public removeGroup(groupId: string): boolean;
48
50
 
49
- public setGroup(groupId: string, groupDef?: (string)[]|any|null): string;
51
+ public setGroup(groupId: string, groupDef?: ((string)[]|any)|null): string;
50
52
 
51
53
  public hasGroupChild(parentId: string, childId: string): boolean;
52
54
 
55
+ public contains(groupId: string, childId: string): boolean;
56
+
53
57
  public addGroupChild(parentId: string, childId: string, position?: number|null): boolean;
54
58
 
55
59
  public removeGroupChild(parentId: string, childId?: string|null): boolean;