@refinitiv-ui/efx-grid 6.0.77 → 6.0.78

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.
@@ -54,10 +54,13 @@ var CheckboxPlugin = function (options) {
54
54
  t._onPreSectionRender = t._onPreSectionRender.bind(t);
55
55
  t._onPostSectionDataBinding = t._onPostSectionDataBinding.bind(t);
56
56
  t._onCheckboxClicked = t._onCheckboxClicked.bind(t);
57
+ t._onCheckboxKeydown = t._onCheckboxKeydown.bind(t);
58
+ t._onCheckboxMousedown = t._onCheckboxMousedown.bind(t);
57
59
  t._onColumnIndexChanged = t._onColumnIndexChanged.bind(t);
58
60
  t._onColumnAdded = t._onColumnAdded.bind(t);
59
61
  t._requestUIPopulation = t._requestUIPopulation.bind(t);
60
62
  t._populateUIs = t._populateUIs.bind(t);
63
+ t._isCheckboxDisabled = t._isCheckboxDisabled.bind(t);
61
64
  t.selectAll = t.selectAll.bind(t);
62
65
  t.deselectAll = t.deselectAll.bind(t);
63
66
  t._hosts = [];
@@ -68,6 +71,84 @@ var CheckboxPlugin = function (options) {
68
71
  };
69
72
  Ext.inherits(CheckboxPlugin, GridPlugin);
70
73
 
74
+ /** @type {Function}
75
+ * @private
76
+ */
77
+ CheckboxPlugin._emptyFunc = function () { };
78
+ /** @private
79
+ * @function
80
+ * @param {Object} view DataView object
81
+ * @param {string} rid
82
+ * @return {boolean}
83
+ */
84
+ CheckboxPlugin._isRowExpansion = function (view, rid) {
85
+ return view.isRowExpansion(rid); // WARNING: isRowExpansion() is available only in DataView and not DataTable
86
+ };
87
+ /** @private
88
+ * @function
89
+ * @param {Object} view DataView object
90
+ * @param {Function} disablingGetter
91
+ * @param {string} rid
92
+ * @return {boolean}
93
+ */
94
+ CheckboxPlugin._checkableRow = function (view, disablingGetter, rid) {
95
+ if(disablingGetter(view, rid)) {
96
+ return false;
97
+ }
98
+ if(CheckboxPlugin._isRowExpansion(view, rid)) {
99
+ return false;
100
+ }
101
+ return true;
102
+ };
103
+ /** @private
104
+ * @function
105
+ * @param {Element} elem
106
+ */
107
+ CheckboxPlugin._addDisabledProp = function (elem) {
108
+ elem.setAttribute("disabled", "");
109
+ };
110
+ /** @private
111
+ * @function
112
+ * @param {Element} elem
113
+ */
114
+ CheckboxPlugin._removeDisabledProp = function (elem) {
115
+ elem.removeAttribute("disabled");
116
+ };
117
+ /** @private
118
+ * @function
119
+ * @param {Element} elem
120
+ * @param {string} prop
121
+ * @param {boolean} bool
122
+ */
123
+ CheckboxPlugin._setBooleanProp = function (elem, prop, bool) {
124
+ if(bool) {
125
+ elem.setAttribute(prop, "");
126
+ } else {
127
+ elem.removeAttribute(prop);
128
+ }
129
+ };
130
+ /** Collect member row that is in the given view and all members in collapsed group.
131
+ * @private
132
+ * @param {Object} dv DataView object
133
+ * @param {!Array.<string>} rids
134
+ * @param {string} rid
135
+ * @return {!Array.<string>} rids
136
+ */
137
+ CheckboxPlugin._collectRowMemberId = function (dv, rids, rid) {
138
+ if(rid) {
139
+ var subGroup = dv.getGroupByRowId(rid);
140
+ if(subGroup) {
141
+ if(subGroup.isCollapsed()) {
142
+ return rids.concat(subGroup.getAllRowIds(true));
143
+ }
144
+ } else {
145
+ rids.push(rid);
146
+ }
147
+ }
148
+ return rids;
149
+ };
150
+
151
+
71
152
  /** @type {number}
72
153
  * @private
73
154
  */
@@ -108,10 +189,12 @@ CheckboxPlugin.prototype._autoRowSelection = false;
108
189
  * @private
109
190
  */
110
191
  CheckboxPlugin.prototype._topCheckboxHandler = true;
111
- /** @type {Function}
192
+ /** @type {string}
112
193
  * @private
113
194
  */
114
- CheckboxPlugin._emptyFunc = function () { };
195
+ CheckboxPlugin.prototype._anchorRowId = "";
196
+
197
+
115
198
  /** @type {Object.<string, number>}
116
199
  * @private
117
200
  */
@@ -250,17 +333,6 @@ CheckboxPlugin._mergeStates = function(states) {
250
333
  }
251
334
  return state;
252
335
  };
