@refinitiv-ui/efx-grid 6.0.83 → 6.0.84

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.
@@ -563,6 +563,10 @@ Core.prototype._batches = null;
563
563
  * @private
564
564
  */
565
565
  Core.prototype._firstRendered = false;
566
+ /** @type {boolean}
567
+ * @private
568
+ */
569
+ Core.prototype._hasPendingRowChange = false;
566
570
  //#region Public Methods
567
571
 
568
572
  /**
@@ -570,7 +574,7 @@ Core.prototype._firstRendered = false;
570
574
  * @return {string}
571
575
  */
572
576
  Core.getVersion = function () {
573
- return "5.1.86";
577
+ return "5.1.87";
574
578
  };
575
579
  /** {@link ElementWrapper#dispose}
576
580
  * @override
@@ -4772,8 +4776,8 @@ Core.prototype._setColumnWidth = function (colIndex, px, opt_scalable) {
4772
4776
  * @param {*=} ctx
4773
4777
  */
4774
4778
  Core.prototype._dispatchColumnAddedEvent = function (at, count, atTheMiddle, ctx) {
4779
+ var e = {};
4775
4780
  if (this._hasListener("columnAdded")) {
4776
- var e = {};
4777
4781
  e["atTheMiddle"] = atTheMiddle;
4778
4782
  if(count === 1) {
4779
4783
  e["colIndex"] = at;
@@ -4789,7 +4793,11 @@ Core.prototype._dispatchColumnAddedEvent = function (at, count, atTheMiddle, ctx
4789
4793
  }
4790
4794
  }
4791
4795
 
4792
- this._dispatchColumnRenderEvent({},
4796
+ if(this._frozenLayout){
4797
+ e["noDataUpdate"] = true;
4798
+ }
4799
+
4800
+ this._dispatchColumnRenderEvent(e,
4793
4801
  at, at + count,
4794
4802
  0, this._settings.length,
4795
4803
  NaN, NaN);
@@ -5399,9 +5407,13 @@ Core.prototype._onRowCountChanged = function (e) {
5399
5407
  }
5400
5408
  }
5401
5409
 
5410
+ var noBinding = e["noBinding"];
5402
5411
  var paneChanged = (sectionIndex <= this._startVScrollbarIndex) || (sectionIndex >= this._getFooterStartIndex());
5403
5412
  var forceUpdate = this._frozenFooterCount > 0 ? true : false; // Prevent from footer section flashing
5404
- var viewChanged = this._updateScrollbarHeight(paneChanged, forceUpdate, e["noBinding"]); // Virtualization is triggered
5413
+ var viewChanged = this._updateScrollbarHeight(paneChanged, forceUpdate, noBinding); // Virtualization is triggered
5414
+ if(noBinding){
5415
+ this._hasPendingRowChange = true;
5416
+ }
5405
5417
  if(!this._frozenLayout && !viewChanged) { // Grid must activate newly created section if no event is dispatched from the row virtualizer
5406
5418
  if(this._rowVirtualizer.isVirtualizable()) {
5407
5419
  section.activateRows(this._rowVirtualizer.getFirstIndexInView(),
@@ -5410,6 +5422,7 @@ Core.prototype._onRowCountChanged = function (e) {
5410
5422
  section.activateRows();
5411
5423
  }
5412
5424
  }
5425
+ this._hasPendingRowChange = false;
5413
5426
 
5414
5427
  if(!forceUpdate) {
5415
5428
  this._updateVScrollbar(); // Asynchronous
@@ -5493,6 +5506,9 @@ Core.prototype._containsSection = function (s) {
5493
5506
  * @param {!Object} e
5494
5507
  */
5495
5508
  Core.prototype._onRowAvailable = function (e) {
5509
+ if(this._hasPendingRowChange){
5510
+ return;
5511
+ }
5496
5512
  var sectionIndex = /** @type{number} */(e["sectionIndex"]);
5497
5513
  this._dispatchColumnRenderEvent(e,
5498
5514
  0, this.getColumnCount(),
@@ -2478,7 +2478,6 @@ LayoutGrid.prototype.updateColumnSeparators = function () {
2478
2478
  }
2479
2479
  }
2480
2480
  };
2481
-
2482
2481
  /** @private
2483
2482
  * @return {Element}
2484
2483
  */
@@ -35,7 +35,8 @@ const _toItemStates = function(val, idx) {
35
35
  label: _toLabelText(val),
36
36
  checked: (val && val.checked) ? true : false,
37
37
  index: idx,
38
- elem: null
38
+ elem: null,
39
+ value: val.value
39
40
  };
40
41
  };
41
42
  /** @private
@@ -270,7 +271,8 @@ class CheckboxList extends BasicElement {
270
271
  if(_getCheckedState(state)) {
271
272
  items.push({
272
273
  title: state.label,
273
- index: i
274
+ index: i,
275
+ value: state.value
274
276
  });
275
277
  }
276
278
  }
@@ -27,6 +27,7 @@ declare namespace FilterDialog {
27
27
  sortState?: string|null,
28
28
  sortUI?: boolean|null,
29
29
  filterUI?: boolean|null,
30
+ blankValues?: (string|boolean)|null,
30
31
  filterChanged?: ((...params: any[]) => any)|null,
31
32
  confirm?: ((...params: any[]) => any)|null,
32
33
  cancel?: ((...params: any[]) => any)|null,
@@ -25,12 +25,20 @@ import "./checkbox-list.js";
25
25
  * @property {string=} sortState "a" for ascending or "d" for descending
26
26
  * @property {boolean=} sortUI Show Sort area
27
27
  * @property {boolean=} filterUI Show Filter area
28
+ * @property {(string|boolean)=} blankValues Display a Blanks item in the filter dialog to represent an empty value. If a string is passed, it will be used as the label for the blank item
28
29
  * @property {Function=} filterChanged Filter changed handler
29
30
  * @property {Function=} confirm Alias of filterChanged
30
31
  * @property {Function=} cancel Alias of dialog cancel
31
32
  * @property {Function=} sortChanged Sort changed handler
32
33
  */
33
34
 
35
+
36
+ /** @type {string}
37
+ * @private
38
+ * @constant
39
+ */
40
+ const BLANKS = "(Blanks)";
41
+
34
42
  /** @type {number}
35
43
  * @private
36
44
  * @constant
@@ -58,6 +66,14 @@ const DEFAULT_FILTERS = [
58
66
  * @private
59
67
  * @constant
60
68
  */
69
+ const BLANK_FILTERS = [
70
+ ["EQ_BLANK", "Equal To Blank Value"],
71
+ ["NEQ_BLANK", "Does Not Equal To Blank Value"]
72
+ ];
73
+ /** @type {Array.<Array>}
74
+ * @private
75
+ * @constant
76
+ */
61
77
  const DATE_FILTERS = [
62
78
  ["DT", "Date is"],
63
79
  ["DTB", "Date is Before"],
@@ -150,6 +166,8 @@ class FilterDialog extends BasicElement {
150
166
  this.isShown = false;
151
167
  this.sortState = "n";
152
168
  this.fieldDataType = "";
169
+ this._blankValues = false;
170
+ this._blankValuesChecked = false;
153
171
  this.useUTCTime = true;
154
172
  this._popup = new Popup({
155
173
  "shown": this._onPopupShown.bind(this),
@@ -193,6 +211,19 @@ class FilterDialog extends BasicElement {
193
211
  this.hiddenFilterUI = options.filterUI === false;
194
212
  }
195
213
 
214
+ if(options.blankValues != null ) {
215
+ this._blankValues = options.blankValues;
216
+ }
217
+
218
+ this._blankValuesChecked = false;
219
+ if(options.blankValuesChecked != null) {
220
+ this._blankValuesChecked = options.blankValuesChecked;
221
+ }
222
+
223
+ if(this._blankValues) {
224
+ this._addBlankItem();
225
+ }
226
+
196
227
  if (options.target) {
197
228
  this.target = options.target;
198
229
  this._popup.attachTo(this.target);
@@ -594,6 +625,8 @@ class FilterDialog extends BasicElement {
594
625
  if(oper) {
595
626
  if(val || val === 0) {
596
627
  return true;
628
+ } else { // Blank operations don't need value
629
+ return oper === BLANK_FILTERS[0][0] || oper === BLANK_FILTERS[1][0];
597
630
  }
598
631
  }
599
632
  return false;
@@ -743,6 +776,9 @@ class FilterDialog extends BasicElement {
743
776
  } else {
744
777
  filterItems = DEFAULT_FILTERS;
745
778
  }
779
+ if(this._blankValues) {
780
+ filterItems = filterItems.concat(BLANK_FILTERS);
781
+ }
746
782
  var translated = this._translateFilters(filterItems);
747
783
  this._generalComboBoxes[0].data = createComboBoxData(translated);
748
784
  this._generalComboBoxes[2].data = createComboBoxData(translated);
@@ -827,7 +863,7 @@ class FilterDialog extends BasicElement {
827
863
  conOp1 = con1[0];
828
864
  if(con1.length && con1[0]) {
829
865
  conVal1 = con1[1];
830
- if(conVal1 || conVal1 === 0 || conVal1 === false) {
866
+ if(conVal1 || conVal1 === 0 || conVal1 === false || conOp1 === BLANK_FILTERS[0][0] || conOp1 === BLANK_FILTERS[1][0]) {
831
867
  validCon1 = true;
832
868
  connector = con1[2] || "";
833
869
  } else {
@@ -844,7 +880,7 @@ class FilterDialog extends BasicElement {
844
880
  conOp2 = con2[0];
845
881
  if(con2.length && conOp2) {
846
882
  conVal2 = con2[1];
847
- if(conVal2 || conVal2 === 0 || conVal2 === false) {
883
+ if(conVal2 || conVal2 === 0 || conVal2 === false || conOp2 === BLANK_FILTERS[0][0] || conOp2 === BLANK_FILTERS[1][0]) {
848
884
  validCon2 = true;
849
885
  } else {
850
886
  conVal2 = "";
@@ -929,9 +965,10 @@ class FilterDialog extends BasicElement {
929
965
  }
930
966
  /**
931
967
  * @private
968
+ * @param {Array.<Object>|Object} data data for convert into array
969
+ * @return {Array.<Object>}
932
970
  */
933
- _updateValueSelector() {
934
- let data = this.data;
971
+ _dataToArray(data) {
935
972
  let ary = null;
936
973
  if (Array.isArray(data)) {
937
974
  ary = data;
@@ -940,16 +977,48 @@ class FilterDialog extends BasicElement {
940
977
  } else {
941
978
  ary = [];
942
979
  }
980
+ return ary;
981
+ }
943
982
 
944
- // Data selector can take large number of items
983
+ /**
984
+ * @private
985
+ */
986
+ _addBlankItem() {
987
+ var ary = this._dataToArray(this.data);
988
+ if(this._blankValues) {
989
+ let blankItem = {
990
+ id: "_blank",
991
+ title: this._blankValues,
992
+ nodes: [],
993
+ value: BLANKS, // The ".value" property is currently only usable with blank item abilities
994
+ checked: this._blankValuesChecked || false
995
+ };
996
+ this.data = [blankItem].concat(ary);
997
+ } else {
998
+ // Data selector can take large number of items
999
+ this.data = ary; // Preserve original referencing
1000
+ }
1001
+ }
1002
+ /**
1003
+ * @private
1004
+ */
1005
+ _updateValueSelector() {
1006
+ var ary = this._dataToArray(this.data);
945
1007
  this._dataSelector.data = ary; // Preserve original referencing
946
-
947
1008
  // Value selector for Filter by Condition
948
1009
  if(ary.length > ITEM_LIMIT) {
949
1010
  ary = ary.slice(0, ITEM_LIMIT); // Prevent combo box from over population
950
1011
  }
951
- this._generalComboBoxes[1].data = ary.map(this._toComboBoxItem);
952
- this._generalComboBoxes[3].data = ary.map(this._toComboBoxItem);
1012
+ // Advance items
1013
+ var advanceItems = ary.map(this._toComboBoxItem);
1014
+ if(this._blankValues) {
1015
+ var basicItems = advanceItems.slice(1);
1016
+ this._generalComboBoxes[1].data = basicItems;
1017
+ this._generalComboBoxes[3].data = basicItems;
1018
+ } else {
1019
+ this._generalComboBoxes[1].data = advanceItems;
1020
+ this._generalComboBoxes[3].data = advanceItems;
1021
+ }
953
1022
  }
954
1023
  /**
955
1024
  * @private
@@ -29,6 +29,9 @@ var translationDe = {
29
29
  "Equals": "Gleich",
30
30
  "Does Not Equal": "Stimmt nicht überein",
31
31
 
32
+ "Equal To Blank Value": "Equal To Blank Value",
33
+ "Does Not Equal To Blank Value": "Does Not Equal To Blank Value",
34
+
32
35
  "Date is": "Datum ist",
33
36
  "Date is Before": "Datum ist vor",
34
37
  "Date is After": "Datum ist nach"
@@ -29,6 +29,9 @@ var translationEn = {
29
29
  "Equals": "Equals",
30
30
  "Does Not Equal": "Does Not Equal",
31
31
 
32
+ "Equal To Blank Value": "Equal To Blank Value",
33
+ "Does Not Equal To Blank Value": "Does Not Equal To Blank Value",
34
+
32
35
  "Date is": "Date is",
33
36
  "Date is Before": "Date is Before",
34
37
  "Date is After": "Date is After"
@@ -29,6 +29,9 @@ var translationJa = {
29
29
  "Equals": "指定の値に等しい",
30
30
  "Does Not Equal": "指定の値に等しくない",
31
31
 
32
+ "Equal To Blank Value": "Equal To Blank Value",
33
+ "Does Not Equal To Blank Value": "Does Not Equal To Blank Value",
34
+
32
35
  "Date is": "日付が指定の値に等しい",
33
36
  "Date is Before": "日付が指定の値より前",
34
37
  "Date is After": "日付が指定の値より後"
@@ -29,6 +29,9 @@ var translationZhHant = {
29
29
  "Equals": "等於",
30
30
  "Does Not Equal": "不等於",
31
31
 
32
+ "Equal To Blank Value": "Equal To Blank Value",
33
+ "Does Not Equal To Blank Value": "Does Not Equal To Blank Value",
34
+
32
35
  "Date is": "日期",
33
36
  "Date is Before": "日期小於",
34
37
  "Date is After": "日期大於"
@@ -29,6 +29,9 @@ var translationZh = {
29
29
  "Equals": "等于",
30
30
  "Does Not Equal": "不等于",
31
31
 
32
+ "Equal To Blank Value": "Equal To Blank Value",
33
+ "Does Not Equal To Blank Value": "Does Not Equal To Blank Value",
34
+
32
35
  "Date is": "日期",
33
36
  "Date is Before": "日期小于",
34
37
  "Date is After": "日期大于"
package/lib/grid/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import {Grid} from "./lib/efx-grid.js";
2
2
  export {Grid}
3
- window.EFX_GRID = { version: "6.0.83" };
3
+ window.EFX_GRID = { version: "6.0.84" };
@@ -3,7 +3,7 @@ import {GridPlugin} from "../../tr-grid-util/es6/GridPlugin.js";
3
3
  import {FilterBuilder, stringToDateObject} from "../../tr-grid-util/es6/FilterBuilder.js";
4
4
  import {FilterOperators} from "../../tr-grid-util/es6/FilterOperators.js";
5
5
  import {ElfUtil} from "../../tr-grid-util/es6/ElfUtil.js";
6
- import { injectCss, prettifyCss } from "../../tr-grid-util/es6/Util.js";
6
+ import { injectCss, prettifyCss, cloneObject } from "../../tr-grid-util/es6/Util.js";
7
7
 
8
8
  declare namespace RowFilteringPlugin {
9
9
 
@@ -32,7 +32,8 @@ declare namespace RowFilteringPlugin {
32
32
  formattedDataAccessor?: ((...params: any[]) => any)|null,
33
33
  sortLogic?: ((...params: any[]) => any)|null,
34
34
  itemList?: any[]|null,
35
- additionalItems?: any[]|null
35
+ additionalItems?: any[]|null,
36
+ blankValues?: (boolean|string)|null
36
37
  };
37
38
 
38
39
  type Options = {