@syncfusion/ej2-treegrid 31.2.15 → 32.1.21
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.
- package/dist/ej2-treegrid.min.js +2 -2
- package/dist/ej2-treegrid.umd.min.js +2 -2
- package/dist/ej2-treegrid.umd.min.js.map +1 -1
- package/dist/es6/ej2-treegrid.es2015.js +1056 -321
- package/dist/es6/ej2-treegrid.es2015.js.map +1 -1
- package/dist/es6/ej2-treegrid.es5.js +1062 -324
- package/dist/es6/ej2-treegrid.es5.js.map +1 -1
- package/dist/global/ej2-treegrid.min.js +2 -2
- package/dist/global/ej2-treegrid.min.js.map +1 -1
- package/dist/global/index.d.ts +1 -1
- package/package.json +5 -5
- package/src/treegrid/actions/batch-edit.js +21 -3
- package/src/treegrid/actions/context-menu.d.ts +1 -0
- package/src/treegrid/actions/context-menu.js +16 -0
- package/src/treegrid/actions/edit.d.ts +4 -1
- package/src/treegrid/actions/edit.js +56 -3
- package/src/treegrid/actions/freeze-column.js +1 -1
- package/src/treegrid/actions/rowdragdrop.js +3 -0
- package/src/treegrid/actions/selection.d.ts +226 -8
- package/src/treegrid/actions/selection.js +759 -288
- package/src/treegrid/actions/summary.js +1 -1
- package/src/treegrid/actions/virtual-scroll.js +6 -3
- package/src/treegrid/base/data.js +2 -1
- package/src/treegrid/base/treegrid-model.d.ts +16 -0
- package/src/treegrid/base/treegrid.d.ts +50 -4
- package/src/treegrid/base/treegrid.js +159 -21
- package/src/treegrid/models/column.d.ts +24 -0
- package/src/treegrid/models/column.js +12 -0
- package/src/treegrid/renderer/virtual-tree-content-render.d.ts +5 -0
- package/src/treegrid/renderer/virtual-tree-content-render.js +26 -3
- package/styles/bds-lite.scss +17 -18
- package/styles/bds.scss +18 -19
- package/styles/bootstrap-dark-lite.scss +17 -18
- package/styles/bootstrap-dark.scss +18 -19
- package/styles/bootstrap-lite.scss +17 -18
- package/styles/bootstrap.scss +18 -19
- package/styles/bootstrap4-lite.scss +17 -18
- package/styles/bootstrap4.scss +18 -19
- package/styles/bootstrap5-dark-lite.scss +17 -18
- package/styles/bootstrap5-dark.scss +18 -19
- package/styles/bootstrap5-lite.scss +18 -18
- package/styles/bootstrap5.3-lite.css +81 -1
- package/styles/bootstrap5.3-lite.scss +18 -18
- package/styles/bootstrap5.3.css +81 -1
- package/styles/bootstrap5.3.scss +19 -19
- package/styles/bootstrap5.scss +19 -19
- package/styles/fabric-dark-lite.scss +18 -18
- package/styles/fabric-dark.scss +19 -19
- package/styles/fabric-lite.scss +18 -18
- package/styles/fabric.scss +19 -19
- package/styles/fluent-dark-lite.scss +18 -18
- package/styles/fluent-dark.scss +19 -19
- package/styles/fluent-lite.scss +18 -18
- package/styles/fluent.scss +19 -19
- package/styles/fluent2-lite.css +152 -4
- package/styles/fluent2-lite.scss +18 -18
- package/styles/fluent2.css +152 -4
- package/styles/fluent2.scss +19 -19
- package/styles/highcontrast-light-lite.scss +18 -18
- package/styles/highcontrast-light.scss +19 -19
- package/styles/highcontrast-lite.scss +18 -18
- package/styles/highcontrast.scss +19 -19
- package/styles/material-dark-lite.scss +18 -18
- package/styles/material-dark.scss +19 -19
- package/styles/material-lite.scss +17 -18
- package/styles/material.scss +18 -19
- package/styles/material3-dark-lite.css +140 -1
- package/styles/material3-dark-lite.scss +18 -18
- package/styles/material3-dark.css +140 -1
- package/styles/material3-dark.scss +19 -21
- package/styles/material3-lite.css +140 -1
- package/styles/material3-lite.scss +18 -18
- package/styles/material3.css +140 -1
- package/styles/material3.scss +19 -21
- package/styles/tailwind-dark-lite.scss +18 -18
- package/styles/tailwind-dark.scss +19 -19
- package/styles/tailwind-lite.scss +18 -18
- package/styles/tailwind.scss +19 -19
- package/styles/tailwind3-lite.css +119 -1
- package/styles/tailwind3-lite.scss +18 -18
- package/styles/tailwind3.css +119 -1
- package/styles/tailwind3.scss +19 -19
- package/styles/treegrid/_all.scss +2 -2
- package/styles/treegrid/_bds-definition.scss +2 -0
- package/styles/treegrid/_bigger.scss +2 -0
- package/styles/treegrid/_bootstrap-dark-definition.scss +2 -0
- package/styles/treegrid/_bootstrap-definition.scss +2 -0
- package/styles/treegrid/_bootstrap4-definition.scss +2 -0
- package/styles/treegrid/_bootstrap5-dark-definition.scss +26 -1
- package/styles/treegrid/_bootstrap5-definition.scss +2 -0
- package/styles/treegrid/_bootstrap5.3-definition.scss +2 -0
- package/styles/treegrid/_fabric-dark-definition.scss +2 -0
- package/styles/treegrid/_fabric-definition.scss +2 -0
- package/styles/treegrid/_fluent-dark-definition.scss +27 -1
- package/styles/treegrid/_fluent-definition.scss +2 -0
- package/styles/treegrid/_fluent2-definition.scss +2 -0
- package/styles/treegrid/_highcontrast-definition.scss +2 -0
- package/styles/treegrid/_highcontrast-light-definition.scss +2 -0
- package/styles/treegrid/_layout.scss +5 -2
- package/styles/treegrid/_material-dark-definition.scss +2 -0
- package/styles/treegrid/_material-definition.scss +2 -0
- package/styles/treegrid/_material3-dark-definition.scss +26 -1
- package/styles/treegrid/_material3-definition.scss +2 -0
- package/styles/treegrid/_tailwind-dark-definition.scss +26 -1
- package/styles/treegrid/_tailwind-definition.scss +2 -0
- package/styles/treegrid/_tailwind3-definition.scss +2 -0
- package/styles/treegrid/_theme-variables.scss +1 -0
- package/styles/treegrid/bds.scss +19 -19
- package/styles/treegrid/bootstrap-dark.scss +19 -19
- package/styles/treegrid/bootstrap.scss +19 -19
- package/styles/treegrid/bootstrap4.scss +19 -19
- package/styles/treegrid/bootstrap5-dark.scss +19 -19
- package/styles/treegrid/bootstrap5.3.css +81 -1
- package/styles/treegrid/bootstrap5.3.scss +19 -19
- package/styles/treegrid/bootstrap5.scss +19 -19
- package/styles/treegrid/fabric-dark.scss +19 -19
- package/styles/treegrid/fabric.scss +19 -19
- package/styles/treegrid/fluent-dark.scss +19 -19
- package/styles/treegrid/fluent.scss +19 -19
- package/styles/treegrid/fluent2.css +152 -4
- package/styles/treegrid/fluent2.scss +19 -19
- package/styles/treegrid/highcontrast-light.scss +19 -19
- package/styles/treegrid/highcontrast.scss +19 -19
- package/styles/treegrid/icons/_bds.scss +1 -0
- package/styles/treegrid/icons/_bootstrap-dark.scss +1 -0
- package/styles/treegrid/icons/_bootstrap.scss +1 -0
- package/styles/treegrid/icons/_bootstrap4.scss +1 -0
- package/styles/treegrid/icons/_bootstrap5-dark.scss +1 -1
- package/styles/treegrid/icons/_bootstrap5.3.scss +1 -0
- package/styles/treegrid/icons/_bootstrap5.scss +1 -0
- package/styles/treegrid/icons/_fabric-dark.scss +1 -0
- package/styles/treegrid/icons/_fabric.scss +1 -0
- package/styles/treegrid/icons/_fluent-dark.scss +1 -1
- package/styles/treegrid/icons/_fluent.scss +1 -0
- package/styles/treegrid/icons/_fluent2.scss +1 -0
- package/styles/treegrid/icons/_fusionnew.scss +1 -0
- package/styles/treegrid/icons/_highcontrast-light.scss +1 -0
- package/styles/treegrid/icons/_highcontrast.scss +1 -0
- package/styles/treegrid/icons/_material-dark.scss +1 -0
- package/styles/treegrid/icons/_material.scss +1 -0
- package/styles/treegrid/icons/_material3-dark.scss +1 -1
- package/styles/treegrid/icons/_material3.scss +1 -0
- package/styles/treegrid/icons/_tailwind-dark.scss +1 -0
- package/styles/treegrid/icons/_tailwind.scss +1 -0
- package/styles/treegrid/icons/_tailwind3.scss +1 -0
- package/styles/treegrid/material-dark.scss +19 -19
- package/styles/treegrid/material.scss +19 -19
- package/styles/treegrid/material3-dark.css +140 -1
- package/styles/treegrid/material3-dark.scss +19 -20
- package/styles/treegrid/material3.css +140 -1
- package/styles/treegrid/material3.scss +19 -20
- package/styles/treegrid/tailwind-dark.scss +19 -19
- package/styles/treegrid/tailwind.scss +19 -19
- package/styles/treegrid/tailwind3.css +119 -1
- package/styles/treegrid/tailwind3.scss +19 -19
|
@@ -70,6 +70,18 @@ class Column {
|
|
|
70
70
|
* @default null
|
|
71
71
|
*/
|
|
72
72
|
this.filter = {};
|
|
73
|
+
/**
|
|
74
|
+
* Allows treegrid to perform row spanning on the specified column.
|
|
75
|
+
*
|
|
76
|
+
* @default true
|
|
77
|
+
*/
|
|
78
|
+
this.enableRowSpan = true;
|
|
79
|
+
/**
|
|
80
|
+
* Allows treegrid to perform column spanning on the specified column.
|
|
81
|
+
*
|
|
82
|
+
* @default true
|
|
83
|
+
*/
|
|
84
|
+
this.enableColumnSpan = true;
|
|
73
85
|
merge(this, options);
|
|
74
86
|
}
|
|
75
87
|
/**
|
|
@@ -875,27 +887,56 @@ function isHidden(el) {
|
|
|
875
887
|
*/
|
|
876
888
|
class Selection {
|
|
877
889
|
/**
|
|
878
|
-
*
|
|
890
|
+
* Creates an instance of Selection.
|
|
879
891
|
*
|
|
880
|
-
* @param {TreeGrid} parent -
|
|
892
|
+
* @param {TreeGrid} parent - The TreeGrid instance this selection module is associated with.
|
|
881
893
|
*/
|
|
882
894
|
constructor(parent) {
|
|
895
|
+
this.headerCheckboxFrameEl = null;
|
|
896
|
+
this.checkboxColIndexCache = -2;
|
|
897
|
+
this.parentSelectionCounters = {};
|
|
898
|
+
this.selectedUidMap = new Map(); // Quick lookup for whether an item is selected
|
|
899
|
+
this.totalSelectableCount = 0;
|
|
900
|
+
this.headerSelectionState = 'uncheck';
|
|
901
|
+
this.checkedItemCount = 0;
|
|
902
|
+
this.visibleUidIndex = {};
|
|
883
903
|
this.parent = parent;
|
|
884
904
|
this.selectedItems = [];
|
|
885
|
-
this.selectedIndexes = [];
|
|
905
|
+
this.selectedIndexes = []; // Initialize here
|
|
886
906
|
this.filteredList = [];
|
|
887
907
|
this.searchingRecords = [];
|
|
888
908
|
this.addEventListener();
|
|
889
909
|
}
|
|
890
910
|
/**
|
|
891
|
-
*
|
|
911
|
+
* Gets the module name.
|
|
892
912
|
*
|
|
893
|
-
* @
|
|
894
|
-
* @returns {string} Returns Selection module name
|
|
913
|
+
* @returns {string} The name of the module ('selection').
|
|
895
914
|
*/
|
|
896
|
-
getModuleName() {
|
|
897
|
-
|
|
915
|
+
getModuleName() { return 'selection'; }
|
|
916
|
+
/**
|
|
917
|
+
* Builds a map from visible record uniqueID to its visible index.
|
|
918
|
+
* This map is crucial for finding the *current visible index* of a record.
|
|
919
|
+
*
|
|
920
|
+
* @returns {void}
|
|
921
|
+
*/
|
|
922
|
+
buildVisibleUidMap() {
|
|
923
|
+
this.visibleUidIndex = {};
|
|
924
|
+
const view = this.parent.grid.currentViewData;
|
|
925
|
+
if (!view) {
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
for (let i = 0, len = view.length; i < len; i++) {
|
|
929
|
+
const rec = view[parseInt(i.toString(), 10)];
|
|
930
|
+
if (rec && rec.uniqueID) {
|
|
931
|
+
this.visibleUidIndex[rec.uniqueID] = i; // Map uid -> visible row index
|
|
932
|
+
}
|
|
933
|
+
}
|
|
898
934
|
}
|
|
935
|
+
/**
|
|
936
|
+
* Adds required event listeners for selection handling.
|
|
937
|
+
*
|
|
938
|
+
* @returns {void}
|
|
939
|
+
*/
|
|
899
940
|
addEventListener() {
|
|
900
941
|
this.parent.on('dataBoundArg', this.headerCheckbox, this);
|
|
901
942
|
this.parent.on('columnCheckbox', this.columnCheckbox, this);
|
|
@@ -903,6 +944,11 @@ class Selection {
|
|
|
903
944
|
this.parent.grid.on('colgroup-refresh', this.headerCheckbox, this);
|
|
904
945
|
this.parent.on('checkboxSelection', this.checkboxSelection, this);
|
|
905
946
|
}
|
|
947
|
+
/**
|
|
948
|
+
* Removes previously added event listeners.
|
|
949
|
+
*
|
|
950
|
+
* @returns {void}
|
|
951
|
+
*/
|
|
906
952
|
removeEventListener() {
|
|
907
953
|
if (this.parent.isDestroyed) {
|
|
908
954
|
return;
|
|
@@ -914,14 +960,20 @@ class Selection {
|
|
|
914
960
|
this.parent.off('updateGridActions', this.updateGridActions);
|
|
915
961
|
}
|
|
916
962
|
/**
|
|
917
|
-
*
|
|
963
|
+
* Destroys the selection module and clears internal caches.
|
|
918
964
|
*
|
|
919
965
|
* @returns {void}
|
|
920
|
-
* @hidden
|
|
921
966
|
*/
|
|
922
967
|
destroy() {
|
|
968
|
+
this.resetSelectionCaches();
|
|
923
969
|
this.removeEventListener();
|
|
924
970
|
}
|
|
971
|
+
/**
|
|
972
|
+
* Handles checkbox click events from the DOM and dispatches selection logic.
|
|
973
|
+
*
|
|
974
|
+
* @param {Object} args - Event args containing the click target.
|
|
975
|
+
* @returns {void}
|
|
976
|
+
*/
|
|
925
977
|
checkboxSelection(args) {
|
|
926
978
|
const target = getObject('target', args);
|
|
927
979
|
const checkWrap = parentsUntil(target, 'e-checkbox-wrapper');
|
|
@@ -929,16 +981,23 @@ class Selection {
|
|
|
929
981
|
if (checkWrap && checkWrap.querySelectorAll('.e-treecheckselect').length > 0) {
|
|
930
982
|
checkBox = checkWrap.querySelector('input[type="checkbox"]');
|
|
931
983
|
const rowIndex = [];
|
|
932
|
-
|
|
984
|
+
if (this.parent.frozenRows) {
|
|
985
|
+
rowIndex.push(parseInt(target.closest('tr').getAttribute('aria-rowindex'), 10) - 1);
|
|
986
|
+
}
|
|
987
|
+
else {
|
|
988
|
+
rowIndex.push(target.closest('tr').rowIndex);
|
|
989
|
+
}
|
|
933
990
|
this.selectCheckboxes(rowIndex);
|
|
934
|
-
|
|
991
|
+
const newCheckState = checkBox.nextElementSibling.classList.contains('e-check');
|
|
992
|
+
this.triggerChkChangeEvent(checkBox, newCheckState, target.closest('tr'));
|
|
935
993
|
}
|
|
936
994
|
else if (checkWrap && checkWrap.querySelectorAll('.e-treeselectall').length > 0 && this.parent.autoCheckHierarchy) {
|
|
937
|
-
const
|
|
938
|
-
|
|
939
|
-
|
|
995
|
+
const frame = checkWrap.querySelector('.e-frame');
|
|
996
|
+
const currentStateIsUncheck = !frame.classList.contains('e-check') && !frame.classList.contains('e-stop');
|
|
997
|
+
const targetState = currentStateIsUncheck; // If currently uncheck, target state is to check all.
|
|
998
|
+
this.headerSelection(targetState);
|
|
940
999
|
checkBox = checkWrap.querySelector('input[type="checkbox"]');
|
|
941
|
-
this.triggerChkChangeEvent(checkBox,
|
|
1000
|
+
this.triggerChkChangeEvent(checkBox, targetState, target.closest('tr'));
|
|
942
1001
|
}
|
|
943
1002
|
if (!isNullOrUndefined(this.parent['parentQuery']) && this.parent.selectionSettings.persistSelection
|
|
944
1003
|
&& this.parent['columnModel'].filter((col) => { return col.type === 'checkbox'; }).length > 0
|
|
@@ -949,63 +1008,99 @@ class Selection {
|
|
|
949
1008
|
}
|
|
950
1009
|
}
|
|
951
1010
|
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Triggers the checkboxChange event with the appropriate arguments.
|
|
1013
|
+
*
|
|
1014
|
+
* @param {HTMLInputElement} checkBox - The checkbox input element that changed.
|
|
1015
|
+
* @param {boolean} checkState - The new checked state.
|
|
1016
|
+
* @param {HTMLTableRowElement} rowElement - The row element where the change occurred.
|
|
1017
|
+
* @returns {void}
|
|
1018
|
+
*/
|
|
952
1019
|
triggerChkChangeEvent(checkBox, checkState, rowElement) {
|
|
953
1020
|
const data = this.parent.getCurrentViewRecords()[rowElement.rowIndex];
|
|
954
|
-
const args = {
|
|
1021
|
+
const args = {
|
|
1022
|
+
checked: checkState, target: checkBox, rowElement: rowElement,
|
|
955
1023
|
rowData: checkBox.classList.contains('e-treeselectall')
|
|
956
|
-
? this.parent.getCheckedRecords() : data
|
|
1024
|
+
? this.parent.getCheckedRecords() : data
|
|
1025
|
+
};
|
|
957
1026
|
this.parent.trigger(checkboxChange, args);
|
|
958
1027
|
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Determines the index of the checkbox column in the header.
|
|
1030
|
+
*
|
|
1031
|
+
* @returns {number} The index of the checkbox column, or -1 if not found.
|
|
1032
|
+
*/
|
|
959
1033
|
getCheckboxcolumnIndex() {
|
|
1034
|
+
if (this.checkboxColIndexCache !== -2) {
|
|
1035
|
+
return this.checkboxColIndexCache;
|
|
1036
|
+
}
|
|
960
1037
|
let mappingUid;
|
|
961
|
-
let columnIndex;
|
|
1038
|
+
let columnIndex = -1;
|
|
962
1039
|
const stackedHeader = 'stackedHeader';
|
|
963
1040
|
const columnModel = 'columnModel';
|
|
964
1041
|
const columns = this.parent[`${stackedHeader}`] ? this.parent[`${columnModel}`] : (this.parent.columns);
|
|
965
1042
|
for (let col = 0; col < columns.length; col++) {
|
|
966
1043
|
if (columns[parseInt(col.toString(), 10)].showCheckbox) {
|
|
967
1044
|
mappingUid = columns[parseInt(col.toString(), 10)].uid;
|
|
1045
|
+
break;
|
|
968
1046
|
}
|
|
969
1047
|
}
|
|
970
|
-
const
|
|
971
|
-
for (let j = 0; j <
|
|
972
|
-
const headercell =
|
|
1048
|
+
const headerDivs = this.parent.getHeaderContent().querySelectorAll('.e-headercelldiv');
|
|
1049
|
+
for (let j = 0; j < headerDivs.length; j++) {
|
|
1050
|
+
const headercell = headerDivs[parseInt(j.toString(), 10)];
|
|
973
1051
|
if (headercell.getAttribute('data-mappinguid') === mappingUid) {
|
|
974
1052
|
columnIndex = j;
|
|
1053
|
+
break;
|
|
975
1054
|
}
|
|
976
1055
|
}
|
|
977
|
-
|
|
1056
|
+
this.checkboxColIndexCache = isNullOrUndefined(columnIndex) ? -1 : columnIndex;
|
|
1057
|
+
return this.checkboxColIndexCache;
|
|
978
1058
|
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Renders and initializes the header checkbox element.
|
|
1061
|
+
*
|
|
1062
|
+
* @returns {void}
|
|
1063
|
+
*/
|
|
979
1064
|
headerCheckbox() {
|
|
1065
|
+
this.buildVisibleUidMap();
|
|
1066
|
+
this.totalSelectableCount = this.countSelectableRecords(this.resolveHeaderSelectionList(true)); // Use all flatData for initial count
|
|
980
1067
|
this.columnIndex = this.getCheckboxcolumnIndex();
|
|
981
|
-
if (this.columnIndex > -1
|
|
1068
|
+
if (this.columnIndex > -1) {
|
|
982
1069
|
const headerElement = this.parent.getHeaderContent().querySelectorAll('.e-headercelldiv')[this.columnIndex];
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
this.
|
|
1070
|
+
if (headerElement && headerElement.querySelectorAll('.e-treeselectall').length === 0) {
|
|
1071
|
+
const value = false; // Initial state can be false.
|
|
1072
|
+
const rowChkBox = this.parent.createElement('input', { className: 'e-treeselectall', attrs: { 'type': 'checkbox' } });
|
|
1073
|
+
const checkWrap = createCheckBox(this.parent.createElement, false, { checked: value, label: ' ' });
|
|
1074
|
+
checkWrap.classList.add('e-hierarchycheckbox');
|
|
1075
|
+
checkWrap.insertBefore(rowChkBox.cloneNode(), checkWrap.firstChild);
|
|
1076
|
+
if (!isNullOrUndefined(headerElement)) {
|
|
1077
|
+
headerElement.insertBefore(checkWrap, headerElement.firstChild);
|
|
1078
|
+
}
|
|
1079
|
+
this.headerCheckboxFrameEl = checkWrap.querySelector('.e-frame'); // Assign the frame element
|
|
1080
|
+
if (this.parent.autoCheckHierarchy) {
|
|
1081
|
+
this.headerSelection();
|
|
1082
|
+
} // Update header state based on data
|
|
993
1083
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
this.headerSelection(checkBoxvalue);
|
|
1084
|
+
else if (headerElement && headerElement.querySelectorAll('.e-treeselectall').length > 0) {
|
|
1085
|
+
this.headerCheckboxFrameEl = headerElement.querySelector('.e-frame');
|
|
1086
|
+
if (this.parent.autoCheckHierarchy) {
|
|
1087
|
+
this.headerSelection();
|
|
1088
|
+
} // Update status based on current selections
|
|
1000
1089
|
}
|
|
1001
1090
|
}
|
|
1002
1091
|
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Renders a checkbox element for a column cell.
|
|
1094
|
+
*
|
|
1095
|
+
* @param {QueryCellInfoEventArgs} args - The QueryCellInfoEventArgs for the cell.
|
|
1096
|
+
* @returns {Element} The rendered checkbox wrapper element.
|
|
1097
|
+
*/
|
|
1003
1098
|
renderColumnCheckbox(args) {
|
|
1004
1099
|
const rowChkBox = this.parent.createElement('input', { className: 'e-treecheckselect', attrs: { 'type': 'checkbox', 'aria-label': 'checkbox' } });
|
|
1005
1100
|
const data = args.data;
|
|
1006
1101
|
args.cell.classList.add('e-treegridcheckbox');
|
|
1007
1102
|
args.cell.setAttribute('aria-label', 'checkbox');
|
|
1008
|
-
const value = (
|
|
1103
|
+
const value = (data.checkboxState === 'check');
|
|
1009
1104
|
const checkWrap = createCheckBox(this.parent.createElement, false, { checked: value, label: ' ' });
|
|
1010
1105
|
checkWrap.classList.add('e-hierarchycheckbox');
|
|
1011
1106
|
if (this.parent.allowTextWrap) {
|
|
@@ -1016,9 +1111,25 @@ class Selection {
|
|
|
1016
1111
|
removeClass([checkbox], ['e-check', 'e-stop', 'e-uncheck']);
|
|
1017
1112
|
checkWrap.querySelector('.e-frame').classList.add('e-stop');
|
|
1018
1113
|
}
|
|
1114
|
+
else if (data.checkboxState === 'uncheck') {
|
|
1115
|
+
const checkbox = checkWrap.querySelectorAll('.e-frame')[0];
|
|
1116
|
+
removeClass([checkbox], ['e-check', 'e-stop', 'e-uncheck']);
|
|
1117
|
+
checkWrap.querySelector('.e-frame').classList.add('e-uncheck');
|
|
1118
|
+
}
|
|
1119
|
+
else if (data.checkboxState === 'check') {
|
|
1120
|
+
const checkbox = checkWrap.querySelectorAll('.e-frame')[0];
|
|
1121
|
+
removeClass([checkbox], ['e-check', 'e-stop', 'e-uncheck']);
|
|
1122
|
+
checkWrap.querySelector('.e-frame').classList.add('e-check');
|
|
1123
|
+
}
|
|
1019
1124
|
checkWrap.insertBefore(rowChkBox.cloneNode(), checkWrap.firstChild);
|
|
1020
1125
|
return checkWrap;
|
|
1021
1126
|
}
|
|
1127
|
+
/**
|
|
1128
|
+
* Injects the checkbox into a column cell during QueryCellInfo.
|
|
1129
|
+
*
|
|
1130
|
+
* @param {QueryCellInfoEventArgs} container - The cell event args.
|
|
1131
|
+
* @returns {void}
|
|
1132
|
+
*/
|
|
1022
1133
|
columnCheckbox(container) {
|
|
1023
1134
|
const checkWrap = this.renderColumnCheckbox(container);
|
|
1024
1135
|
const containerELe = container.cell.querySelector('.e-treecolumn-container');
|
|
@@ -1038,112 +1149,247 @@ class Selection {
|
|
|
1038
1149
|
container.cell.appendChild(divEle);
|
|
1039
1150
|
}
|
|
1040
1151
|
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Selects or toggles checkboxes for the provided row indexes.
|
|
1154
|
+
*
|
|
1155
|
+
* @param {number[]} rowIndexes - Array of row indexes to toggle selection for.
|
|
1156
|
+
* @returns {void}
|
|
1157
|
+
*/
|
|
1041
1158
|
selectCheckboxes(rowIndexes) {
|
|
1042
|
-
if (isNullOrUndefined(rowIndexes)) {
|
|
1043
|
-
const error = 'The provided value for the rowIndexes is undefined. Please ensure the rowIndexes contains number.';
|
|
1044
|
-
this.parent.trigger(actionFailure, { error: error });
|
|
1045
|
-
}
|
|
1046
1159
|
for (let i = 0; i < rowIndexes.length; i++) {
|
|
1047
|
-
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
const keys = Object.keys(record);
|
|
1053
|
-
for (let j = 0; j < keys.length; j++) {
|
|
1054
|
-
if (Object.prototype.hasOwnProperty.call(flatRecord, keys[parseInt(j.toString(), 10)])) {
|
|
1055
|
-
flatRecord[keys[parseInt(j.toString(), 10)]] = record[keys[parseInt(j.toString(), 10)]];
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
this.traverSelection(record, checkboxState, false);
|
|
1059
|
-
if (this.parent.autoCheckHierarchy) {
|
|
1060
|
-
this.headerSelection();
|
|
1061
|
-
}
|
|
1160
|
+
const viewRec = this.parent.getCurrentViewRecords()[rowIndexes[parseInt(i.toString(), 10)]];
|
|
1161
|
+
const flatRec = getParentData(this.parent, viewRec.uniqueID);
|
|
1162
|
+
const nextState = (flatRec.checkboxState === 'check') ? 'uncheck' : 'check';
|
|
1163
|
+
flatRec.checkboxState = nextState;
|
|
1164
|
+
this.traverSelection(flatRec, nextState, false);
|
|
1062
1165
|
}
|
|
1063
1166
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1167
|
+
/**
|
|
1168
|
+
* Traverses selection for a record and cascades selections to children/parents as necessary.
|
|
1169
|
+
*
|
|
1170
|
+
* @param {ITreeData} record - The record to process.
|
|
1171
|
+
* @param {string} checkboxState - The desired checkbox state ('check'|'uncheck'|'indeterminate').
|
|
1172
|
+
* @param {boolean} isChildItem - True if this invocation is for a child during recursion.
|
|
1173
|
+
* @returns {void}
|
|
1174
|
+
*/
|
|
1175
|
+
traverSelection(record, checkboxState, isChildItem) {
|
|
1176
|
+
const previousState = record.checkboxState;
|
|
1177
|
+
if (!isChildItem) {
|
|
1178
|
+
this.buildVisibleUidMap();
|
|
1179
|
+
}
|
|
1180
|
+
let effectiveChildren = Array.isArray(record.childRecords) ? record.childRecords : [];
|
|
1181
|
+
if ((!effectiveChildren || effectiveChildren.length === 0) && this.parent.autoCheckHierarchy) {
|
|
1182
|
+
effectiveChildren = this.getChildrenFromFlat(record);
|
|
1183
|
+
}
|
|
1184
|
+
if (this.parent.filterModule && this.parent.filterModule.filteredResult.length > 0
|
|
1185
|
+
&& effectiveChildren && effectiveChildren.length) {
|
|
1186
|
+
effectiveChildren = this.getFilteredChildRecords(effectiveChildren);
|
|
1187
|
+
}
|
|
1188
|
+
if (!this.parent.autoCheckHierarchy || !effectiveChildren || effectiveChildren.length === 0) {
|
|
1189
|
+
this.updateSelectedItems(record, checkboxState);
|
|
1190
|
+
if (!isChildItem) {
|
|
1191
|
+
if (record.parentItem && this.parent.autoCheckHierarchy) {
|
|
1192
|
+
this.updateParentSelection(record.parentItem);
|
|
1085
1193
|
}
|
|
1194
|
+
this.updateSelectedCollectionsAfterBulk(this.resolveHeaderSelectionList(), '');
|
|
1195
|
+
this.refreshVisibleCheckboxes();
|
|
1196
|
+
if (this.parent.autoCheckHierarchy) {
|
|
1197
|
+
this.updateHeaderCheckboxState();
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
let childCount = 0;
|
|
1203
|
+
let checkedCount = 0;
|
|
1204
|
+
let indeterminateCount = 0;
|
|
1205
|
+
for (let i = 0; i < effectiveChildren.length; i++) {
|
|
1206
|
+
const child = effectiveChildren[parseInt(i.toString(), 10)];
|
|
1207
|
+
if (!child || child.isSummaryRow) {
|
|
1208
|
+
continue;
|
|
1209
|
+
}
|
|
1210
|
+
childCount++;
|
|
1211
|
+
this.updateSelectedItems(child, checkboxState, true);
|
|
1212
|
+
if (child.hasChildRecords) {
|
|
1213
|
+
this.traverSelection(child, checkboxState, true);
|
|
1086
1214
|
}
|
|
1215
|
+
if (child.checkboxState === 'check') {
|
|
1216
|
+
checkedCount++;
|
|
1217
|
+
}
|
|
1218
|
+
else if (child.checkboxState === 'indeterminate') {
|
|
1219
|
+
indeterminateCount++;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (record.uniqueID) {
|
|
1223
|
+
this.parentSelectionCounters[record.uniqueID] = {
|
|
1224
|
+
total: childCount,
|
|
1225
|
+
checked: checkedCount,
|
|
1226
|
+
indeterminate: indeterminateCount
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
const summary = this.parentSelectionCounters[record.uniqueID];
|
|
1230
|
+
let finalState = this.deriveParentState(record, summary);
|
|
1231
|
+
if (checkboxState === 'check' && summary.total > 0 && summary.checked === summary.total && summary.indeterminate === 0) {
|
|
1232
|
+
finalState = 'check';
|
|
1233
|
+
}
|
|
1234
|
+
this.updateSelectedItems(record, finalState);
|
|
1235
|
+
if (!isChildItem && record.parentItem && this.parent.autoCheckHierarchy) {
|
|
1236
|
+
this.updateParentSelection(record.parentItem, previousState, finalState);
|
|
1237
|
+
}
|
|
1238
|
+
if (!isChildItem) {
|
|
1239
|
+
const bulkList = this.resolveHeaderSelectionList();
|
|
1240
|
+
this.updateSelectedCollectionsAfterBulk(bulkList, ''); // This will rebuild selectedItems & selectedIndexes based on total state
|
|
1241
|
+
this.refreshVisibleCheckboxes();
|
|
1242
|
+
this.updateHeaderCheckboxState();
|
|
1087
1243
|
}
|
|
1088
1244
|
}
|
|
1245
|
+
/**
|
|
1246
|
+
* Filters provided child records against the current filter result.
|
|
1247
|
+
*
|
|
1248
|
+
* @param {ITreeData[]} childRecords - The array of child records to filter.
|
|
1249
|
+
* @returns {ITreeData[]} The filtered child records array.
|
|
1250
|
+
*/
|
|
1089
1251
|
getFilteredChildRecords(childRecords) {
|
|
1090
1252
|
const filteredChildRecords = childRecords.filter((e) => {
|
|
1091
1253
|
return this.parent.filterModule.filteredResult.indexOf(e) > -1;
|
|
1092
1254
|
});
|
|
1093
1255
|
return filteredChildRecords;
|
|
1094
1256
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
if (!isNullOrUndefined(checkBoxRecord)) {
|
|
1114
|
-
if (checkBoxRecord.checkboxState === 'indeterminate') {
|
|
1115
|
-
indeter++;
|
|
1116
|
-
}
|
|
1117
|
-
else if (checkBoxRecord.checkboxState === 'check') {
|
|
1118
|
-
checkChildRecords++;
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
if (indeter > 0 || (checkChildRecords > 0 && checkChildRecords !== length)) {
|
|
1123
|
-
record.checkboxState = 'indeterminate';
|
|
1257
|
+
/**
|
|
1258
|
+
* Derives children for a record from flatData using the parentItem link.
|
|
1259
|
+
* Used when childRecords is missing or empty.
|
|
1260
|
+
*
|
|
1261
|
+
* @param {ITreeData} record - The record for which to find child elements.
|
|
1262
|
+
* @returns {ITreeData[]} An array of child records derived from flatData.
|
|
1263
|
+
*/
|
|
1264
|
+
getChildrenFromFlat(record) {
|
|
1265
|
+
const all = (this.parent.flatData);
|
|
1266
|
+
if (!all || !record) {
|
|
1267
|
+
return [];
|
|
1268
|
+
}
|
|
1269
|
+
const pid = record.uniqueID;
|
|
1270
|
+
const out = [];
|
|
1271
|
+
for (let i = 0; i < all.length; i++) {
|
|
1272
|
+
const r = all[parseInt(i.toString(), 10)];
|
|
1273
|
+
if (!r || r.isSummaryRow) {
|
|
1274
|
+
continue;
|
|
1124
1275
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1276
|
+
const p = r.parentItem;
|
|
1277
|
+
if (p && p.uniqueID === pid) {
|
|
1278
|
+
out.push(r);
|
|
1128
1279
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1280
|
+
}
|
|
1281
|
+
return out;
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Updates parent selection by rebuilding summary and applying deltas, then bubbling up if required.
|
|
1285
|
+
*
|
|
1286
|
+
* @param {ITreeData} parentRecord - The parent record reference.
|
|
1287
|
+
* @param {string} [previousChildState] - Previous state of the child that changed.
|
|
1288
|
+
* @param {string} [nextChildState] - Next state of the child that changed.
|
|
1289
|
+
* @returns {void}
|
|
1290
|
+
*/
|
|
1291
|
+
updateParentSelection(parentRecord, previousChildState, nextChildState) {
|
|
1292
|
+
const parent = getParentData(this.parent, parentRecord.uniqueID);
|
|
1293
|
+
if (!parent) {
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
const summary = this.buildSelectionSummary(parent);
|
|
1297
|
+
if (previousChildState) {
|
|
1298
|
+
this.applySummaryDelta(summary, previousChildState, -1);
|
|
1299
|
+
}
|
|
1300
|
+
if (nextChildState) {
|
|
1301
|
+
this.applySummaryDelta(summary, nextChildState, 1);
|
|
1302
|
+
}
|
|
1303
|
+
if (parent.uniqueID) {
|
|
1304
|
+
this.parentSelectionCounters[parent.uniqueID] = summary;
|
|
1305
|
+
}
|
|
1306
|
+
const desiredState = this.deriveParentState(parent, summary);
|
|
1307
|
+
if (parent.checkboxState === desiredState) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
const parentPrev = parent.checkboxState;
|
|
1311
|
+
parent.checkboxState = desiredState;
|
|
1312
|
+
this.updateSelectedItems(parent, desiredState);
|
|
1313
|
+
if (parent.parentItem) {
|
|
1314
|
+
this.updateParentSelection(parent.parentItem, parentPrev, desiredState);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Builds a selection summary for a record's children.
|
|
1319
|
+
*
|
|
1320
|
+
* @param {Object} record - The record whose children should be summarized.
|
|
1321
|
+
* @param {boolean} [ignoreFilter] - If true, ignore current filter when computing summary.
|
|
1322
|
+
* @returns {{ total: number, checked: number, indeterminate: number }} The computed summary.
|
|
1323
|
+
*/
|
|
1324
|
+
buildSelectionSummary(record, ignoreFilter) {
|
|
1325
|
+
const summary = { total: 0, checked: 0, indeterminate: 0 };
|
|
1326
|
+
let children = [];
|
|
1327
|
+
if (record && Array.isArray(record.childRecords) && record.childRecords.length) {
|
|
1328
|
+
children = record.childRecords;
|
|
1329
|
+
}
|
|
1330
|
+
else {
|
|
1331
|
+
children = this.getChildrenFromFlat(record);
|
|
1332
|
+
}
|
|
1333
|
+
if (!ignoreFilter && this.parent.filterModule && this.parent.filterModule.filteredResult.length > 0) {
|
|
1334
|
+
children = this.getFilteredChildRecords(children);
|
|
1335
|
+
}
|
|
1336
|
+
for (let i = 0; i < children.length; i++) {
|
|
1337
|
+
const child = children[parseInt(i.toString(), 10)];
|
|
1338
|
+
if (!child || child.isSummaryRow) {
|
|
1339
|
+
continue;
|
|
1132
1340
|
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1341
|
+
summary.total++;
|
|
1342
|
+
if (child.checkboxState === 'check') {
|
|
1343
|
+
summary.checked++;
|
|
1135
1344
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
this.updateParentSelection(record.parentItem);
|
|
1345
|
+
else if (child.checkboxState === 'indeterminate') {
|
|
1346
|
+
summary.indeterminate++;
|
|
1139
1347
|
}
|
|
1140
1348
|
}
|
|
1349
|
+
return summary;
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Applies a delta to a selection summary based on a state change.
|
|
1353
|
+
*
|
|
1354
|
+
* @param {Object} summary - The summary to modify. Object with numeric properties: total, checked, indeterminate.
|
|
1355
|
+
* @param {string} state - The state that changed ('check' | 'indeterminate').
|
|
1356
|
+
* @param {number} delta - The delta to apply (e.g. +1 or -1).
|
|
1357
|
+
* @returns {void}
|
|
1358
|
+
*/
|
|
1359
|
+
applySummaryDelta(summary, state, delta) {
|
|
1360
|
+
if (state === 'check') {
|
|
1361
|
+
summary.checked = Math.max(0, summary.checked + delta);
|
|
1362
|
+
}
|
|
1363
|
+
else if (state === 'indeterminate') {
|
|
1364
|
+
summary.indeterminate = Math.max(0, summary.indeterminate + delta);
|
|
1365
|
+
}
|
|
1141
1366
|
}
|
|
1367
|
+
/**
|
|
1368
|
+
* Derives the parent's checkbox state based on children summary counts.
|
|
1369
|
+
*
|
|
1370
|
+
* @param {ITreeData} record The parent record.
|
|
1371
|
+
* @param {{ total: number, checked: number, indeterminate: number }} summary The children summary.
|
|
1372
|
+
* @returns {'check'|'indeterminate'|'uncheck'} The derived checkbox state.
|
|
1373
|
+
*/
|
|
1374
|
+
deriveParentState(record, summary) {
|
|
1375
|
+
const total = summary.total;
|
|
1376
|
+
const checked = summary.checked;
|
|
1377
|
+
const indeterminate = summary.indeterminate;
|
|
1378
|
+
if (indeterminate > 0 || (checked > 0 && checked !== total)) {
|
|
1379
|
+
return 'indeterminate';
|
|
1380
|
+
}
|
|
1381
|
+
if (checked === total && total > 0) {
|
|
1382
|
+
return 'check';
|
|
1383
|
+
}
|
|
1384
|
+
return 'uncheck';
|
|
1385
|
+
}
|
|
1386
|
+
/**
|
|
1387
|
+
* Handles header checkbox (select all / clear all) behavior.
|
|
1388
|
+
*
|
|
1389
|
+
* @param {boolean} [checkAll] - Optional explicit flag to check or uncheck all.
|
|
1390
|
+
* @returns {void}
|
|
1391
|
+
*/
|
|
1142
1392
|
headerSelection(checkAll) {
|
|
1143
|
-
let index = -1;
|
|
1144
|
-
let length = 0;
|
|
1145
|
-
//This property used to maintain the check state of the currentview data after clear filtering
|
|
1146
|
-
let multiFilterCheckState = false;
|
|
1147
1393
|
if (!isNullOrUndefined(this.parent.filterModule) && this.parent.filterModule.filteredResult.length > 0) {
|
|
1148
1394
|
const filterResult = this.parent.filterModule.filteredResult;
|
|
1149
1395
|
if (this.filteredList.length === 0) {
|
|
@@ -1153,160 +1399,397 @@ class Selection {
|
|
|
1153
1399
|
this.searchingRecords = filterResult;
|
|
1154
1400
|
}
|
|
1155
1401
|
else {
|
|
1156
|
-
if (this.filteredList !== filterResult) {
|
|
1402
|
+
if (this.filteredList !== filterResult && !this.parent.grid.searchSettings.key.length) {
|
|
1157
1403
|
this.filteredList = filterResult;
|
|
1158
|
-
|
|
1159
|
-
}
|
|
1160
|
-
else {
|
|
1161
|
-
multiFilterCheckState = false;
|
|
1404
|
+
this.searchingRecords = [];
|
|
1162
1405
|
}
|
|
1163
1406
|
}
|
|
1164
1407
|
}
|
|
1165
|
-
if (this.
|
|
1166
|
-
|
|
1167
|
-
|
|
1408
|
+
if (this.searchingRecords.length > 0 && !isNullOrUndefined(checkAll)) {
|
|
1409
|
+
this.filteredList = this.searchingRecords;
|
|
1410
|
+
}
|
|
1411
|
+
else if (this.filteredList.length > 0 && !this.parent.filterSettings.columns.length
|
|
1412
|
+
&& !this.parent.grid.searchSettings.key.length) {
|
|
1413
|
+
this.filteredList = [];
|
|
1414
|
+
}
|
|
1415
|
+
const records = this.resolveHeaderSelectionList(true);
|
|
1416
|
+
if (!isNullOrUndefined(checkAll)) {
|
|
1417
|
+
this.resetSelectionCaches();
|
|
1418
|
+
const targetState = checkAll ? 'check' : 'uncheck';
|
|
1419
|
+
this.headerSelectionState = targetState;
|
|
1420
|
+
this.processHeaderSelection(records, targetState);
|
|
1421
|
+
this.finalizeParentsAfterBulk(records);
|
|
1422
|
+
this.updateSelectedCollectionsAfterBulk(records, '');
|
|
1423
|
+
this.refreshVisibleCheckboxes();
|
|
1424
|
+
this.updateHeaderCheckboxState();
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
this.totalSelectableCount = this.countSelectableRecords(records);
|
|
1428
|
+
this.updateHeaderCheckboxState();
|
|
1429
|
+
}
|
|
1430
|
+
/**
|
|
1431
|
+
* Finalizes parent states after a bulk header operation (e.g., Select All).
|
|
1432
|
+
* This ensures parent states (checked/indeterminate) are correct after cascades.
|
|
1433
|
+
*
|
|
1434
|
+
* @param {ITreeData[]} records - The records that were processed in the bulk operation.
|
|
1435
|
+
* @returns {void}
|
|
1436
|
+
*/
|
|
1437
|
+
finalizeParentsAfterBulk(records) {
|
|
1438
|
+
const all = records;
|
|
1439
|
+
for (let i = 0; i < all.length; i++) {
|
|
1440
|
+
const rec = all[parseInt(i.toString(), 10)];
|
|
1441
|
+
if (!rec || !rec.hasChildRecords) {
|
|
1442
|
+
continue;
|
|
1168
1443
|
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1444
|
+
const summary = this.buildSelectionSummary(rec, true);
|
|
1445
|
+
this.parentSelectionCounters[rec.uniqueID] = summary;
|
|
1446
|
+
let finalState = this.deriveParentState(rec, summary);
|
|
1447
|
+
if (this.headerSelectionState === 'check' &&
|
|
1448
|
+
summary.total > 0 && summary.checked === summary.total && summary.indeterminate === 0) {
|
|
1449
|
+
finalState = 'check';
|
|
1450
|
+
}
|
|
1451
|
+
else if (this.headerSelectionState === 'uncheck') {
|
|
1452
|
+
finalState = 'uncheck';
|
|
1453
|
+
}
|
|
1454
|
+
if (rec.checkboxState !== finalState) {
|
|
1455
|
+
this.updateSelectedItems(rec, finalState);
|
|
1171
1456
|
}
|
|
1172
1457
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1458
|
+
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Processes header selection for each record, setting their state silently in the data model.
|
|
1461
|
+
* Called during bulk operations like "select all".
|
|
1462
|
+
*
|
|
1463
|
+
* @param {ITreeData[]} records - The records to process.
|
|
1464
|
+
* @param {string} targetState - The target state to set on each record.
|
|
1465
|
+
* @returns {void}
|
|
1466
|
+
*/
|
|
1467
|
+
processHeaderSelection(records, targetState) {
|
|
1468
|
+
for (let i = 0; i < records.length; i++) {
|
|
1469
|
+
const record = records[parseInt(i.toString(), 10)];
|
|
1470
|
+
if (!record) {
|
|
1471
|
+
continue;
|
|
1472
|
+
}
|
|
1473
|
+
const previousState = record.checkboxState;
|
|
1474
|
+
if (previousState === targetState) {
|
|
1475
|
+
continue;
|
|
1476
|
+
}
|
|
1477
|
+
record.checkboxState = targetState;
|
|
1478
|
+
this.updateSelectedItems(record, targetState, true);
|
|
1182
1479
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Rebuilds `selectedItems`, `selectedUidMap`, and `selectedIndexes` based on the current data states in the model.
|
|
1483
|
+
* This method is called after bulk operations (like headerSelection, grid actions, etc.) to synchronize internal collections.
|
|
1484
|
+
* It ensures `selectedItems` retains original selection order *as much as possible* for currently checked items
|
|
1485
|
+
* and `selectedIndexes` reflects their *current visible order*.
|
|
1486
|
+
*
|
|
1487
|
+
* @param {ITreeData[]} records - The records that were processed (or the full data set if re-evaluating everything).
|
|
1488
|
+
* @param {string} requestType - The data action type such as filtering, searching, refresh,etc.
|
|
1489
|
+
* @returns {void}
|
|
1490
|
+
*/
|
|
1491
|
+
updateSelectedCollectionsAfterBulk(records, requestType) {
|
|
1492
|
+
const hasFilter = !!(this.parent.filterModule && this.parent.filterModule.filteredResult &&
|
|
1493
|
+
this.parent.filterModule.filteredResult.length);
|
|
1494
|
+
const hasSearch = !!(this.parent.grid && this.parent.grid.searchSettings &&
|
|
1495
|
+
this.parent.grid.searchSettings.key && this.parent.grid.searchSettings.key.length);
|
|
1496
|
+
const isFilterOrSearch = hasFilter || hasSearch || requestType === 'refresh' || requestType === 'searching';
|
|
1497
|
+
const currentlySelectedItemsInOrder = isFilterOrSearch ? records : this.selectedItems.slice();
|
|
1498
|
+
const newSelectedItems = [];
|
|
1499
|
+
const newSelectedUidMap = new Map();
|
|
1500
|
+
const newSelectedIndexes = [];
|
|
1501
|
+
for (const item of currentlySelectedItemsInOrder) {
|
|
1502
|
+
if (item.hasChildRecords && isFilterOrSearch && item.level === 0) {
|
|
1503
|
+
this.updateParentSelection(item);
|
|
1504
|
+
}
|
|
1505
|
+
if (item.uniqueID && item.checkboxState === 'check') {
|
|
1506
|
+
newSelectedItems.push(item);
|
|
1507
|
+
newSelectedUidMap.set(item.uniqueID, true);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
if (!isFilterOrSearch) {
|
|
1511
|
+
const allFlatData = this.parent.flatData;
|
|
1512
|
+
if (allFlatData) {
|
|
1513
|
+
for (const record of allFlatData) {
|
|
1514
|
+
if (!record || record.isSummaryRow) {
|
|
1188
1515
|
continue;
|
|
1189
1516
|
}
|
|
1190
|
-
if (
|
|
1191
|
-
|
|
1517
|
+
if (record.uniqueID && record.checkboxState === 'check' && !newSelectedUidMap.has(record.uniqueID)) {
|
|
1518
|
+
newSelectedItems.push(record);
|
|
1519
|
+
newSelectedUidMap.set(record.uniqueID, true);
|
|
1192
1520
|
}
|
|
1193
|
-
data[parseInt(i.toString(), 10)].checkboxState = 'check';
|
|
1194
|
-
this.updateSelectedItems(data[parseInt(i.toString(), 10)], data[parseInt(i.toString(), 10)].checkboxState);
|
|
1195
1521
|
}
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
this.selectedItems = newSelectedItems;
|
|
1525
|
+
this.selectedUidMap = newSelectedUidMap;
|
|
1526
|
+
this.buildVisibleUidMap();
|
|
1527
|
+
for (const item of this.selectedItems) {
|
|
1528
|
+
const visibleIdx = this.visibleUidIndex[item.uniqueID];
|
|
1529
|
+
if (visibleIdx !== undefined) {
|
|
1530
|
+
newSelectedIndexes.push(visibleIdx);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
this.selectedIndexes = newSelectedIndexes;
|
|
1534
|
+
this.checkedItemCount = this.selectedItems.length;
|
|
1535
|
+
this.totalSelectableCount =
|
|
1536
|
+
this.countSelectableRecords(records);
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Refreshes visible checkbox DOM elements to reflect the current data state.
|
|
1540
|
+
* This method exclusively updates the UI representation of checkboxes.
|
|
1541
|
+
*
|
|
1542
|
+
* @returns {void}
|
|
1543
|
+
*/
|
|
1544
|
+
refreshVisibleCheckboxes() {
|
|
1545
|
+
this.buildVisibleUidMap();
|
|
1546
|
+
const data = this.parent.getCurrentViewRecords();
|
|
1547
|
+
const uidMap = this.parent.uniqueIDCollection;
|
|
1548
|
+
for (let i = 0; data && i < data.length; i++) {
|
|
1549
|
+
const viewRec = data[parseInt(i.toString(), 10)];
|
|
1550
|
+
if (!viewRec) {
|
|
1551
|
+
continue;
|
|
1552
|
+
}
|
|
1553
|
+
const uid = viewRec.uniqueID;
|
|
1554
|
+
const srcRec = (uidMap && uid != null) ? uidMap[String(uid)] : viewRec;
|
|
1555
|
+
const state = (srcRec && srcRec.checkboxState) ? srcRec.checkboxState : 'uncheck';
|
|
1556
|
+
let rowEl = null;
|
|
1557
|
+
const rowUid = viewRec.uid;
|
|
1558
|
+
if (rowUid) {
|
|
1559
|
+
rowEl = this.parent.grid.getRowElementByUID(rowUid);
|
|
1560
|
+
}
|
|
1561
|
+
if (!rowEl) {
|
|
1562
|
+
const rows = this.parent.getRows();
|
|
1563
|
+
rowEl = rows && rows[parseInt(i.toString(), 10)];
|
|
1564
|
+
if ((this.parent.frozenRows || this.parent.getFrozenColumns()) && !rowEl) {
|
|
1565
|
+
const movableRows = this.parent.getDataRows();
|
|
1566
|
+
rowEl = movableRows && movableRows[parseInt(i.toString(), 10)];
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
if (rowEl) {
|
|
1570
|
+
const frame = rowEl.querySelector('.e-hierarchycheckbox .e-frame');
|
|
1571
|
+
if (frame) {
|
|
1572
|
+
removeClass([frame], ['e-check', 'e-stop', 'e-uncheck']);
|
|
1573
|
+
frame.classList.add(state === 'indeterminate' ? 'e-stop' : ('e-' + state));
|
|
1574
|
+
const input = rowEl.querySelector('.e-treecheckselect');
|
|
1575
|
+
if (input) {
|
|
1576
|
+
input.setAttribute('aria-checked', state === 'check' ? 'true' :
|
|
1577
|
+
(state === 'uncheck' ? 'false' : 'mixed'));
|
|
1204
1578
|
}
|
|
1205
1579
|
}
|
|
1206
1580
|
}
|
|
1207
1581
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Resets internal selection caches to their initial state.
|
|
1585
|
+
* This is usually called before a bulk selection operation (like "select all").
|
|
1586
|
+
*
|
|
1587
|
+
* @returns {void}
|
|
1588
|
+
*/
|
|
1589
|
+
resetSelectionCaches() {
|
|
1590
|
+
this.parentSelectionCounters = {};
|
|
1591
|
+
this.selectedUidMap = new Map();
|
|
1592
|
+
this.selectedItems = [];
|
|
1593
|
+
this.selectedIndexes = [];
|
|
1594
|
+
this.totalSelectableCount = 0;
|
|
1595
|
+
this.headerSelectionState = 'uncheck';
|
|
1596
|
+
this.checkedItemCount = 0;
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Counts selectable (non-summary) records in the provided array.
|
|
1600
|
+
*
|
|
1601
|
+
* @param {ITreeData[]} records - The records to count.
|
|
1602
|
+
* @returns {number} The number of selectable records.
|
|
1603
|
+
*/
|
|
1604
|
+
countSelectableRecords(records) {
|
|
1605
|
+
let count = 0;
|
|
1606
|
+
if (!records) {
|
|
1607
|
+
return count;
|
|
1215
1608
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1609
|
+
for (let i = 0; i < records.length; i++) {
|
|
1610
|
+
const rec = records[parseInt(i.toString(), 10)];
|
|
1611
|
+
if (rec && !rec.isSummaryRow) {
|
|
1612
|
+
count++;
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
return count;
|
|
1616
|
+
}
|
|
1617
|
+
/**
|
|
1618
|
+
* Resolves the list of records used for header selection operations (e.g., for `select all`).
|
|
1619
|
+
*
|
|
1620
|
+
* @param {boolean} [includeAll] - If true and data is local, returns flatData (all records for full dataset actions).
|
|
1621
|
+
* @returns {ITreeData[]} The array of records to consider for header operations.
|
|
1622
|
+
*/
|
|
1623
|
+
resolveHeaderSelectionList(includeAll) {
|
|
1624
|
+
let dataToProcess = [];
|
|
1625
|
+
if (!isRemoteData(this.parent)) {
|
|
1626
|
+
const hasFilter = !!(this.parent.filterModule &&
|
|
1627
|
+
this.parent.filterModule.filteredResult &&
|
|
1628
|
+
this.parent.filterModule.filteredResult.length);
|
|
1629
|
+
const hasSearch = !!(this.parent.grid &&
|
|
1630
|
+
this.parent.grid.searchSettings &&
|
|
1631
|
+
this.parent.grid.searchSettings.key &&
|
|
1632
|
+
this.parent.grid.searchSettings.key.length);
|
|
1633
|
+
if (includeAll) {
|
|
1634
|
+
if (hasFilter) {
|
|
1635
|
+
dataToProcess = this.filteredList && this.filteredList.length
|
|
1636
|
+
? this.filteredList
|
|
1637
|
+
: this.parent.filterModule.filteredResult;
|
|
1638
|
+
}
|
|
1639
|
+
else if (hasSearch && this.searchingRecords && this.searchingRecords.length) {
|
|
1640
|
+
dataToProcess = this.searchingRecords;
|
|
1641
|
+
}
|
|
1642
|
+
else {
|
|
1643
|
+
dataToProcess = this.parent.flatData;
|
|
1644
|
+
}
|
|
1222
1645
|
}
|
|
1223
1646
|
else {
|
|
1224
|
-
|
|
1225
|
-
|
|
1647
|
+
if (hasFilter) {
|
|
1648
|
+
dataToProcess = this.filteredList && this.filteredList.length
|
|
1649
|
+
? this.filteredList
|
|
1650
|
+
: this.parent.filterModule.filteredResult;
|
|
1651
|
+
}
|
|
1652
|
+
else if (hasSearch && this.searchingRecords && this.searchingRecords.length) {
|
|
1653
|
+
dataToProcess = this.searchingRecords;
|
|
1654
|
+
}
|
|
1655
|
+
else {
|
|
1656
|
+
dataToProcess = this.parent.flatData;
|
|
1657
|
+
}
|
|
1226
1658
|
}
|
|
1227
1659
|
}
|
|
1228
1660
|
else {
|
|
1229
|
-
|
|
1661
|
+
dataToProcess = this.parent.getCurrentViewRecords();
|
|
1230
1662
|
}
|
|
1663
|
+
return dataToProcess;
|
|
1231
1664
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
if (!isNullOrUndefined(checkbox)) {
|
|
1249
|
-
removeClass([checkbox], ['e-check', 'e-stop', 'e-uncheck']);
|
|
1665
|
+
/**
|
|
1666
|
+
* Updates the header checkbox state (checked/indeterminate/unchecked) based on current selections.
|
|
1667
|
+
*
|
|
1668
|
+
* @returns {void}
|
|
1669
|
+
*/
|
|
1670
|
+
updateHeaderCheckboxState() {
|
|
1671
|
+
const frame = this.headerCheckboxFrameEl;
|
|
1672
|
+
if (!frame) {
|
|
1673
|
+
return;
|
|
1674
|
+
}
|
|
1675
|
+
const recordsForHeaderLogic = this.resolveHeaderSelectionList(true);
|
|
1676
|
+
this.totalSelectableCount = this.countSelectableRecords(recordsForHeaderLogic);
|
|
1677
|
+
let checkedCountForHeaderLogic = 0;
|
|
1678
|
+
for (const record of recordsForHeaderLogic) {
|
|
1679
|
+
if (record && !record.isSummaryRow && record.checkboxState === 'check') {
|
|
1680
|
+
checkedCountForHeaderLogic++;
|
|
1250
1681
|
}
|
|
1251
1682
|
}
|
|
1252
|
-
|
|
1253
|
-
if (
|
|
1254
|
-
|
|
1683
|
+
removeClass([frame], ['e-check', 'e-stop', 'e-uncheck']);
|
|
1684
|
+
if (this.totalSelectableCount === 0) {
|
|
1685
|
+
frame.classList.add('e-uncheck');
|
|
1255
1686
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1687
|
+
else if (checkedCountForHeaderLogic === 0) {
|
|
1688
|
+
frame.classList.add('e-uncheck');
|
|
1689
|
+
}
|
|
1690
|
+
else if (checkedCountForHeaderLogic === this.totalSelectableCount) {
|
|
1691
|
+
frame.classList.add('e-check');
|
|
1692
|
+
}
|
|
1693
|
+
else {
|
|
1694
|
+
frame.classList.add('e-stop');
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* Updates selection arrays (selectedItems, selectedUidMap, selectedIndexes) and visible DOM for a single record.
|
|
1699
|
+
* This is the core method for managing the state of a single checkbox.
|
|
1700
|
+
*
|
|
1701
|
+
* @param {ITreeData} currentRecord - The record to update.
|
|
1702
|
+
* @param {string} checkState - The new checkbox state ('check' | 'uncheck' | 'indeterminate').
|
|
1703
|
+
* @param {boolean} [silent] - If true, update is silent (only updates data model, no collection management or DOM update).
|
|
1704
|
+
* @returns {void}
|
|
1705
|
+
*/
|
|
1706
|
+
updateSelectedItems(currentRecord, checkState, silent) {
|
|
1707
|
+
this.buildVisibleUidMap();
|
|
1708
|
+
const uid = currentRecord.uniqueID;
|
|
1709
|
+
const uidMap = this.parent.uniqueIDCollection;
|
|
1710
|
+
const checkboxRecord = (uidMap && uid != null) ? (uidMap[String(uid)] ?
|
|
1711
|
+
uidMap[String(uid)] : currentRecord) : currentRecord;
|
|
1712
|
+
const isSummary = currentRecord.isSummaryRow === true;
|
|
1713
|
+
const previousState = checkboxRecord.checkboxState;
|
|
1714
|
+
const currentVisibleIndex = this.visibleUidIndex[String(uid)];
|
|
1715
|
+
checkboxRecord.checkboxState = checkState;
|
|
1716
|
+
if (silent) {
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1719
|
+
if (!isSummary && previousState !== checkState) {
|
|
1720
|
+
if (checkState === 'check') {
|
|
1721
|
+
this.checkedItemCount++;
|
|
1722
|
+
if (!this.selectedUidMap.has(String(uid))) {
|
|
1723
|
+
if (checkboxRecord.uniqueID) {
|
|
1724
|
+
this.selectedUidMap.set(String(checkboxRecord.uniqueID), true);
|
|
1725
|
+
}
|
|
1726
|
+
this.selectedItems.push(checkboxRecord);
|
|
1727
|
+
if (currentVisibleIndex !== undefined && this.selectedIndexes.indexOf(currentVisibleIndex) === -1) {
|
|
1728
|
+
this.selectedIndexes.push(currentVisibleIndex);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1271
1731
|
}
|
|
1272
|
-
if (
|
|
1273
|
-
this.
|
|
1732
|
+
else if (previousState === 'check' || previousState === 'indeterminate') {
|
|
1733
|
+
if (this.checkedItemCount > 0) {
|
|
1734
|
+
this.checkedItemCount--;
|
|
1735
|
+
}
|
|
1736
|
+
if (checkboxRecord && checkboxRecord.uniqueID && this.selectedUidMap.has(String(checkboxRecord.uniqueID))) {
|
|
1737
|
+
this.selectedUidMap.delete(String(checkboxRecord.uniqueID));
|
|
1738
|
+
const itemIdx = this.selectedItems.indexOf(checkboxRecord);
|
|
1739
|
+
if (itemIdx !== -1) {
|
|
1740
|
+
this.selectedItems.splice(itemIdx, 1);
|
|
1741
|
+
}
|
|
1742
|
+
if (currentVisibleIndex !== undefined) {
|
|
1743
|
+
const indexInSelectedIndexes = this.selectedIndexes.indexOf(currentVisibleIndex);
|
|
1744
|
+
if (indexInSelectedIndexes > -1) {
|
|
1745
|
+
this.selectedIndexes.splice(indexInSelectedIndexes, 1);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1274
1749
|
}
|
|
1275
1750
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1751
|
+
let rowEl = null;
|
|
1752
|
+
const rowUid = currentRecord.uid;
|
|
1753
|
+
if (rowUid) {
|
|
1754
|
+
rowEl = this.parent.grid.getRowElementByUID(rowUid);
|
|
1755
|
+
}
|
|
1756
|
+
if (!rowEl) {
|
|
1757
|
+
const recordVisibleIndex = currentVisibleIndex !== undefined ? currentVisibleIndex : (typeof this.visibleUidIndex[String(uid)] === 'number' ? this.visibleUidIndex[String(uid)] : -1);
|
|
1758
|
+
if (recordVisibleIndex > -1) {
|
|
1759
|
+
rowEl = this.parent.getRows()[parseInt(recordVisibleIndex.toString(), 10)];
|
|
1760
|
+
if (!rowEl && (this.parent.frozenRows || this.parent.getFrozenColumns())) {
|
|
1761
|
+
rowEl = this.parent.getDataRows()[parseInt(recordVisibleIndex.toString(), 10)];
|
|
1762
|
+
}
|
|
1284
1763
|
}
|
|
1285
1764
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
if (
|
|
1289
|
-
|
|
1290
|
-
|
|
1765
|
+
if (rowEl) {
|
|
1766
|
+
const frame = rowEl.querySelector('.e-hierarchycheckbox .e-frame');
|
|
1767
|
+
if (frame) {
|
|
1768
|
+
removeClass([frame], ['e-check', 'e-stop', 'e-uncheck']);
|
|
1769
|
+
frame.classList.add(checkState === 'indeterminate' ? 'e-stop' : ('e-' + checkState));
|
|
1770
|
+
}
|
|
1771
|
+
const input = rowEl.querySelector('.e-treecheckselect');
|
|
1772
|
+
if (input) {
|
|
1773
|
+
input.setAttribute('aria-checked', checkState === 'check' ? 'true' :
|
|
1774
|
+
(checkState === 'uncheck' ? 'false' : 'mixed'));
|
|
1291
1775
|
}
|
|
1292
1776
|
}
|
|
1293
1777
|
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Handles various grid actions and updates selection state accordingly.
|
|
1780
|
+
* This method ensures that selection state is maintained and UI is refreshed after grid operations.
|
|
1781
|
+
*
|
|
1782
|
+
* @param {CellSaveEventArgs} args - Action arguments containing requestType and data.
|
|
1783
|
+
* @returns {void}
|
|
1784
|
+
*/
|
|
1294
1785
|
updateGridActions(args) {
|
|
1295
1786
|
const requestType = args.requestType;
|
|
1296
|
-
let childData;
|
|
1297
|
-
let childLength;
|
|
1298
1787
|
if (isCheckboxcolumn(this.parent)) {
|
|
1299
1788
|
if (this.parent.autoCheckHierarchy) {
|
|
1300
1789
|
if ((requestType === 'sorting' || requestType === 'paging')) {
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
this.selectedIndexes = [];
|
|
1305
|
-
for (let i = 0; i < childLength; i++) {
|
|
1306
|
-
if (!rows[parseInt(i.toString(), 10)].classList.contains('e-summaryrow')) {
|
|
1307
|
-
this.updateSelectedItems(childData[parseInt(i.toString(), 10)], childData[parseInt(i.toString(), 10)].checkboxState);
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1790
|
+
this.updateSelectedCollectionsAfterBulk(this.resolveHeaderSelectionList(), '');
|
|
1791
|
+
this.refreshVisibleCheckboxes();
|
|
1792
|
+
this.updateHeaderCheckboxState();
|
|
1310
1793
|
}
|
|
1311
1794
|
else if (requestType === 'delete' || args.action === 'add') {
|
|
1312
1795
|
let updatedData = [];
|
|
@@ -1318,71 +1801,68 @@ class Selection {
|
|
|
1318
1801
|
}
|
|
1319
1802
|
for (let i = 0; i < updatedData.length; i++) {
|
|
1320
1803
|
if (requestType === 'delete') {
|
|
1321
|
-
|
|
1322
|
-
const checkedIndex = this.selectedIndexes.indexOf(index);
|
|
1323
|
-
this.selectedIndexes.splice(checkedIndex, 1);
|
|
1324
|
-
this.updateSelectedItems(updatedData[parseInt(i.toString(), 10)], 'uncheck');
|
|
1804
|
+
this.updateSelectedItems(updatedData[parseInt(i.toString(), 10)], 'uncheck', false);
|
|
1325
1805
|
}
|
|
1326
1806
|
if (!isNullOrUndefined(updatedData[parseInt(i.toString(), 10)].parentItem)) {
|
|
1327
1807
|
this.updateParentSelection(updatedData[parseInt(i.toString(), 10)].parentItem);
|
|
1328
1808
|
}
|
|
1329
1809
|
}
|
|
1810
|
+
this.updateSelectedCollectionsAfterBulk(this.resolveHeaderSelectionList(true), '');
|
|
1811
|
+
this.refreshVisibleCheckboxes();
|
|
1812
|
+
if (this.parent.autoCheckHierarchy) {
|
|
1813
|
+
this.updateHeaderCheckboxState();
|
|
1814
|
+
}
|
|
1330
1815
|
}
|
|
1331
1816
|
else if (args.requestType === 'add' && this.parent.autoCheckHierarchy) {
|
|
1332
1817
|
args.data.checkboxState = 'uncheck';
|
|
1333
1818
|
}
|
|
1334
|
-
else if (requestType === 'filtering' || requestType === 'searching' || requestType === 'refresh'
|
|
1335
|
-
|
|
1336
|
-
this.
|
|
1337
|
-
this.
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
childData.forEach((record) => {
|
|
1341
|
-
if (this.parent.enableVirtualization) {
|
|
1342
|
-
if (record.hasChildRecords && record.childRecords.length > 0) {
|
|
1343
|
-
this.updateParentSelection(record);
|
|
1344
|
-
}
|
|
1345
|
-
else {
|
|
1346
|
-
this.updateSelectedItems(record, record.checkboxState);
|
|
1347
|
-
}
|
|
1348
|
-
let child = findChildrenRecords(record);
|
|
1349
|
-
child = this.getFilteredChildRecords(child);
|
|
1350
|
-
for (let i = 0; i < child.length; i++) {
|
|
1351
|
-
if (child[parseInt(i.toString(), 10)].hasChildRecords) {
|
|
1352
|
-
this.updateParentSelection(child[parseInt(i.toString(), 10)]);
|
|
1353
|
-
}
|
|
1354
|
-
else if (!(child[parseInt(i.toString(), 10)].hasChildRecords) &&
|
|
1355
|
-
!isNullOrUndefined(child[parseInt(i.toString(), 10)])) {
|
|
1356
|
-
this.updateSelectedItems(child[parseInt(i.toString(), 10)], child[parseInt(i.toString(), 10)].checkboxState);
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
else {
|
|
1361
|
-
if (record.hasChildRecords) {
|
|
1362
|
-
this.updateParentSelection(record);
|
|
1363
|
-
}
|
|
1364
|
-
else {
|
|
1365
|
-
this.updateSelectedItems(record, record.checkboxState);
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
});
|
|
1369
|
-
this.headerSelection();
|
|
1819
|
+
else if (requestType === 'filtering' || requestType === 'searching' || requestType === 'refresh') {
|
|
1820
|
+
this.updateSelectedCollectionsAfterBulk(this.resolveHeaderSelectionList(), requestType);
|
|
1821
|
+
this.refreshVisibleCheckboxes();
|
|
1822
|
+
if (this.parent.autoCheckHierarchy) {
|
|
1823
|
+
this.updateHeaderCheckboxState();
|
|
1824
|
+
}
|
|
1370
1825
|
}
|
|
1371
1826
|
}
|
|
1372
1827
|
else {
|
|
1373
|
-
if ((requestType === 'filtering' || requestType === 'searching' || requestType === 'refresh'
|
|
1374
|
-
|
|
1828
|
+
if ((requestType === 'filtering' || requestType === 'searching' || requestType === 'refresh' ||
|
|
1829
|
+
requestType === 'sorting' || requestType === 'paging' || requestType === 'expanding' ||
|
|
1830
|
+
requestType === 'expand' || requestType === 'collapsing' || requestType === 'collapse') && !isRemoteData(this.parent)) {
|
|
1375
1831
|
this.selectedItems = [];
|
|
1832
|
+
this.selectedUidMap = new Map();
|
|
1376
1833
|
this.selectedIndexes = [];
|
|
1834
|
+
this.refreshVisibleCheckboxes();
|
|
1835
|
+
if (this.parent.autoCheckHierarchy) {
|
|
1836
|
+
this.updateHeaderCheckboxState();
|
|
1837
|
+
}
|
|
1377
1838
|
}
|
|
1378
1839
|
}
|
|
1379
1840
|
}
|
|
1380
1841
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1842
|
+
/**
|
|
1843
|
+
* Retrieves checked record objects.
|
|
1844
|
+
* This array maintains the `ITreeData` objects in the order they were selected.
|
|
1845
|
+
*
|
|
1846
|
+
* @returns {ITreeData[]} Array of checked records.
|
|
1847
|
+
*/
|
|
1848
|
+
getCheckedrecords() { return this.selectedItems; }
|
|
1849
|
+
/**
|
|
1850
|
+
* Retrieves visible indexes of checked rows in the current view, in the order they were selected.
|
|
1851
|
+
* This method dynamically generates the list of visible indexes by iterating through `selectedItems`
|
|
1852
|
+
* (which preserves selection order) and finding their *current* visible index.
|
|
1853
|
+
*
|
|
1854
|
+
* @returns {number[]} Array of checked row indexes in selection order.
|
|
1855
|
+
*/
|
|
1384
1856
|
getCheckedRowIndexes() {
|
|
1385
|
-
|
|
1857
|
+
this.buildVisibleUidMap();
|
|
1858
|
+
const orderedVisibleIndexes = [];
|
|
1859
|
+
for (const selectedItem of this.selectedItems) {
|
|
1860
|
+
const uid = selectedItem.uniqueID;
|
|
1861
|
+
if (uid !== undefined && this.visibleUidIndex[uid] !== undefined) {
|
|
1862
|
+
orderedVisibleIndexes.push(this.visibleUidIndex[uid]);
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
return orderedVisibleIndexes;
|
|
1386
1866
|
}
|
|
1387
1867
|
}
|
|
1388
1868
|
|
|
@@ -1944,6 +2424,7 @@ class DataManipulation {
|
|
|
1944
2424
|
*/
|
|
1945
2425
|
destroy() {
|
|
1946
2426
|
this.removeEventListener();
|
|
2427
|
+
this.hierarchyData = null;
|
|
1947
2428
|
}
|
|
1948
2429
|
/**
|
|
1949
2430
|
* @hidden
|
|
@@ -2544,7 +3025,7 @@ class DataManipulation {
|
|
|
2544
3025
|
this.parent.parentData.push(currentData);
|
|
2545
3026
|
}
|
|
2546
3027
|
currentData.uniqueID = getUid(this.parent.element.id + '_data_');
|
|
2547
|
-
|
|
3028
|
+
this.parent.uniqueIDCollection[currentData.uniqueID] = currentData;
|
|
2548
3029
|
if (!isNullOrUndefined(parentRecords)) {
|
|
2549
3030
|
const parentData = extend$1({}, parentRecords);
|
|
2550
3031
|
delete parentData.childRecords;
|
|
@@ -3534,7 +4015,9 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3534
4015
|
constructor(options, element) {
|
|
3535
4016
|
super(options, element);
|
|
3536
4017
|
this.dataResults = {};
|
|
4018
|
+
/** @hidden */
|
|
3537
4019
|
this.uniqueIDCollection = {};
|
|
4020
|
+
/** @hidden */
|
|
3538
4021
|
this.uniqueIDFilterCollection = {};
|
|
3539
4022
|
this.changedRecords = 'changedRecords';
|
|
3540
4023
|
this.deletedRecords = 'deletedRecords';
|
|
@@ -3544,6 +4027,8 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3544
4027
|
this.modifiedRecords = [];
|
|
3545
4028
|
this.stackedHeader = false;
|
|
3546
4029
|
this.freezeColumnRefresh = true;
|
|
4030
|
+
this.componentRefresh = Component.prototype.refresh;
|
|
4031
|
+
this.isComponentRefresh = false;
|
|
3547
4032
|
this.objectEqualityChecker = (old, current) => {
|
|
3548
4033
|
if (old) {
|
|
3549
4034
|
const keys = Object.keys(old);
|
|
@@ -3592,7 +4077,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3592
4077
|
/* eslint-disable */
|
|
3593
4078
|
excelExport(excelExportProperties, isMultipleExport, workbook, isBlob) {
|
|
3594
4079
|
/* eslint-enable */
|
|
3595
|
-
return this.excelExportModule.Map(excelExportProperties, isMultipleExport, workbook, isBlob, false);
|
|
4080
|
+
return this.allowExcelExport ? this.excelExportModule.Map(excelExportProperties, isMultipleExport, workbook, isBlob, false) : null;
|
|
3596
4081
|
}
|
|
3597
4082
|
/**
|
|
3598
4083
|
* Exports the TreeGrid data to a CSV file.
|
|
@@ -3606,7 +4091,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3606
4091
|
/* eslint-disable */
|
|
3607
4092
|
csvExport(excelExportProperties, isMultipleExport, workbook, isBlob) {
|
|
3608
4093
|
/* eslint-enable */
|
|
3609
|
-
return this.excelExportModule.Map(excelExportProperties, isMultipleExport, workbook, isBlob, true);
|
|
4094
|
+
return this.allowExcelExport ? this.excelExportModule.Map(excelExportProperties, isMultipleExport, workbook, isBlob, true) : null;
|
|
3610
4095
|
}
|
|
3611
4096
|
/**
|
|
3612
4097
|
* Exports the TreeGrid data to a PDF document.
|
|
@@ -3618,7 +4103,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3618
4103
|
* @returns {Promise<any>} - Returns a promise that resolves with the result of the export action.
|
|
3619
4104
|
*/
|
|
3620
4105
|
pdfExport(pdfExportProperties, isMultipleExport, pdfDoc, isBlob) {
|
|
3621
|
-
return this.pdfExportModule.Map(pdfExportProperties, isMultipleExport, pdfDoc, isBlob);
|
|
4106
|
+
return this.allowPdfExport ? this.pdfExportModule.Map(pdfExportProperties, isMultipleExport, pdfDoc, isBlob) : null;
|
|
3622
4107
|
}
|
|
3623
4108
|
/**
|
|
3624
4109
|
* Sends a POST request to export the TreeGrid to an Excel file on the server side.
|
|
@@ -3738,6 +4223,26 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3738
4223
|
getModuleName() {
|
|
3739
4224
|
return 'treegrid';
|
|
3740
4225
|
}
|
|
4226
|
+
/**
|
|
4227
|
+
* Initiates a complete refresh of the TreeGrid's column and layout.
|
|
4228
|
+
*
|
|
4229
|
+
* This method forces a full re-render of the TreeGrid, ensuring that any dynamic
|
|
4230
|
+
* changes to columns or layout are immediately reflected.
|
|
4231
|
+
*
|
|
4232
|
+
* @returns {void}
|
|
4233
|
+
*/
|
|
4234
|
+
refreshLayout() {
|
|
4235
|
+
this.componentRefresh();
|
|
4236
|
+
}
|
|
4237
|
+
/**
|
|
4238
|
+
* @param {Object} prop - Defines the property
|
|
4239
|
+
* @param {boolean} muteOnChange - Defines the mute on change
|
|
4240
|
+
* @returns {void}
|
|
4241
|
+
* @private
|
|
4242
|
+
*/
|
|
4243
|
+
setProperties(prop, muteOnChange) {
|
|
4244
|
+
super.setProperties(prop, muteOnChange);
|
|
4245
|
+
}
|
|
3741
4246
|
/**
|
|
3742
4247
|
* For internal use only - Initialize the event handler;
|
|
3743
4248
|
*
|
|
@@ -3745,6 +4250,9 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3745
4250
|
* @returns {void}
|
|
3746
4251
|
*/
|
|
3747
4252
|
preRender() {
|
|
4253
|
+
if (this.isComponentRefresh) {
|
|
4254
|
+
this.grid = new Grid();
|
|
4255
|
+
}
|
|
3748
4256
|
this.TreeGridLocale();
|
|
3749
4257
|
this.initProperties();
|
|
3750
4258
|
this.defaultLocale = {
|
|
@@ -3914,7 +4422,10 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3914
4422
|
}
|
|
3915
4423
|
}
|
|
3916
4424
|
else {
|
|
3917
|
-
this.
|
|
4425
|
+
const contentTableBody = this.grid.getContent().querySelector('.e-table tbody');
|
|
4426
|
+
if (parentTarget && contentTableBody && parentTarget !== contentTableBody.lastElementChild) {
|
|
4427
|
+
this.clearSelection();
|
|
4428
|
+
}
|
|
3918
4429
|
}
|
|
3919
4430
|
}
|
|
3920
4431
|
}
|
|
@@ -3985,6 +4496,8 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
3985
4496
|
this.isExpandAll = false;
|
|
3986
4497
|
this.isCollapseAll = false;
|
|
3987
4498
|
this.freezeColumnRefresh = true;
|
|
4499
|
+
this.componentRefresh = Component.prototype.refresh;
|
|
4500
|
+
this.isComponentRefresh = false;
|
|
3988
4501
|
this.keyConfigs = {
|
|
3989
4502
|
ctrlDownArrow: 'ctrl+downarrow',
|
|
3990
4503
|
ctrlUpArrow: 'ctrl+uparrow',
|
|
@@ -4337,7 +4850,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
4337
4850
|
if (RecordsCount === 0 && this.columns.length === 0) {
|
|
4338
4851
|
failureCases.push('Either of the Data source or columns should be given.');
|
|
4339
4852
|
}
|
|
4340
|
-
if (this.frozenColumns > 0 && this.columnModel.filter((col) => col.isFrozen)) {
|
|
4853
|
+
if (this.frozenColumns > 0 && this.columnModel.filter((col) => col.isFrozen).length > 0) {
|
|
4341
4854
|
failureCases.push('Use only one attribute for Frozen either IsFrozen or FrozenColumns.');
|
|
4342
4855
|
}
|
|
4343
4856
|
if (this.enableVirtualization && !isNullOrUndefined(this.detailTemplate)) {
|
|
@@ -4347,12 +4860,21 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
4347
4860
|
&& (!isNullOrUndefined(this.detailTemplate) || !isNullOrUndefined(this.rowTemplate))) {
|
|
4348
4861
|
failureCases.push('Frozen rows and columns are not supported with the Detail template and row template.');
|
|
4349
4862
|
}
|
|
4350
|
-
if ((this.frozenColumns > 0 || this.columnModel.filter((col) => col.isFrozen).length > 0 || this.frozenRows > 0) && this.editSettings.mode === 'Cell') {
|
|
4863
|
+
if ((this.frozenColumns > 0 || this.columnModel.filter((col) => col.isFrozen).length > 0 || this.frozenRows > 0) && this.editSettings.allowEditing && this.editSettings.mode === 'Cell') {
|
|
4351
4864
|
failureCases.push('Frozen rows and columns are not supported with cell editing.');
|
|
4352
4865
|
}
|
|
4353
4866
|
if (this.allowSelection && !isNullOrUndefined(this.rowTemplate)) {
|
|
4354
4867
|
failureCases.push('Selection is not supported in RowTemplate');
|
|
4355
4868
|
}
|
|
4869
|
+
if (!this.allowExcelExport && this.action === 'csvExport') {
|
|
4870
|
+
failureCases.push('CSV export is not allowed when allowExcelExport is disabled.');
|
|
4871
|
+
}
|
|
4872
|
+
if (!this.allowPdfExport && this.action === 'pdfExport') {
|
|
4873
|
+
failureCases.push('PDF export is not allowed when allowPdfExport is disabled');
|
|
4874
|
+
}
|
|
4875
|
+
if (!this.allowExcelExport && this.action === 'excelExport') {
|
|
4876
|
+
failureCases.push('Excel export is not allowed when allowExcelExport is disabled.');
|
|
4877
|
+
}
|
|
4356
4878
|
if (this.treeColumnIndex >= this.columns.length) {
|
|
4357
4879
|
failureCases.push('TreeColumnIndex value should not exceed the total column count.');
|
|
4358
4880
|
}
|
|
@@ -4507,6 +5029,8 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
4507
5029
|
this.grid.frozenRows = this.frozenRows;
|
|
4508
5030
|
this.grid.frozenColumns = this.frozenColumns;
|
|
4509
5031
|
this.grid.clipMode = getActualProperties(this.clipMode);
|
|
5032
|
+
this.grid.enableColumnSpan = this.enableColumnSpan;
|
|
5033
|
+
this.grid.enableRowSpan = this.enableRowSpan;
|
|
4510
5034
|
const templateInstance = 'templateDotnetInstance';
|
|
4511
5035
|
this.grid[`${templateInstance}`] = this[`${templateInstance}`];
|
|
4512
5036
|
const isJsComponent = 'isJsComponent';
|
|
@@ -4981,12 +5505,12 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
4981
5505
|
this.grid.refresh();
|
|
4982
5506
|
}
|
|
4983
5507
|
if (args.action === 'filter') {
|
|
4984
|
-
if (!args.isCollapseMaintain && this.filterModule['currentFilterObject'] !== '' && this.enableVirtualization && !this.initialRender && !(isRemoteData(this) && this.enableVirtualization)) {
|
|
5508
|
+
if (!args.isCollapseMaintain && this.filterModule['currentFilterObject'] !== '' && this.enableVirtualization && !this.initialRender && !this.expandStateMapping && !(isRemoteData(this) && this.enableVirtualization)) {
|
|
4985
5509
|
this.expandAll();
|
|
4986
5510
|
}
|
|
4987
5511
|
}
|
|
4988
5512
|
if (args.requestType === 'searching') {
|
|
4989
|
-
if (!args.isCollapseMaintain && this.searchSettings.key !== '' && this.enableVirtualization && !this.initialRender && !(isRemoteData(this) && this.enableVirtualization)) {
|
|
5513
|
+
if (!args.isCollapseMaintain && this.searchSettings.key !== '' && this.enableVirtualization && !this.initialRender && !this.expandStateMapping && !(isRemoteData(this) && this.enableVirtualization)) {
|
|
4990
5514
|
this.expandAll();
|
|
4991
5515
|
}
|
|
4992
5516
|
}
|
|
@@ -5321,11 +5845,14 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
5321
5845
|
onPropertyChanged(newProp) {
|
|
5322
5846
|
const properties = Object.keys(newProp);
|
|
5323
5847
|
let requireRefresh = false;
|
|
5324
|
-
if (properties.indexOf('columns') > -1 && !isNullOrUndefined(newProp.columns)) {
|
|
5325
|
-
this.refreshColumns();
|
|
5326
|
-
}
|
|
5327
5848
|
for (const prop of properties) {
|
|
5328
5849
|
switch (prop) {
|
|
5850
|
+
case 'columns':
|
|
5851
|
+
if (!isNullOrUndefined(newProp.columns)) {
|
|
5852
|
+
this.refreshColumns();
|
|
5853
|
+
}
|
|
5854
|
+
requireRefresh = true;
|
|
5855
|
+
break;
|
|
5329
5856
|
case 'treeColumnIndex':
|
|
5330
5857
|
this.grid.refreshColumns();
|
|
5331
5858
|
break;
|
|
@@ -5536,8 +6063,19 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
5536
6063
|
}
|
|
5537
6064
|
this.grid.editSettings = this.getGridEditSettings();
|
|
5538
6065
|
break;
|
|
6066
|
+
case 'enableRowSpan':
|
|
6067
|
+
case 'enableColumnSpan':
|
|
6068
|
+
this.grid.enableRowSpan = this.enableRowSpan;
|
|
6069
|
+
this.grid.enableColumnSpan = this.enableColumnSpan;
|
|
6070
|
+
this.refreshColumns();
|
|
6071
|
+
break;
|
|
6072
|
+
}
|
|
6073
|
+
}
|
|
6074
|
+
if (requireRefresh) {
|
|
6075
|
+
if (this.isFrozenGrid()) {
|
|
6076
|
+
this.refreshLayout();
|
|
5539
6077
|
}
|
|
5540
|
-
|
|
6078
|
+
else {
|
|
5541
6079
|
this.grid.refresh();
|
|
5542
6080
|
}
|
|
5543
6081
|
}
|
|
@@ -5558,6 +6096,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
5558
6096
|
* @returns {void}
|
|
5559
6097
|
*/
|
|
5560
6098
|
destroy() {
|
|
6099
|
+
this.isComponentRefresh = true;
|
|
5561
6100
|
const treeGridElement = this.element;
|
|
5562
6101
|
if (!treeGridElement) {
|
|
5563
6102
|
return;
|
|
@@ -5568,15 +6107,20 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
5568
6107
|
this.unwireEvents();
|
|
5569
6108
|
}
|
|
5570
6109
|
this.removeListener();
|
|
5571
|
-
if (
|
|
5572
|
-
|
|
6110
|
+
if (this.dataModule) {
|
|
6111
|
+
this.dataModule.destroy();
|
|
5573
6112
|
}
|
|
5574
6113
|
if (this.grid) {
|
|
6114
|
+
this.grid.dataSource = null;
|
|
5575
6115
|
this.grid.destroy();
|
|
5576
6116
|
}
|
|
5577
|
-
if (
|
|
5578
|
-
|
|
6117
|
+
if (hasTreeGridChild) {
|
|
6118
|
+
super.destroy();
|
|
5579
6119
|
}
|
|
6120
|
+
this.infiniteScrollData = null;
|
|
6121
|
+
this.remoteCollapsedData = null;
|
|
6122
|
+
this.remoteExpandedData = null;
|
|
6123
|
+
this.parentData = null;
|
|
5580
6124
|
const modules = ['dataModule', 'sortModule', 'renderModule', 'filterModule', 'printModule', 'clipboardModule',
|
|
5581
6125
|
'excelExportModule', 'pdfExportModule', 'toolbarModule', 'summaryModule', 'reorderModule', 'resizeModule',
|
|
5582
6126
|
'pagerModule', 'keyboardModule', 'columnMenuModule', 'contextMenuModule', 'editModule', 'virtualScrollModule',
|
|
@@ -5586,6 +6130,9 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
5586
6130
|
this[modules[parseInt(i.toString(), 10)]] = null;
|
|
5587
6131
|
}
|
|
5588
6132
|
}
|
|
6133
|
+
this.dataResults = null;
|
|
6134
|
+
this.uniqueIDCollection = {};
|
|
6135
|
+
this.uniqueIDFilterCollection = {};
|
|
5589
6136
|
this.element.innerHTML = '';
|
|
5590
6137
|
this.grid = null;
|
|
5591
6138
|
}
|
|
@@ -5726,7 +6273,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
5726
6273
|
/**
|
|
5727
6274
|
* Adds a new record to the TreeGrid at the specified position or default location.
|
|
5728
6275
|
*
|
|
5729
|
-
* @param {Object} data - Object containing
|
|
6276
|
+
* @param {Object | Object[]} data - Object containing data for a single record, or an array of objects for creating multiple records. If omitted, an empty row is added.
|
|
5730
6277
|
* @param {number} index - The index at which the new row should be added.
|
|
5731
6278
|
* @param {RowPosition} position - Specifies the position of the new row (e.g., before, after or child).
|
|
5732
6279
|
*
|
|
@@ -6535,7 +7082,9 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
6535
7082
|
if (isNullOrUndefined(refreshUI) || refreshUI) {
|
|
6536
7083
|
this.grid.columns = this.getGridColumns(this.columns);
|
|
6537
7084
|
this.getTreeColumn();
|
|
6538
|
-
this.
|
|
7085
|
+
if (!this.isFrozenGrid()) {
|
|
7086
|
+
this.grid.refreshColumns();
|
|
7087
|
+
}
|
|
6539
7088
|
}
|
|
6540
7089
|
else {
|
|
6541
7090
|
this.grid.setProperties({ columns: this.getGridColumns(this.columns) }, true);
|
|
@@ -7067,7 +7616,8 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
7067
7616
|
if (rows.length) {
|
|
7068
7617
|
for (let i = 0; i < rows.length; i++) {
|
|
7069
7618
|
if (action === 'collapse') {
|
|
7070
|
-
|
|
7619
|
+
const currentRecordIndx = this.frozenRows ? this.getCurrentViewRecords()[parseInt(rows[parseInt(i.toString(), 10)].getAttribute('aria-rowindex'), 10) - 1] : this.getCurrentViewRecords()[rows[parseInt(i.toString(), 10)].rowIndex];
|
|
7620
|
+
if (!isNullOrUndefined(currentRecordIndx)) {
|
|
7071
7621
|
this.collapseRow(rows[parseInt(i.toString(), 10)]);
|
|
7072
7622
|
}
|
|
7073
7623
|
}
|
|
@@ -7191,8 +7741,9 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
7191
7741
|
}
|
|
7192
7742
|
const lastrowIdx = this.getVisibleRecords()[this.getVisibleRecords().length - 1]['index'];
|
|
7193
7743
|
const lastRow = this.getRowByIndex(lastrowIdx);
|
|
7194
|
-
|
|
7195
|
-
|
|
7744
|
+
const borderElement = lastRow ? lastRow.nextElementSibling ? lastRow.nextElementSibling.classList.contains('e-detailrow') ? lastRow.nextElementSibling : lastRow : lastRow : null;
|
|
7745
|
+
if (this.grid.getContentTable().clientHeight <= this.grid.getContent().clientHeight && !isNullOrUndefined(borderElement) && !borderElement.cells[0].classList.contains('e-lastrowcell')) {
|
|
7746
|
+
this.lastRowBorder(borderElement, true);
|
|
7196
7747
|
}
|
|
7197
7748
|
}
|
|
7198
7749
|
if (isCountRequired(this) && action === 'expand') {
|
|
@@ -7353,12 +7904,16 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
7353
7904
|
}
|
|
7354
7905
|
localExpand(action, row, record) {
|
|
7355
7906
|
let rows;
|
|
7907
|
+
const detailRow = row.nextElementSibling ? row.nextElementSibling.classList.contains('e-detailrow') ? row.nextElementSibling : null : null;
|
|
7356
7908
|
const childRecords = this.grid.currentViewData.filter((e) => {
|
|
7357
7909
|
return e.parentUniqueID === record.uniqueID;
|
|
7358
7910
|
});
|
|
7359
7911
|
if (this.isPixelHeight() && row.cells[0].classList.contains('e-lastrowcell')) {
|
|
7360
7912
|
this.lastRowBorder(row, false);
|
|
7361
7913
|
}
|
|
7914
|
+
else if (this.isPixelHeight() && detailRow && detailRow.cells[0].classList.contains('e-lastrowcell')) {
|
|
7915
|
+
this.lastRowBorder(row.nextElementSibling, false);
|
|
7916
|
+
}
|
|
7362
7917
|
let movableRows;
|
|
7363
7918
|
let freezeRightRows;
|
|
7364
7919
|
let gridRows = this.getRows();
|
|
@@ -7561,6 +8116,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
7561
8116
|
this.on('updateResults', this.updateResultModel, this);
|
|
7562
8117
|
this.grid.on('initial-end', this.afterGridRender, this);
|
|
7563
8118
|
this.grid.on('partial-filter-update', this.partialFilterUpdate, this);
|
|
8119
|
+
this.grid.on('get-row-cells', this.getCellsByTableName, this);
|
|
7564
8120
|
}
|
|
7565
8121
|
updateResultModel(returnResult) {
|
|
7566
8122
|
this.dataResults = returnResult;
|
|
@@ -7577,6 +8133,16 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
7577
8133
|
this.grid.off('initial-end', this.afterGridRender);
|
|
7578
8134
|
this.grid.off('last-rowcell-border-updated', this.lastRowCellBorderUpdated);
|
|
7579
8135
|
this.grid.off('partial-filter-update', this.partialFilterUpdate);
|
|
8136
|
+
this.grid.off('get-row-cells', this.getCellsByTableName);
|
|
8137
|
+
}
|
|
8138
|
+
getCellsByTableName(args) {
|
|
8139
|
+
if (!Array.isArray(args.elements)) {
|
|
8140
|
+
args.elements = [];
|
|
8141
|
+
}
|
|
8142
|
+
if (args.rowIndex < this.grid.getDataRows().length) {
|
|
8143
|
+
const cells = [].slice.call(this.grid.getDataRows()[parseInt(args.rowIndex.toString(), 10)].getElementsByClassName('e-rowcell'));
|
|
8144
|
+
Array.prototype.push.apply(args.elements, cells);
|
|
8145
|
+
}
|
|
7580
8146
|
}
|
|
7581
8147
|
partialFilterUpdate(args) {
|
|
7582
8148
|
const gridFiltered = args.gridFiltered;
|
|
@@ -8001,6 +8567,53 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
|
|
|
8001
8567
|
this.rowDragAndDropModule[this.indentOutdentAction](record, 'outdent');
|
|
8002
8568
|
}
|
|
8003
8569
|
}
|
|
8570
|
+
/**
|
|
8571
|
+
* Calculates and returns the optimal page size that fits the current height of the TreeGrid's container.
|
|
8572
|
+
*
|
|
8573
|
+
* @param {number | string } containerHeight - (Optional) The height of the container - i.e. the complete TreeGrid height, which can be a number (in pixels) or a string.
|
|
8574
|
+
* @returns {number} returns the page size
|
|
8575
|
+
*/
|
|
8576
|
+
getPageSizeByHeight(containerHeight) {
|
|
8577
|
+
if (isNullOrUndefined(containerHeight)) {
|
|
8578
|
+
const treegridControlElement = document.getElementById(this.element.id);
|
|
8579
|
+
if (treegridControlElement) {
|
|
8580
|
+
containerHeight = treegridControlElement.clientHeight;
|
|
8581
|
+
}
|
|
8582
|
+
else {
|
|
8583
|
+
const root = this.element;
|
|
8584
|
+
containerHeight = root ? (root.offsetHeight || root.clientHeight || 0) : 0;
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
if ((this.allowTextWrap && this.textWrapSettings.wrapMode === 'Header') || (!this.allowTextWrap)) {
|
|
8588
|
+
let pagesize = 0;
|
|
8589
|
+
if (typeof containerHeight === 'string' && containerHeight.indexOf('%') !== -1) {
|
|
8590
|
+
containerHeight = parseInt(containerHeight, 10) / 100 * this.element.clientHeight;
|
|
8591
|
+
}
|
|
8592
|
+
const nonContentHeight = this.grid['getNoncontentHeight']() + this.grid.getRowHeight();
|
|
8593
|
+
if (containerHeight > nonContentHeight) {
|
|
8594
|
+
let contentHeight = 0;
|
|
8595
|
+
let calcNonContentHeight = this.grid['getNoncontentHeight']();
|
|
8596
|
+
const pagerMsg = document.getElementsByClassName('e-pagerexternalmsg')[0];
|
|
8597
|
+
if (pagerMsg) {
|
|
8598
|
+
calcNonContentHeight += pagerMsg.clientHeight;
|
|
8599
|
+
}
|
|
8600
|
+
contentHeight = containerHeight - calcNonContentHeight;
|
|
8601
|
+
pagesize = (contentHeight / this.grid.getRowHeight());
|
|
8602
|
+
}
|
|
8603
|
+
if (this.frozenRows > 0) {
|
|
8604
|
+
pagesize = pagesize + this.frozenRows;
|
|
8605
|
+
}
|
|
8606
|
+
if (pagesize > 0) {
|
|
8607
|
+
return Math.floor(pagesize);
|
|
8608
|
+
}
|
|
8609
|
+
else {
|
|
8610
|
+
return 0;
|
|
8611
|
+
}
|
|
8612
|
+
}
|
|
8613
|
+
else {
|
|
8614
|
+
return 0;
|
|
8615
|
+
}
|
|
8616
|
+
}
|
|
8004
8617
|
};
|
|
8005
8618
|
__decorate$c([
|
|
8006
8619
|
Property(0)
|
|
@@ -8215,6 +8828,12 @@ __decorate$c([
|
|
|
8215
8828
|
__decorate$c([
|
|
8216
8829
|
Property(false)
|
|
8217
8830
|
], TreeGrid.prototype, "allowPdfExport", void 0);
|
|
8831
|
+
__decorate$c([
|
|
8832
|
+
Property(false)
|
|
8833
|
+
], TreeGrid.prototype, "enableColumnSpan", void 0);
|
|
8834
|
+
__decorate$c([
|
|
8835
|
+
Property(false)
|
|
8836
|
+
], TreeGrid.prototype, "enableRowSpan", void 0);
|
|
8218
8837
|
__decorate$c([
|
|
8219
8838
|
Event()
|
|
8220
8839
|
], TreeGrid.prototype, "created", void 0);
|
|
@@ -8716,6 +9335,9 @@ class RowDD {
|
|
|
8716
9335
|
this.selectedItem = isNullOrUndefined(record) ?
|
|
8717
9336
|
tObj.getCurrentViewRecords()[parseInt(selectedItemIndex.toString(), 10)] : record;
|
|
8718
9337
|
const primaryKeyField = this.parent.getPrimaryKeyFieldNames()[0];
|
|
9338
|
+
if (!primaryKeyField) {
|
|
9339
|
+
return;
|
|
9340
|
+
}
|
|
8719
9341
|
const rowIndex = this.parent.grid.getRowIndexByPrimaryKey(this.selectedItem[`${primaryKeyField}`]);
|
|
8720
9342
|
this.selectedRow = this.parent[this.selectedRows] = selectedItemIndex !== -1 ?
|
|
8721
9343
|
this.parent.getSelectedRows()[0]
|
|
@@ -11653,7 +12275,7 @@ class Aggregate {
|
|
|
11653
12275
|
const value = types[parseInt(i.toString(), 10)] !== 'Custom' ? val[`${key}`] : val;
|
|
11654
12276
|
single[`${disp}`] = single[`${disp}`] || {};
|
|
11655
12277
|
single[`${disp}`][`${key}`] = value;
|
|
11656
|
-
single[`${disp}`][types[parseInt(i.toString(), 10)]] = !isNullOrUndefined(val) ? formatFn(value) : ' ';
|
|
12278
|
+
single[`${disp}`][types[parseInt(i.toString(), 10)]] = (!isNullOrUndefined(val) && !isNullOrUndefined(value)) ? formatFn(value) : ' ';
|
|
11657
12279
|
}
|
|
11658
12280
|
helper.format = summaryColumn.getFormatter();
|
|
11659
12281
|
const cellElement = createElement('td', {
|
|
@@ -11877,6 +12499,7 @@ class ContextMenu {
|
|
|
11877
12499
|
addEventListener() {
|
|
11878
12500
|
this.parent.on('contextMenuOpen', this.contextMenuOpen, this);
|
|
11879
12501
|
this.parent.on('contextMenuClick', this.contextMenuClick, this);
|
|
12502
|
+
this.parent.on('contextMenuItemClick', this.contextMenuItemClick, this);
|
|
11880
12503
|
}
|
|
11881
12504
|
/**
|
|
11882
12505
|
* @hidden
|
|
@@ -11888,6 +12511,21 @@ class ContextMenu {
|
|
|
11888
12511
|
}
|
|
11889
12512
|
this.parent.off('contextMenuOpen', this.contextMenuOpen);
|
|
11890
12513
|
this.parent.off('contextMenuClick', this.contextMenuClick);
|
|
12514
|
+
this.parent.off('contextMenuItemClick', this.contextMenuItemClick);
|
|
12515
|
+
}
|
|
12516
|
+
contextMenuItemClick(args) {
|
|
12517
|
+
const id = args.item && args.item.id ? args.item.id : '';
|
|
12518
|
+
const delId = this.parent.element.id + '_gridcontrol_cmenu_Delete';
|
|
12519
|
+
if (id !== delId) {
|
|
12520
|
+
return;
|
|
12521
|
+
}
|
|
12522
|
+
if (this.parent.getSelectedRecords()[0].hasChildRecords || this.parent.getSelectedRecords().length > 1) {
|
|
12523
|
+
this.parent.deleteRecord();
|
|
12524
|
+
}
|
|
12525
|
+
else {
|
|
12526
|
+
this.parent.deleteRow(this.parent.getSelectedRows()[0]);
|
|
12527
|
+
}
|
|
12528
|
+
args.cancel = true;
|
|
11891
12529
|
}
|
|
11892
12530
|
contextMenuOpen(args) {
|
|
11893
12531
|
const addRow = select('#' + this.parent.element.id + '_gridcontrol_cmenu_AddRow', args.element);
|
|
@@ -12269,13 +12907,22 @@ class BatchEdit {
|
|
|
12269
12907
|
focusModule.getContent().matrix.matrix = this.matrix;
|
|
12270
12908
|
}
|
|
12271
12909
|
else {
|
|
12272
|
-
|
|
12910
|
+
if (this.parent.frozenRows) {
|
|
12911
|
+
actualIndex = this.batchIndex;
|
|
12912
|
+
}
|
|
12913
|
+
else if (this.parent.editModule.isAddedMultipleRowsByMethod) {
|
|
12914
|
+
actualIndex = e.index;
|
|
12915
|
+
}
|
|
12916
|
+
else {
|
|
12917
|
+
actualIndex = table.getElementsByClassName('e-batchrow')[0].rowIndex;
|
|
12918
|
+
}
|
|
12273
12919
|
// if (this.parent.frozenRows || this.parent.frozenColumns) {
|
|
12274
12920
|
// actualIndex = this.batchIndex;
|
|
12275
12921
|
// }
|
|
12276
12922
|
}
|
|
12277
12923
|
focusModule.getContent().matrix.current = [actualIndex, focusModule.getContent().matrix.current[1]];
|
|
12278
|
-
if (this.parent.editModule['isAddedRowByMethod'] && !isNullOrUndefined(this.parent.editModule['addRowIndex']) &&
|
|
12924
|
+
if (this.parent.editModule['isAddedRowByMethod'] && !isNullOrUndefined(this.parent.editModule['addRowIndex']) &&
|
|
12925
|
+
!this.parent.editModule['isAddedRowByContextMenu'] && !this.parent.editModule.isAddedMultipleRowsByMethod) {
|
|
12279
12926
|
const newlyAddedRecords = this.parent.getBatchChanges()['addedRecords'];
|
|
12280
12927
|
const index = parseInt(this.parent.getContentTable().getElementsByClassName('e-insertedrow')[newlyAddedRecords.length - 1].getAttribute('aria-rowindex'), 10) - 1;
|
|
12281
12928
|
this.batchRecords.splice(index, 0, newlyAddedRecords[newlyAddedRecords.length - 1]);
|
|
@@ -12515,7 +13162,12 @@ class BatchEdit {
|
|
|
12515
13162
|
this.parent.editModule['previousNewRowPosition'] = rowPosition;
|
|
12516
13163
|
}
|
|
12517
13164
|
addRecords[parseInt(i.toString(), 10)].taskData = taskData;
|
|
12518
|
-
|
|
13165
|
+
if (this.batchAddRowRecord.length > 1) {
|
|
13166
|
+
addRowRecord = this.batchAddRowRecord[parseInt(i.toString(), 10)];
|
|
13167
|
+
}
|
|
13168
|
+
else {
|
|
13169
|
+
addRowRecord = this.batchAddRowRecord[0];
|
|
13170
|
+
}
|
|
12519
13171
|
if (isNullOrUndefined(addRowRecord)) {
|
|
12520
13172
|
addRowRecord = this.batchAddRowRecord[i - 1];
|
|
12521
13173
|
}
|
|
@@ -12530,6 +13182,10 @@ class BatchEdit {
|
|
|
12530
13182
|
if (isNullOrUndefined(addRecords[parseInt(i.toString(), 10)].index)) {
|
|
12531
13183
|
addRowIndex = 0;
|
|
12532
13184
|
}
|
|
13185
|
+
if (this.parent.editModule.isAddedMultipleRowsByMethod && this.isSelfReference && (this.parent.editSettings.newRowPosition === 'Above' || this.parent.editSettings.newRowPosition === 'Below')) {
|
|
13186
|
+
addRowIndex = args.index;
|
|
13187
|
+
addRowRecord = this.parent.flatData[args.index];
|
|
13188
|
+
}
|
|
12533
13189
|
if (this.parent.editSettings.newRowPosition !== 'Top' && this.parent.editSettings.newRowPosition !== 'Bottom') {
|
|
12534
13190
|
if (isNullOrUndefined(addRecords[parseInt(i.toString(), 10)].parentItem) && this.selectedIndex === -1) {
|
|
12535
13191
|
selectedIndex = -1;
|
|
@@ -12656,6 +13312,7 @@ class Edit {
|
|
|
12656
13312
|
this.isAddedRowByMethod = false;
|
|
12657
13313
|
this.isAddedRowByContextMenu = false;
|
|
12658
13314
|
this.isIndexUndefined = false;
|
|
13315
|
+
this.isAddedMultipleRowsByMethod = false;
|
|
12659
13316
|
Grid.Inject(Edit$1);
|
|
12660
13317
|
this.parent = parent;
|
|
12661
13318
|
this.isSelfReference = !isNullOrUndefined(parent.parentIdMapping);
|
|
@@ -13312,7 +13969,8 @@ class Edit {
|
|
|
13312
13969
|
}
|
|
13313
13970
|
}
|
|
13314
13971
|
}
|
|
13315
|
-
if (this.parent.editSettings.mode === 'Batch' && !isNullOrUndefined(this.addRowIndex) && this.addRowIndex !== -1 &&
|
|
13972
|
+
if (this.parent.editSettings.mode === 'Batch' && !isNullOrUndefined(this.addRowIndex) && this.addRowIndex !== -1 &&
|
|
13973
|
+
!this.isAddedMultipleRowsByMethod && this['isAddedRowByMethod'] && !this.isAddedRowByContextMenu) {
|
|
13316
13974
|
index = this.batchEditModule.getAddRowIndex();
|
|
13317
13975
|
this.selectedIndex = this.batchEditModule.getSelectedIndex();
|
|
13318
13976
|
const batchAddedRecords = this.parent.getBatchChanges()['addedRecords'];
|
|
@@ -13334,6 +13992,28 @@ class Edit {
|
|
|
13334
13992
|
this.batchEditModule['batchAddRowRecord'].push(this.batchEditModule['addRowRecord']);
|
|
13335
13993
|
this.batchEditModule['batchAddedRecords'].push(args['data']);
|
|
13336
13994
|
}
|
|
13995
|
+
else if (this.parent.editSettings.mode === 'Batch' && this.isAddedMultipleRowsByMethod && (this.parent.editSettings.newRowPosition === 'Above' || this.parent.editSettings.newRowPosition === 'Below')) {
|
|
13996
|
+
index = this.multipleRowIndex;
|
|
13997
|
+
this.selectedIndex = this.multipleRowIndex;
|
|
13998
|
+
const batchAddedRecords = this.updatedRecords.addedRecords;
|
|
13999
|
+
let newlyAddedRecord;
|
|
14000
|
+
if (batchAddedRecords.length) {
|
|
14001
|
+
for (let i = 0; i < batchAddedRecords.length; i++) {
|
|
14002
|
+
if (isNullOrUndefined(batchAddedRecords[parseInt(i.toString(), 10)].uniqueID)) {
|
|
14003
|
+
newlyAddedRecord = batchAddedRecords[parseInt(i.toString(), 10)];
|
|
14004
|
+
}
|
|
14005
|
+
const args = {
|
|
14006
|
+
action: 'add',
|
|
14007
|
+
data: newlyAddedRecord,
|
|
14008
|
+
index: index,
|
|
14009
|
+
seletedRow: 0
|
|
14010
|
+
};
|
|
14011
|
+
this.beginAddEdit(args);
|
|
14012
|
+
this.batchEditModule['batchAddRowRecord'].push(this.batchEditModule['addRowRecord']);
|
|
14013
|
+
this.batchEditModule['batchAddedRecords'].push(args['data']);
|
|
14014
|
+
}
|
|
14015
|
+
}
|
|
14016
|
+
}
|
|
13337
14017
|
}
|
|
13338
14018
|
// private beforeDataBound(args: BeforeDataBoundArgs): void {
|
|
13339
14019
|
// if (this.parent.grid.isEdit && this.parent.dataSource instanceof DataManager &&
|
|
@@ -13618,7 +14298,35 @@ class Edit {
|
|
|
13618
14298
|
if (isNullOrUndefined(index)) {
|
|
13619
14299
|
this.isIndexUndefined = true;
|
|
13620
14300
|
}
|
|
13621
|
-
if (!
|
|
14301
|
+
if (!isNullOrUndefined(data) && Array.isArray(data)) {
|
|
14302
|
+
let addRecords = [];
|
|
14303
|
+
const previousEditMode = this.parent.editSettings.mode;
|
|
14304
|
+
const previousGridEditMode = this.parent.grid.editSettings.mode;
|
|
14305
|
+
if (!this.isSelfReference && !isNullOrUndefined(data) && Object.hasOwnProperty.call(data, this.parent.childMapping)) {
|
|
14306
|
+
addRecords.push(data);
|
|
14307
|
+
}
|
|
14308
|
+
else if (Array.isArray(data)) {
|
|
14309
|
+
addRecords = data;
|
|
14310
|
+
}
|
|
14311
|
+
this.parent.setProperties({ editSettings: { mode: 'Batch' } }, true);
|
|
14312
|
+
this.parent.grid.setProperties({ editSettings: { mode: 'Batch' } }, true);
|
|
14313
|
+
if (!isNullOrUndefined(position)) {
|
|
14314
|
+
this.parent.setProperties({ editSettings: { newRowPosition: position } }, true);
|
|
14315
|
+
}
|
|
14316
|
+
this.updatedRecords = { addedRecords: addRecords, changedRecords: [], deletedRecords: [] };
|
|
14317
|
+
if ((position === 'Above' || position === 'Below') && this.isSelfReference) {
|
|
14318
|
+
this.isAddedMultipleRowsByMethod = true;
|
|
14319
|
+
this.multipleRowIndex = index;
|
|
14320
|
+
this.addRowIndex = index;
|
|
14321
|
+
this.parent.notify(batchAdd, { updatedRecords: this.updatedRecords, index: index });
|
|
14322
|
+
}
|
|
14323
|
+
const updatedRecords = this.updatedRecords;
|
|
14324
|
+
this.parent.notify(batchSave, { updatedRecords, index });
|
|
14325
|
+
this.parent.setProperties({ editSettings: { mode: previousEditMode } }, true);
|
|
14326
|
+
this.parent.grid.setProperties({ editSettings: { mode: previousGridEditMode } }, true);
|
|
14327
|
+
this.parent.refresh();
|
|
14328
|
+
}
|
|
14329
|
+
else if (!this.isSelfReference && !isNullOrUndefined(data) && Object.hasOwnProperty.call(data, this.parent.childMapping)) {
|
|
13622
14330
|
const addRecords = [];
|
|
13623
14331
|
const previousEditMode = this.parent.editSettings.mode;
|
|
13624
14332
|
const previousGridEditMode = this.parent.grid.editSettings.mode;
|
|
@@ -13628,7 +14336,8 @@ class Edit {
|
|
|
13628
14336
|
if (!isNullOrUndefined(position)) {
|
|
13629
14337
|
this.parent.setProperties({ editSettings: { newRowPosition: position } }, true);
|
|
13630
14338
|
}
|
|
13631
|
-
|
|
14339
|
+
this.updatedRecords = { addedRecords: addRecords, changedRecords: [], deletedRecords: [] };
|
|
14340
|
+
const updatedRecords = this.updatedRecords;
|
|
13632
14341
|
this.parent.notify(batchSave, { updatedRecords, index });
|
|
13633
14342
|
this.parent.setProperties({ editSettings: { mode: previousEditMode } }, true);
|
|
13634
14343
|
this.parent.grid.setProperties({ editSettings: { mode: previousGridEditMode } }, true);
|
|
@@ -13916,7 +14625,8 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
|
|
|
13916
14625
|
*/
|
|
13917
14626
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13918
14627
|
getRowCollection(index, isMovable, isRowObject, isFrozenRight) {
|
|
13919
|
-
const
|
|
14628
|
+
const rows = this.parent.getRows();
|
|
14629
|
+
const startIdx = rows.length > 0 ? parseInt(rows[0].getAttribute(ariaRowIndex), 10) - 1 : 0;
|
|
13920
14630
|
const rowCollection = this.parent.getDataRows();
|
|
13921
14631
|
const collection = isRowObject ? this.parent.getCurrentViewRecords() : rowCollection;
|
|
13922
14632
|
let selectedRow = collection[index - startIdx];
|
|
@@ -14108,6 +14818,9 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
|
|
|
14108
14818
|
super.renderTable();
|
|
14109
14819
|
if (!(this.parent.dataSource instanceof DataManager && this.parent.dataSource.dataSource.url !== undefined
|
|
14110
14820
|
&& this.parent.dataSource.dataSource.offline && this.parent.dataSource.dataSource.url !== '') || !isCountRequired(this.parent)) {
|
|
14821
|
+
if (this.observers) {
|
|
14822
|
+
this.observers.disconnect();
|
|
14823
|
+
}
|
|
14111
14824
|
getValue('observer', this).options.debounceEvent = false;
|
|
14112
14825
|
this.observers = new TreeInterSectionObserver(getValue('observer', this).element, getValue('observer', this).options);
|
|
14113
14826
|
this.contents = this.getPanel().firstChild;
|
|
@@ -14822,6 +15535,9 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
|
|
|
14822
15535
|
this.parent.off('refresh-virtual-editform-cells', this.refreshCell);
|
|
14823
15536
|
this.parent.off('virtaul-cell-focus', this.cellFocus);
|
|
14824
15537
|
this.parent.off('virtual-scroll-edit', this.restoreEditState);
|
|
15538
|
+
if (this.observers) {
|
|
15539
|
+
this.observers.disconnect();
|
|
15540
|
+
}
|
|
14825
15541
|
}
|
|
14826
15542
|
}
|
|
14827
15543
|
class TreeInterSectionObserver extends InterSectionObserver {
|
|
@@ -14844,12 +15560,28 @@ class TreeInterSectionObserver extends InterSectionObserver {
|
|
|
14844
15560
|
observes(callback, onEnterCallback, instance) {
|
|
14845
15561
|
const containerRect = 'containerRect';
|
|
14846
15562
|
super[`${containerRect}`] = getValue('options', this).container.getBoundingClientRect();
|
|
14847
|
-
|
|
15563
|
+
this.containerEl = getValue('options', this).container;
|
|
15564
|
+
this.containerScrollHandler = this.virtualScrollHandlers(callback, onEnterCallback, instance);
|
|
15565
|
+
EventHandler.add(this.containerEl, 'scroll', this.containerScrollHandler, this);
|
|
14848
15566
|
if (getValue('options', this).movableContainer) {
|
|
14849
15567
|
const movableContainerRect = 'movableContainerRect';
|
|
14850
15568
|
super[`${movableContainerRect}`] = getValue('options', this).movableContainer.getBoundingClientRect();
|
|
14851
|
-
|
|
15569
|
+
this.movableContainerEl = getValue('options', this).movableContainer;
|
|
15570
|
+
this.movableScrollHandler = this.virtualScrollHandlers(callback, onEnterCallback, instance);
|
|
15571
|
+
EventHandler.add(this.movableContainerEl, 'scroll', this.movableScrollHandler, this);
|
|
15572
|
+
}
|
|
15573
|
+
}
|
|
15574
|
+
disconnect() {
|
|
15575
|
+
if (this.containerEl && this.containerScrollHandler) {
|
|
15576
|
+
EventHandler.remove(this.containerEl, 'scroll', this.containerScrollHandler);
|
|
15577
|
+
this.containerScrollHandler = null;
|
|
15578
|
+
}
|
|
15579
|
+
if (this.movableContainerEl && this.movableScrollHandler) {
|
|
15580
|
+
EventHandler.remove(this.movableContainerEl, 'scroll', this.movableScrollHandler);
|
|
15581
|
+
this.movableScrollHandler = null;
|
|
14852
15582
|
}
|
|
15583
|
+
this.containerEl = null;
|
|
15584
|
+
this.movableContainerEl = null;
|
|
14853
15585
|
}
|
|
14854
15586
|
/**
|
|
14855
15587
|
* Clears the last known position.
|
|
@@ -15057,9 +15789,12 @@ class VirtualScroll {
|
|
|
15057
15789
|
const dm = new DataManager(pageingDetails.result);
|
|
15058
15790
|
const expanded = new Predicate$1('expanded', 'notequal', null).or('expanded', 'notequal', undefined);
|
|
15059
15791
|
const parents = dm.executeLocal(new Query().where(expanded));
|
|
15060
|
-
const
|
|
15061
|
-
|
|
15062
|
-
|
|
15792
|
+
const isFiltering = pageingDetails.actionArgs.requestType === 'filtering';
|
|
15793
|
+
const isFlatHierarchy = this.parent.filterSettings.hierarchyMode === 'Child' ||
|
|
15794
|
+
this.parent.filterSettings.hierarchyMode === 'None';
|
|
15795
|
+
const visualData = isFiltering && isFlatHierarchy
|
|
15796
|
+
? parents
|
|
15797
|
+
: parents.filter((e) => getExpandStatus(this.parent, e));
|
|
15063
15798
|
this.visualData = visualData;
|
|
15064
15799
|
pageingDetails.count = visualData.length;
|
|
15065
15800
|
this.parent.grid.notify(dataListener, { data: visualData });
|
|
@@ -15290,7 +16025,7 @@ class Freeze {
|
|
|
15290
16025
|
}
|
|
15291
16026
|
const queryselector = args.action === 'e-childrow-hidden' ? '.e-treecolumn-container .e-treegridcollapse'
|
|
15292
16027
|
: '.e-treecolumn-container .e-treegridexpand';
|
|
15293
|
-
if (frozenrows[row.
|
|
16028
|
+
if (frozenrows[parseInt(row.getAttribute('aria-rowindex'), 10) - 1].querySelector(queryselector)) {
|
|
15294
16029
|
const cRow = [];
|
|
15295
16030
|
for (let i = 0; i < movableRows.length; i++) {
|
|
15296
16031
|
if (movableRows[parseInt(i.toString(), 10)].querySelector('.e-gridrowindex' + rData.index + 'level' + (rData.level + 1))) {
|