253
- /** @private
254
- * @function
255
- * @param {number} count
256
- * @param {boolean} bool
257
- * @return {Array.<boolean>}
258
- */
259
- CheckboxPlugin._genData = function (count, bool) {
260
- var data = new Array(count);
261
- for(var i = count; --i >= 0;) { data[i] = bool; }
262
- return data;
263
- };
264
336
 
265
337
  /** @public
266
338
  * @return {string}
@@ -632,6 +704,8 @@ CheckboxPlugin.prototype._createCheckbox = function (sectionSettings, colIndex,
632
704
  chkbox._chkbox = true;
633
705
 
634
706
  chkbox.addEventListener("click", this._onCheckboxClicked, false);
707
+ chkbox.addEventListener("keydown", this._onCheckboxKeydown, false);
708
+ chkbox.addEventListener("mousedown", this._onCheckboxMousedown, false);
635
709
  // chkbox.addEventListener("checked-changed", this._onCheckboxClicked, false); // Elf v3
636
710
 
637
711
  cell.setContent(chkbox);
@@ -660,19 +734,70 @@ CheckboxPlugin.prototype._createCheckbox = function (sectionSettings, colIndex,
660
734
  };
661
735
 
662
736
 
663
- /** Select all checkboxes that are not affected by filtering and pagination logics. This is equivalent to ticking the checkbox at the top header section of the grid
737
+ /** Select/check all checkboxes that are not affected by filtering and pagination logics. This is equivalent to ticking the checkbox at the top header section of the grid
664
738
  * @public
665
739
  */
666
740
  CheckboxPlugin.prototype.selectAll = function () {
667
741
  this.checkAll(true);
668
742
  };
669
- /** Deselect all checkboxes that are not affected by filtering and pagination logics. This is equivalent to un-ticking the checkbox at the top header section of the grid
743
+ /** Deselect/uncheck all checkboxes that are not affected by filtering and pagination logics. This is equivalent to un-ticking the checkbox at the top header section of the grid
670
744
  * @public
671
745
  * @param {boolean} check
672
746
  */
673
747
  CheckboxPlugin.prototype.deselectAll = function () {
674
748
  this.checkAll(false);
675
749
  };
750
+ /** Select/check all spicified content checkboxes that are in view
751
+ * @public
752
+ * @param {Array.<number|string>} rowRefs
753
+ * @param {boolean} checked
754
+ */
755
+ CheckboxPlugin.prototype.selectCheckboxes = function (rowRefs) {
756
+ this.setCheckStates(rowRefs, true);
757
+ };
758
+ /** Select/check all spicified content checkboxes that are in view
759
+ * @public
760
+ * @param {Array.<number|string>} rowRefs
761
+ * @param {boolean} checked
762
+ */
763
+ CheckboxPlugin.prototype.deselectCheckboxes = function (rowRefs) {
764
+ this.setCheckStates(rowRefs, false);
765
+ };
766
+ /** Set check state to all spicified content checkboxes that are in view
767
+ * @public
768
+ * @param {Array.<number|string>} rowRefs
769
+ * @param {boolean} checked
770
+ */
771
+ CheckboxPlugin.prototype.setCheckStates = function (rowRefs, checked) {
772
+ if(!rowRefs) {
773
+ return;
774
+ }
775
+ var ary = Array.isArray(rowRefs) ? rowRefs : [rowRefs];
776
+ var len = ary.length;
777
+ if(!len) {
778
+ return;
779
+ }
780
+
781
+ // TODO: Support multi-table mode
782
+ var host = this._hosts[0];
783
+ var sectionSettings = host.getSectionSettings("content");
784
+ var dv = sectionSettings.getDataSource();
785
+ if(!dv) {
786
+ return;
787
+ }
788
+
789
+ var rids = [];
790
+ var i;
791
+ for (i = 0; i < len; ++i) {
792
+ var ref = ary[i];
793
+ var rid = (typeof ref === "string") ? ref : dv.getRowId(ref);
794
+ rids = CheckboxPlugin._collectRowMemberId(dv, rids, rid);
795
+ }
796
+ if(rids.length) {
797
+ rids = rids.filter(CheckboxPlugin._checkableRow.bind(null, dv, this._isCheckboxDisabled));
798
+ this._setColumnData(dv, this._checkboxField, checked, rids);
799
+ }
800
+ };
676
801
 
677
802
  /** This is equivalent to clicking the checkbox at the top header section of the grid. <br>
678
803
  * Use {@link CheckboxPlugin#setAllCheckStates} to set all states regardless of filtering and pagination
@@ -710,9 +835,9 @@ CheckboxPlugin.prototype.setAllCheckStates = function (checked) {
710
835
  var dt = dv ? dv.getDataSource() : null;
711
836
 
712
837
  if(dt) {
713
- var valueList = CheckboxPlugin._genData(dt.getRowCount(), checked);
714
- var rids = dt.getAllRowIds();
715
- this._setColumnData(dv, this._checkboxField, valueList, rids);
838
+ // TODO: Check if we need to omit disabled checkboxes
839
+ var rids = dt.getAllRowIds(true); // TODO: Check if we can use shallow copy
840
+ this._setColumnData(dv, this._checkboxField, checked, rids);
716
841
  }
717
842
  };
718
843
 
@@ -722,27 +847,17 @@ CheckboxPlugin.prototype.setAllCheckStates = function (checked) {
722
847
  * @see {@link CheckboxPlugin#checkAll}
723
848
  */
724
849
  CheckboxPlugin.prototype.selectAllPages = function (checked) {
725
- var state = checked != null ? checked : true;
726
850
  var host = this._hosts[0];
727
851
  var dv = host ? host.getDataSource() : null;
728
-
729
- if(dv) {
730
- var allRids = dv.getSortedRowIds(true); // All row ids with filter applied, including disabled and pagination
731
-
732
- // remove disabled row
733
- var rids = [];
734
- var dataRows = dv.getMultipleRowData(allRids);
735
- var len = dataRows.length;
736
- var dataRow;
737
- for(var i = 0; i < len; i++) {
738
- dataRow = this._rowGetter(dataRows[i]);
739
- if(dataRow && !dataRow[this._disablingField]) {
740
- rids.push(allRids[i]);
741
- }
742
- }
743
- var valueList = CheckboxPlugin._genData(rids.length, state);
744
- this._setColumnData(dv, this._checkboxField, valueList, rids);
852
+ if(!dv) {
853
+ return;
745
854
  }
855
+
856
+ var allRids = dv.getSortedRowIds(true); // All row ids with filter applied, including disabled and pagination
857
+ allRids = allRids.filter(CheckboxPlugin._checkableRow.bind(null, dv, this._isCheckboxDisabled));
858
+
859
+ var state = checked != null ? checked : true;
860
+ this._setColumnData(dv, this._checkboxField, state, allRids);
746
861
  };
747
862
 
748
863
  /** @public
@@ -765,6 +880,18 @@ CheckboxPlugin.prototype.disableCheckbox = function(rowRef, disabled) {
765
880
 
766
881
  this._setData(dv, rowRef, this._disablingField, disabled !== false);
767
882
  };
883
+ /** @private
884
+ * @param {Object} view DataView object
885
+ * @param {string} rowId in the data table or row index
886
+ * @returns {boolean} disabled Truthy or Falsy value
887
+ */
888
+ CheckboxPlugin.prototype._isCheckboxDisabled = function(view, rowId) {
889
+ var rowData = this._getRowFromId(view, rowId);
890
+ if(rowData) {
891
+ return rowData[this._disablingField] ? true : false;
892
+ }
893
+ return false;
894
+ };
768
895
 
769
896
  /** @public
770
897
  * @param {number|string} rowRef Row id in the data table or row index
@@ -833,7 +960,6 @@ CheckboxPlugin.prototype.getFilteredSelectedData = function (field) {
833
960
  * @param {string=} field="" When field is not provided, entire rowData is returned. If field is specified, field values will be returned. Use "ROW_ID" as the field for retrieving internal row ids.
834
961
  * @return {!Array} Returns selected rows
835
962
  * @example
836
- * var chkBoxExtension = new CheckboxExtension();
837
963
  * chkBoxExtension.getSelectedRowData(); // Get all selected row data in this format [{}, {}, ... RowData objects, {}]
838
964
  * chkBoxExtension.getSelectedRowData("field"); // Get all field values from selected row data in this format [value1, value2, ... values, valueN]
839
965
  */
@@ -924,67 +1050,52 @@ CheckboxPlugin.prototype._getCheckboxValue = function (dv, rowId) {
924
1050
  };
925
1051
  /** @private
926
1052
  * @param {Object} dv DataView
927
- * @return {Array.<string>} state
1053
+ * @return {string} state
928
1054
  */
929
- CheckboxPlugin.prototype._getRowMemberIds = function (dv) {
930
- var rowIds = [];
931
- if (!dv) return rowIds;
1055
+ CheckboxPlugin.prototype._getGroupState = function (dv) {
1056
+ if (!dv) {
1057
+ return "unchecked";
1058
+ }
932
1059
 
933
- if (dv.getGroupLevel && 0 === dv.getGroupLevel()) {
934
- // case root group we check state from member that visible in view
1060
+ var rowIds = null;
1061
+ if (dv.getGroupLevel && dv.getGroupLevel() === 0) { // Root group
935
1062
  rowIds = this._getRowMemberIdsInView(dv);
936
- } else {
937
- // case dataTable or subGroup we check state from member in group
1063
+ } else { // Subgroup
938
1064
  rowIds = dv.getAllRowIds(true); // Getting shallow copy and excluding header rows
1065
+ rowIds = rowIds.filter(CheckboxPlugin._checkableRow.bind(null, dv, this._isCheckboxDisabled));
939
1066
  }
940
- return rowIds;
941
- };
942
- /** @private
943
- * @param {Object} dv DataView
944
- * @return {string} state
945
- */
946
- CheckboxPlugin.prototype._getGroupState = function (dv) {
947
- if (!dv) return "unchecked";
948
1067
 
949
- var rowIds = this._getRowMemberIds(dv);
950
-
951
- var dataRows = dv.getMultipleRowData(rowIds);
952
1068
  var len = rowIds.length;
953
- if (0 === len) return "unchecked";
1069
+ if (!len) {
1070
+ return "unchecked";
1071
+ }
954
1072
 
955
- var dataRow;
956
- var states = [];
1073
+ var state = "";
957
1074
  for(var i = 0; i < len; ++i) {
958
- if (dv.getGroupByRowId(rowIds[i])) { continue; }
959
- dataRow = dataRows[i];
960
- if(dataRow && dataRow[this._disablingField]) {
961
- continue;
962
- }
963
- states.push(CheckboxPlugin._toCheckState(this._getCheckboxValue(dv, rowIds[i])));
1075
+ state = CheckboxPlugin._mergeState(
1076
+ state,
1077
+ CheckboxPlugin._toCheckState(this._getCheckboxValue(dv, rowIds[i]))
1078
+ );
964
1079
  }
965
- return CheckboxPlugin._mergeStates(states);
1080
+ return state;
966
1081
  };
967
1082
  /** @private
968
1083
  * @param {Object} dv DataView
969
1084
  * @return {boolean} state
970
1085
  */
971
1086
  CheckboxPlugin.prototype._getGroupDisabledState = function (dv) {
972
- if (!dv) return false;
1087
+ if (!dv) {
1088
+ return false;
1089
+ }
973
1090
 
974
- var rowIds = this._getRowMemberIds(dv);
1091
+ var rowIds = this._getRowMemberIdsInView(dv);
975
1092
  var len = rowIds.length;
976
- if (!len) return true;
977
-
978
- var disabled = true;
979
1093
  for(var i = 0; i < len; ++i) {
980
- var rid = rowIds[i];
981
- var dataRow = this._getRowFromId(dv, rid);
982
- if (!dataRow[this._disablingField]) {
983
- disabled = false;
984
- break;
1094
+ if(!this._isCheckboxDisabled(dv, rowIds[i])) {
1095
+ return false;
985
1096
  }
986
1097
  }
987
- return disabled;
1098
+ return true;
988
1099
  };
989
1100
  /** @private
990
1101
  * @param {Object} sectionSettings Grid sectionSettings object
@@ -1091,14 +1202,7 @@ CheckboxPlugin.prototype._syncAscendantState = function (sectionSettings, caller
1091
1202
  var titleSection = host.getSectionSettings("title");
1092
1203
  var disabled = this._getGroupDisabledState(dv);
1093
1204
  var checkboxes = this._getAllCheckboxes(titleSection);
1094
- for(i = 0; i < checkboxes.length; i++){
1095
- var checkbox = checkboxes[i];
1096
- if(disabled) {
1097
- checkbox.setAttribute("disabled", "");
1098
- } else {
1099
- checkbox.removeAttribute("disabled");
1100
- }
1101
- }
1205
+ checkboxes.forEach(disabled ? CheckboxPlugin._addDisabledProp : CheckboxPlugin._removeDisabledProp);
1102
1206
  }
1103
1207
 
1104
1208
  this._setSectionState(parent, state);
@@ -1109,51 +1213,18 @@ CheckboxPlugin.prototype._syncAscendantState = function (sectionSettings, caller
1109
1213
  * @param {string} state
1110
1214
  */
1111
1215
  CheckboxPlugin.prototype._setSectionState = function (sectionSettings, state) {
1112
- var i;
1113
1216
  if (!state) {
1114
1217
  return;
1115
1218
  }
1116
1219
 
1117
1220
  if (this._isDataBound(sectionSettings)) {
1221
+ var checked = (state !== "unchecked");
1118
1222
  var dv = /** @type{DataView} */(sectionSettings.getDataSource());
1119
-
1120
- // create row dict and mark unchecked
1121
- var rowIdDict = {};
1122
- // in state !== unchecked we will get filtered row in group
1123
- // and set rowIdDict[checkID] = true
1124
- var checkIDs = this._getRowMemberIdsInView(dv);
1125
- for (i = 0; i < checkIDs.length; i++) {
1126
- var checkID = checkIDs[i];
1127
-
1128
- // there are header group rows in the case of paging and grouping
1129
- if (dv.getGroupByRowId(checkID)) { continue; }
1130
-
1131
- var dataRow = this._getRowFromId(dv, checkID);
1132
- if (dataRow && dataRow[this._disablingField]) {
1133
- continue;
1134
- }
1135
-
1136
- if (state === "unchecked") {
1137
- // TODO: This will not work in RT grid
1138
- rowIdDict[checkID] = false;
1139
- } else {
1140
- rowIdDict[checkID] = true;
1141
- }
1142
- }
1143
-
1144
- // create data array and rowIds array
1145
- var data = [];
1146
- var allRowIDInGroup = [];
1147
- for (var rowID in rowIdDict) {
1148
- allRowIDInGroup.push(rowID);
1149
- data.push(rowIdDict[rowID]);
1150
- }
1151
-
1152
- // finally set all data
1153
- this._setColumnData(dv, this._checkboxField, data, allRowIDInGroup);
1223
+ var memberRids = this._getRowMemberIdsInView(dv);
1224
+ this._setColumnData(dv, this._checkboxField, checked, memberRids);
1154
1225
  } else {
1155
1226
  var checkboxes = this._getAllCheckboxes(sectionSettings);
1156
- for (i = checkboxes.length; --i >= 0; ) {
1227
+ for (var i = checkboxes.length; --i >= 0; ) {
1157
1228
  CheckboxPlugin._setCheckState(checkboxes[i], state);
1158
1229
  }
1159
1230
  }
@@ -1266,26 +1337,24 @@ CheckboxPlugin.prototype._populateUIs = function () {
1266
1337
  host.requestRowRefresh(); // For content
1267
1338
  this._initializing = false;
1268
1339
  };
1340
+
1269
1341
  /** @private
1270
1342
  * @param {Event} e
1343
+ * @param {boolean=} toggling
1271
1344
  */
1272
- CheckboxPlugin.prototype._onCheckboxClicked = function (e) {
1273
- if(this._coralCheckboxVer === 1) {
1274
- // Workaround for duplicate event from ef-checkbox
1275
- if(e.target.tagName === "LABEL") {
1276
- return;
1277
- }
1345
+ CheckboxPlugin.prototype._onCheckboxChanged = function (e, toggling) {
1346
+ var chkbox = e ? /** @type{Element} */(e.currentTarget) : null;
1347
+ if(!chkbox) {
1348
+ return;
1278
1349
  }
1279
1350
 
1280
- var chkbox = /** @type{Element} */(e.currentTarget);
1281
-
1282
1351
  // after checkbox change by user clicked action
1283
1352
  // the checkbox state is change only 'unchecked' or 'checked' only
1284
1353
  // so we must remove 'square-shape' class that use in only 'partial' state
1285
1354
  chkbox.classList.remove('square-shape');
1286
1355
 
1287
1356
  var newState = CheckboxPlugin._getCheckState(chkbox);
1288
- if(this._coralCheckboxVer === 1) { // State of the ef-checkbox will not be reflected immediately after click
1357
+ if(toggling) {
1289
1358
  newState = CheckboxPlugin._toggleState(newState);
1290
1359
  }
1291
1360
 
@@ -1297,41 +1366,49 @@ CheckboxPlugin.prototype._onCheckboxClicked = function (e) {
1297
1366
  }
1298
1367
 
1299
1368
  if (this._isDataBound(sectionSettings)) {
1300
- var rowIndex = pos["rowIndex"];
1301
- var bool = newState !== "unchecked";
1302
1369
  var dv = sectionSettings.getDataSource();
1370
+ var rowIndex = pos["rowIndex"];
1303
1371
  var rid = dv.getRowId(rowIndex);
1304
- var dataRow = this._getRowFromId(dv, rid);
1305
- if(dataRow) {
1306
- if (dataRow[this._disablingField]) {
1307
- return;
1308
- }
1309
- this._setData(dv, rowIndex, this._checkboxField, bool);
1310
- } else { // Group header
1311
- var subGroup = dv.getGroupByRowId(rid);
1312
- if (subGroup) {
1313
- // prepare data for _setColumnData fn.
1314
- var rowMemberIds = this._getRowMemberIdsOfGroupInView(dv, subGroup);
1315
- var len = rowMemberIds.length;
1316
-
1317
- var dataRows = dv.getMultipleRowData(rowMemberIds);
1318
- var rids = [];
1319
- var data = [];
1320
- for (var i = 0; i < len; i++) {
1321
- dataRow = dataRows[i];
1322
- if (dataRow && dataRow[this._disablingField]) {
1323
- continue;
1372
+
1373
+ if(this._isCheckboxDisabled(dv, rid)) { // TODO: Check if this is necessary
1374
+ return;
1375
+ }
1376
+
1377
+
1378
+ var changeRange = null;
1379
+ if(e.shiftKey && this._anchorRowId) { // Select/deselect range of checkboxes
1380
+ var prevIndex = dv.getRowIndex(this._anchorRowId);
1381
+ if(prevIndex >= 0) {
1382
+ var i;
1383
+ if(prevIndex < rowIndex) {
1384
+ changeRange = [];
1385
+ for(i = prevIndex; i <= rowIndex; ++i) {
1386
+ changeRange.push(i);
1387
+ }
1388
+ } else if(rowIndex < prevIndex) {
1389
+ changeRange = [];
1390
+ for(i = rowIndex; i <= prevIndex; ++i) {
1391
+ changeRange.push(i);
1324
1392
  }
1325
- rids.push(rowMemberIds[i]);
1326
- data.push(bool);
1327
1393
  }
1394
+ }
1395
+ }
1328
1396
 
1329
- this._setColumnData(dv, this._checkboxField, data, rids);
1397
+ if(changeRange) {
1398
+ this.setCheckStates(changeRange, !e.altKey);
1399
+ } else {
1400
+ var bool = newState !== "unchecked";
1401
+ var subGroup = dv.getGroupByRowId(rid);
1402
+ if (subGroup) {
1403
+ var rowMemberIds = this._getRowMemberIdsOfSubgroup(dv, subGroup);
1404
+ this._setColumnData(dv, this._checkboxField, bool, rowMemberIds);
1330
1405
 
1331
1406
  // WORKAROUND: to force group move to next state from partial state
1332
1407
  if (newState === 'checked' && chkbox._prevState === 'partial') {
1333
1408
  chkbox._forceNewState = newState;
1334
1409
  }
1410
+ } else {
1411
+ this._setData(dv, rowIndex, this._checkboxField, bool);
1335
1412
  }
1336
1413
  }
1337
1414
  }
@@ -1348,107 +1425,97 @@ CheckboxPlugin.prototype._onCheckboxClicked = function (e) {
1348
1425
 
1349
1426
  e.stopPropagation();
1350
1427
  };
1428
+ /** @private
1429
+ * @param {Event} e
1430
+ */
1431
+ CheckboxPlugin.prototype._onCheckboxClicked = function (e) {
1432
+ var v1 = this._coralCheckboxVer === 1;
1433
+ if(v1) {
1434
+ // Workaround for duplicate event from ef-checkbox
1435
+ if(e.target.tagName === "LABEL") {
1436
+ return;
1437
+ }
1438
+ }
1439
+
1440
+ // State of the ef-checkbox will not be reflected immediately after click in ELF v1
1441
+ this._onCheckboxChanged(e, v1);
1442
+ };
1443
+ /** @private
1444
+ * @param {Event} e
1445
+ */
1446
+ CheckboxPlugin.prototype._onCheckboxKeydown = function (e) {
1447
+ if(e.keyCode === 32) {
1448
+ this._onCheckboxChanged(e, true);
1449
+ e.preventDefault();
1450
+ }
1451
+ };
1452
+ /** @private
1453
+ * @param {Event} e
1454
+ */
1455
+ CheckboxPlugin.prototype._onCheckboxMousedown = function (e) {
1456
+ if(!e.shiftKey) {
1457
+ this._anchorRowId = "";
1458
+ var host = this._hosts[0];
1459
+ var pos = host.getRelativePosition(e.currentTarget);
1460
+ if(pos.sectionType === "content") {
1461
+ var dv = host.getDataSource();
1462
+ this._anchorRowId = dv.getRowId(pos.rowIndex);
1463
+ }
1464
+ }
1465
+ };
1351
1466
 
1352
1467
  /** get member items in view. the items in view are items on current page and already filtered , include items in collapsed group
1353
1468
  * @private
1354
- * @param {Object} view dataview object
1355
- * @param {Object} targetGroup dataview object
1469
+ * @param {Object} view Root DataView object
1470
+ * @param {Object} targetGroup Subgroup DataView object
1356
1471
  * @return {!Array.<string>} list of row member ids of group in view
1357
1472
  */
1358
- CheckboxPlugin.prototype._getRowMemberIdsOfGroupInView = function (view, targetGroup) {
1359
- var visibleRowIds = view.getVisibleRowIds(true);
1360
- var beginPos = 0;
1473
+ CheckboxPlugin.prototype._getRowMemberIdsOfSubgroup = function (view, targetGroup) {
1474
+ var memberIds = this._getRowMemberIdsInView(view); // Slow
1361
1475
 
1362
- // if group header is in view and collapsed we can return all id in view immediately
1363
- var pos = visibleRowIds.indexOf(targetGroup.getGroupRowId());
1364
- if (pos >= 0) {
1365
- if (targetGroup.isCollapsed()) return targetGroup.getAllRowIds(true);
1366
- else beginPos = pos + 1;
1367
- } else { // not support case group header not in view or inside group parent that collapsed
1368
- return [];
1369
- }
1370
-
1371
- // loop to check which member is in view
1372
- var groupVisibleRowIds = targetGroup.getVisibleRowIds(true);
1373
- var result = [], id, childGroup, i;
1374
- var len = groupVisibleRowIds.length;
1375
- for (i = 0; i < len; i++) {
1376
- id = groupVisibleRowIds[i];
1377
- pos = visibleRowIds.indexOf(id, beginPos);
1476
+ // WARNING: Subgroup header row may not be in the view
1477
+ var subgroupMembers = targetGroup.isCollapsed() ? targetGroup.getAllRowIds(true) : targetGroup.getVisibleRowIds(true);
1478
+ var beginPos = 0;
1479
+ var result = [];
1480
+ var len = subgroupMembers.length;
1481
+ // TODO: Use object map instead of indexOf for checking
1482
+ for (var i = 0; i < len; i++) {
1483
+ var subgroupMember = subgroupMembers[i];
1484
+ var pos = memberIds.indexOf(subgroupMember, beginPos);
1378
1485
  if (pos >= 0) {
1379
1486
  beginPos = pos + 1;
1380
- childGroup = view.getGroupByRowId(id);
1381
- if (childGroup) {
1382
- if (childGroup.isCollapsed()) {
1383
- // child group collapsed then all rows in childGroup are in view
1384
- result = result.concat(childGroup.getAllRowIds(true) || []);
1385
- }
1386
- } else {
1387
- result.push(id);
1388
- }
1487
+ result.push(subgroupMember);
1389
1488
  }
1390
1489
  }
1391
1490
 
1392
1491
  return result;
1393
1492
  };
1394
1493
 
1395
- /** @private
1396
- * @param {Object} view dataview or datatable object
1494
+ /** Get all member rows that are in the given view and all members in a collapsed group. This excludes group header row ids.
1495
+ * Only valid row ids are returned. Row expansions and disabled rows are excluded.
1496
+ * @private
1497
+ * @param {Object} view DataView or DataTable object
1397
1498
  * @return {!Array.<string>} list of row member ids in view
1398
1499
  */
1399
1500
  CheckboxPlugin.prototype._getRowMemberIdsInView = function (view) {
1400
- // 1. get All member and group rowIds
1401
- // 2. loop check whether rowIds is group or just row member
1402
- // 3. if rowId is not group then it's just a row member
1403
- // 4. in case rowId is group and collapsed we will get all member rowIds of group and add to memberRowIds
1404
-
1405
1501
  if (view.getDataSource()) { // check is dataView
1406
1502
  // TODO: support multi-level grouping
1407
1503
  // if view is DataView -> view.getVisibleRowIds(true) will get member and group rowIds in view
1408
- var rids = view.getVisibleRowIds(true);
1504
+ var rids = view.isCollapsed() ? view.getAllRowIds(true) : view.getVisibleRowIds(true); // get All member and group rowIds
1409
1505
  var len = rids.length;
1410
1506
  var allRids = [];
1411
- var rid, group, i;
1412
- for (i = 0; i < len; i++) { // 2
1413
- rid = rids[i];
1414
- group = view.getGroupByRowId(rid);
1415
- if (!group) {
1416
- allRids.push(rid); // 3
1417
- } else if (group.isCollapsed()) { // 4
1418
- allRids = allRids.concat(group.getAllRowIds(true) || []);
1419
- }
1507
+ for (var i = 0; i < len; i++) { // loop check whether rowIds is group or just row member
1508
+ allRids = CheckboxPlugin._collectRowMemberId(view, allRids, rids[i]);
1420
1509
  }
1421
1510
 
1422
- // remove disabled row
1423
- rids = [];
1424
- var dataRows = view.getMultipleRowData(allRids);
1425
- len = dataRows.length;
1426
- var dataRow;
1427
- for(i = 0; i < len; i++) {
1428
- dataRow = dataRows[i];
1429
- if(dataRow && dataRow[this._disablingField]) {
1430
- continue;
1431
- }
1432
- rids.push(allRids[i]);
1433
- }
1434
1511
  // if view is DataView, the intention is to get data with applied filter/hidden. row expansion should also filtered out.
1435
- return rids.filter(this._isNotRowExpansion.bind(null, view));
1512
+ return allRids.filter(CheckboxPlugin._checkableRow.bind(null, view, this._isCheckboxDisabled));
1436
1513
  } else {
1437
1514
  // if view is DataTable -> view.getAllRowIds(true) will get all member in grid regardless of hidden/filtered state.
1438
1515
  return view.getAllRowIds(true);
1439
1516
  }
1440
1517
  };
1441
1518
 
1442
- /** @private
1443
- * @param {Object} view DataView object
1444
- * @param {string} rid
1445
- * @return {boolean}
1446
- */
1447
- CheckboxPlugin.prototype._isNotRowExpansion = function (view, rid) {
1448
- // NOTE: isRowExpansion() is only available in DataView.
1449
- return !view.isRowExpansion(rid);
1450
- };
1451
-
1452
1519
  /** @private
1453
1520
  * @param {Object} e
1454
1521
  */
@@ -1533,7 +1600,7 @@ CheckboxPlugin.prototype._onPostSectionDataBinding = function (e) {
1533
1600
  chkbox = checkboxes[i] = this._createCheckbox(sectionSettings, this._displayColumn, rowIndex);
1534
1601
  }
1535
1602
  var rowId = dv.getRowId(rowIndex); // Slow
1536
- rowData = this._rowGetter(dv.getRowData(rowId));
1603
+ rowData = this._getRowFromId(dv, rowId);
1537
1604
  if(hasBinding && chkbox) {
1538
1605
  arg["checkbox"] = chkbox;
1539
1606
  arg["rowIndex"] = rowIndex;
@@ -1556,11 +1623,7 @@ CheckboxPlugin.prototype._onPostSectionDataBinding = function (e) {
1556
1623
  }
1557
1624
 
1558
1625
  if(chkbox) {
1559
- if(disabled) {
1560
- chkbox.setAttribute("disabled", "");
1561
- } else {
1562
- chkbox.removeAttribute("disabled");
1563
- }
1626
+ CheckboxPlugin._setBooleanProp(chkbox, "disabled", disabled);
1564
1627
  CheckboxPlugin._setCheckState(chkbox, state);
1565
1628
  }
1566
1629
  }
@@ -1569,5 +1632,6 @@ CheckboxPlugin.prototype._onPostSectionDataBinding = function (e) {
1569
1632
  };
1570
1633
 
1571
1634
 
1635
+
1572
1636
  export default CheckboxPlugin;
1573
1637
  export { CheckboxPlugin, CheckboxPlugin as Checkbox, CheckboxPlugin as CheckboxExtension };