@syncfusion/ej2-treegrid 31.1.17 → 31.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/ej2-treegrid.min.js +2 -2
  2. package/dist/ej2-treegrid.umd.min.js +2 -2
  3. package/dist/ej2-treegrid.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-treegrid.es2015.js +13 -4
  5. package/dist/es6/ej2-treegrid.es2015.js.map +1 -1
  6. package/dist/es6/ej2-treegrid.es5.js +13 -4
  7. package/dist/es6/ej2-treegrid.es5.js.map +1 -1
  8. package/dist/global/ej2-treegrid.min.js +2 -2
  9. package/dist/global/ej2-treegrid.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/package.json +14 -50
  12. package/src/treegrid/actions/edit.js +1 -1
  13. package/src/treegrid/actions/rowdragdrop.js +12 -3
  14. package/styles/bootstrap4-lite.css +8 -0
  15. package/styles/bootstrap4.css +8 -0
  16. package/styles/treegrid/bootstrap4.css +8 -0
  17. package/dist/ts/index.d.ts +0 -4
  18. package/dist/ts/index.ts +0 -4
  19. package/dist/ts/treegrid/actions/batch-edit.d.ts +0 -74
  20. package/dist/ts/treegrid/actions/batch-edit.ts +0 -627
  21. package/dist/ts/treegrid/actions/clipboard.d.ts +0 -36
  22. package/dist/ts/treegrid/actions/clipboard.ts +0 -174
  23. package/dist/ts/treegrid/actions/column-chooser.d.ts +0 -37
  24. package/dist/ts/treegrid/actions/column-chooser.ts +0 -55
  25. package/dist/ts/treegrid/actions/column-menu.d.ts +0 -24
  26. package/dist/ts/treegrid/actions/column-menu.ts +0 -39
  27. package/dist/ts/treegrid/actions/command-column.d.ts +0 -24
  28. package/dist/ts/treegrid/actions/command-column.ts +0 -32
  29. package/dist/ts/treegrid/actions/context-menu.d.ts +0 -42
  30. package/dist/ts/treegrid/actions/context-menu.ts +0 -149
  31. package/dist/ts/treegrid/actions/crud-actions.d.ts +0 -66
  32. package/dist/ts/treegrid/actions/crud-actions.ts +0 -388
  33. package/dist/ts/treegrid/actions/detail-row.d.ts +0 -39
  34. package/dist/ts/treegrid/actions/detail-row.ts +0 -124
  35. package/dist/ts/treegrid/actions/edit.d.ts +0 -121
  36. package/dist/ts/treegrid/actions/edit.ts +0 -1083
  37. package/dist/ts/treegrid/actions/excel-export.d.ts +0 -67
  38. package/dist/ts/treegrid/actions/excel-export.ts +0 -240
  39. package/dist/ts/treegrid/actions/filter.d.ts +0 -57
  40. package/dist/ts/treegrid/actions/filter.ts +0 -231
  41. package/dist/ts/treegrid/actions/freeze-column.d.ts +0 -28
  42. package/dist/ts/treegrid/actions/freeze-column.ts +0 -119
  43. package/dist/ts/treegrid/actions/index.d.ts +0 -24
  44. package/dist/ts/treegrid/actions/index.ts +0 -24
  45. package/dist/ts/treegrid/actions/infinite-scroll.d.ts +0 -96
  46. package/dist/ts/treegrid/actions/infinite-scroll.ts +0 -320
  47. package/dist/ts/treegrid/actions/logger.d.ts +0 -25
  48. package/dist/ts/treegrid/actions/logger.ts +0 -136
  49. package/dist/ts/treegrid/actions/page.d.ts +0 -67
  50. package/dist/ts/treegrid/actions/page.ts +0 -212
  51. package/dist/ts/treegrid/actions/pdf-export.d.ts +0 -63
  52. package/dist/ts/treegrid/actions/pdf-export.ts +0 -182
  53. package/dist/ts/treegrid/actions/print.d.ts +0 -37
  54. package/dist/ts/treegrid/actions/print.ts +0 -69
  55. package/dist/ts/treegrid/actions/reorder.d.ts +0 -36
  56. package/dist/ts/treegrid/actions/reorder.ts +0 -60
  57. package/dist/ts/treegrid/actions/resize.d.ts +0 -36
  58. package/dist/ts/treegrid/actions/resize.ts +0 -54
  59. package/dist/ts/treegrid/actions/rowdragdrop.d.ts +0 -405
  60. package/dist/ts/treegrid/actions/rowdragdrop.ts +0 -1896
  61. package/dist/ts/treegrid/actions/selection.d.ts +0 -51
  62. package/dist/ts/treegrid/actions/selection.ts +0 -530
  63. package/dist/ts/treegrid/actions/sort.d.ts +0 -63
  64. package/dist/ts/treegrid/actions/sort.ts +0 -149
  65. package/dist/ts/treegrid/actions/summary.d.ts +0 -47
  66. package/dist/ts/treegrid/actions/summary.ts +0 -231
  67. package/dist/ts/treegrid/actions/toolbar.d.ts +0 -52
  68. package/dist/ts/treegrid/actions/toolbar.ts +0 -154
  69. package/dist/ts/treegrid/actions/virtual-scroll.d.ts +0 -90
  70. package/dist/ts/treegrid/actions/virtual-scroll.ts +0 -306
  71. package/dist/ts/treegrid/base/constant.d.ts +0 -158
  72. package/dist/ts/treegrid/base/constant.ts +0 -158
  73. package/dist/ts/treegrid/base/data.d.ts +0 -90
  74. package/dist/ts/treegrid/base/data.ts +0 -904
  75. package/dist/ts/treegrid/base/index.d.ts +0 -11
  76. package/dist/ts/treegrid/base/index.ts +0 -11
  77. package/dist/ts/treegrid/base/interface.d.ts +0 -186
  78. package/dist/ts/treegrid/base/interface.ts +0 -191
  79. package/dist/ts/treegrid/base/treegrid-model.d.ts +0 -1100
  80. package/dist/ts/treegrid/base/treegrid.d.ts +0 -2422
  81. package/dist/ts/treegrid/base/treegrid.ts +0 -5962
  82. package/dist/ts/treegrid/enum.d.ts +0 -152
  83. package/dist/ts/treegrid/enum.ts +0 -217
  84. package/dist/ts/treegrid/index.d.ts +0 -9
  85. package/dist/ts/treegrid/index.ts +0 -9
  86. package/dist/ts/treegrid/models/column-chooser-settings-model.d.ts +0 -62
  87. package/dist/ts/treegrid/models/column-chooser-settings.d.ts +0 -53
  88. package/dist/ts/treegrid/models/column-chooser-settings.ts +0 -67
  89. package/dist/ts/treegrid/models/column-model.d.ts +0 -30
  90. package/dist/ts/treegrid/models/column.d.ts +0 -697
  91. package/dist/ts/treegrid/models/column.ts +0 -800
  92. package/dist/ts/treegrid/models/edit-settings-model.d.ts +0 -100
  93. package/dist/ts/treegrid/models/edit-settings.d.ts +0 -89
  94. package/dist/ts/treegrid/models/edit-settings.ts +0 -111
  95. package/dist/ts/treegrid/models/filter-settings-model.d.ts +0 -216
  96. package/dist/ts/treegrid/models/filter-settings.d.ts +0 -195
  97. package/dist/ts/treegrid/models/filter-settings.ts +0 -237
  98. package/dist/ts/treegrid/models/index.d.ts +0 -24
  99. package/dist/ts/treegrid/models/index.ts +0 -24
  100. package/dist/ts/treegrid/models/infinite-scroll-settings-model.d.ts +0 -29
  101. package/dist/ts/treegrid/models/infinite-scroll-settings.d.ts +0 -25
  102. package/dist/ts/treegrid/models/infinite-scroll-settings.ts +0 -31
  103. package/dist/ts/treegrid/models/loading-indicator-model.d.ts +0 -21
  104. package/dist/ts/treegrid/models/loading-indicator.d.ts +0 -19
  105. package/dist/ts/treegrid/models/loading-indicator.ts +0 -21
  106. package/dist/ts/treegrid/models/page-settings-model.d.ts +0 -66
  107. package/dist/ts/treegrid/models/page-settings.d.ts +0 -57
  108. package/dist/ts/treegrid/models/page-settings.ts +0 -73
  109. package/dist/ts/treegrid/models/rowdrop-settings-model.d.ts +0 -15
  110. package/dist/ts/treegrid/models/rowdrop-settings.d.ts +0 -34
  111. package/dist/ts/treegrid/models/rowdrop-settings.ts +0 -37
  112. package/dist/ts/treegrid/models/search-settings-model.d.ts +0 -79
  113. package/dist/ts/treegrid/models/search-settings.d.ts +0 -73
  114. package/dist/ts/treegrid/models/search-settings.ts +0 -83
  115. package/dist/ts/treegrid/models/selection-settings-model.d.ts +0 -76
  116. package/dist/ts/treegrid/models/selection-settings.d.ts +0 -68
  117. package/dist/ts/treegrid/models/selection-settings.ts +0 -82
  118. package/dist/ts/treegrid/models/sort-settings-model.d.ts +0 -49
  119. package/dist/ts/treegrid/models/sort-settings.d.ts +0 -43
  120. package/dist/ts/treegrid/models/sort-settings.ts +0 -51
  121. package/dist/ts/treegrid/models/summary-model.d.ts +0 -93
  122. package/dist/ts/treegrid/models/summary.d.ts +0 -126
  123. package/dist/ts/treegrid/models/summary.ts +0 -170
  124. package/dist/ts/treegrid/models/textwrap-settings-model.d.ts +0 -21
  125. package/dist/ts/treegrid/models/textwrap-settings.d.ts +0 -19
  126. package/dist/ts/treegrid/models/textwrap-settings.ts +0 -21
  127. package/dist/ts/treegrid/renderer/index.d.ts +0 -5
  128. package/dist/ts/treegrid/renderer/index.ts +0 -5
  129. package/dist/ts/treegrid/renderer/render.d.ts +0 -41
  130. package/dist/ts/treegrid/renderer/render.ts +0 -379
  131. package/dist/ts/treegrid/renderer/virtual-row-model-generator.d.ts +0 -16
  132. package/dist/ts/treegrid/renderer/virtual-row-model-generator.ts +0 -90
  133. package/dist/ts/treegrid/renderer/virtual-tree-content-render.d.ts +0 -353
  134. package/dist/ts/treegrid/renderer/virtual-tree-content-render.ts +0 -1125
  135. package/dist/ts/treegrid/utils.d.ts +0 -70
  136. package/dist/ts/treegrid/utils.ts +0 -217
@@ -1,1896 +0,0 @@
1
- import { TreeGrid } from '../base/treegrid';
2
- import { Grid, RowDD as GridDragDrop, RowDropEventArgs, parentsUntil, Row, Column } from '@syncfusion/ej2-grids';
3
- import { EJ2Intance, getObject, Scroll } from '@syncfusion/ej2-grids';
4
- import { closest, isNullOrUndefined, setValue, extend, getValue, removeClass, addClass, setStyleAttribute } from '@syncfusion/ej2-base';
5
- import { ITreeData } from '../base';
6
- import { DataManager } from '@syncfusion/ej2-data';
7
- import * as events from '../base/constant';
8
- import { editAction } from './crud-actions';
9
- import { getParentData, findChildrenRecords, isRemoteData, isOffline, isCountRequired } from '../utils';
10
- import { TreeActionEventArgs } from '../models';
11
- import { RowDragEventArgs } from '../base';
12
-
13
- /**
14
- * TreeGrid RowDragAndDrop module
15
- *
16
- * @hidden
17
- */
18
- export class RowDD {
19
- private parent: TreeGrid;
20
- /** @hidden
21
- * Represents the position where a row can be dropped within the TreeGrid.
22
- */
23
- private dropPosition: string;
24
- /** @hidden
25
- * Represents the record that is currently being dragged in the TreeGrid.
26
- */
27
- private draggedRecord: ITreeData;
28
- /** @hidden
29
- * Represents the record that the currently dragged item is being dropped onto in the TreeGrid.
30
- */
31
- private droppedRecord: ITreeData;
32
- /** @hidden
33
- * Stores the data representation of the TreeGrid, including hierarchical structures.
34
- */
35
- public treeGridData: ITreeData[];
36
- /** @hidden
37
- * Represents the underlying hierarchical data of the TreeGrid.
38
- */
39
- private treeData: ITreeData[];
40
- /** @hidden
41
- * Indicates whether a row can be dropped into the current target position during a drag-and-drop operation.
42
- */
43
- private canDrop: boolean = true;
44
- /** @hidden
45
- * Indicates whether the current drag operation includes child records of the dragged item.
46
- */
47
- private isDraggedWithChild: boolean = false;
48
- /** @hidden
49
- *
50
- */
51
- public isMultipleGrid: string;
52
- /** @hidden
53
- * Indicates whether multiple TreeGrid instances are being managed or displayed.
54
- */
55
- private modifiedRecords: string = 'modifiedRecords';
56
- /** @hidden
57
- * Represents the currently selected item in the TreeGrid.
58
- */
59
- private selectedItem: ITreeData;
60
- /** @hidden
61
- * Represents the currently selected item in the TreeGrid.
62
- */
63
- private selectedRecords: string = 'selectedRecords';
64
- /** @hidden
65
- * Holds an array of currently selected records in the TreeGrid.
66
- */
67
- private selectedRows: string = 'selectedRows';
68
- /** @hidden
69
- * Indicates whether there is a droppable item in the TreeGrid.
70
- */
71
- private hasDropItem: boolean = true;
72
- /** @hidden
73
- * Indicates whether the item is being added to the bottom of the TreeGrid.
74
- */
75
- public isaddtoBottom: boolean = false;
76
- private selectedRecord: ITreeData;
77
- private selectedRow: HTMLTableRowElement;
78
-
79
- /**
80
- * Constructor for render module
81
- *
82
- * @param {TreeGrid} parent - Tree Grid instance
83
- */
84
- constructor(parent?: TreeGrid) {
85
- Grid.Inject(GridDragDrop);
86
- this.parent = parent;
87
- this.addEventListener();
88
- }
89
-
90
- /**
91
- * Retrieves child records for a specified parent ID in the TreeGrid.
92
- *
93
- * @param {string} id - The unique ID of the parent record for which to retrieve child records.
94
- * @returns {ITreeData[]} An array of child records corresponding to the specified parent ID.
95
- */
96
- private getChildrecordsByParentID(id: string): ITreeData[] {
97
- let treeGridDataSource: Object;
98
- if (this.parent.dataSource instanceof DataManager && isOffline(this.parent)) {
99
- treeGridDataSource = (<DataManager>this.parent.grid.dataSource).dataSource.json;
100
- } else {
101
- treeGridDataSource = this.parent.grid.dataSource;
102
- }
103
- const record: Object[] = (treeGridDataSource as ITreeData[]).filter((e: ITreeData) => {
104
- return e.uniqueID === id;
105
- });
106
- return record;
107
- }
108
-
109
- /**
110
- * @hidden
111
- * @returns {void}
112
- */
113
- private addEventListener(): void {
114
- this.parent.on(events.rowdraging, this.Rowdraging, this);
115
- this.parent.on(events.rowDropped, this.rowDropped, this);
116
- this.parent.on(events.rowsAdd, this.rowsAdded, this);
117
- this.parent.on(events.rowsRemove, this.rowsRemoved, this);
118
- }
119
-
120
- /**
121
- * Reorder the rows based on given indexes and position
122
- *
123
- * @returns {void}
124
- * @param {number[]} fromIndexes - source indexes of rows to be re-ordered
125
- * @param {number} toIndex - Destination row index
126
- * @param {string} position - Drop position as above or below or child
127
- */
128
- public reorderRows(fromIndexes: number[], toIndex: number, position: string): void {
129
- const tObj: TreeGrid = this.parent;
130
- if (fromIndexes[0] === toIndex || ['above', 'below', 'child'].indexOf(position) === -1) {
131
- return;
132
- }
133
- const action: string = 'action'; const dropPosition: string = 'dropPosition';
134
- if (fromIndexes[0] !== toIndex && ['above', 'below', 'child'].indexOf(position) !== -1) {
135
- if (position === 'above') {
136
- this.dropPosition = 'topSegment';
137
- }
138
- if (position === 'below') {
139
- this.dropPosition = 'bottomSegment';
140
- }
141
- if (position === 'child') {
142
- this.dropPosition = 'middleSegment';
143
- }
144
- this.parent[`${dropPosition}`] = this.dropPosition;
145
- const data: ITreeData[] = [];
146
- for (let i: number = 0; i < fromIndexes.length; i++) {
147
- const index: number = (this.parent.getRowByIndex(fromIndexes[parseInt(i.toString(), 10)]) as HTMLTableRowElement).rowIndex;
148
- data[parseInt(i.toString(), 10)] = this.parent.getCurrentViewRecords()[parseInt(index.toString(), 10)];
149
- }
150
- const isByMethod: boolean = true;
151
- const args: RowDropEventArgs = {
152
- data: data,
153
- dropIndex: toIndex
154
- };
155
- if (!isCountRequired(this.parent)) {
156
- this.dropRows(args, isByMethod);
157
- }
158
- //this.refreshGridDataSource();
159
- if (tObj.isLocalData) {
160
- tObj.flatData = this.orderToIndex(tObj.flatData);
161
- }
162
- if (this.parent[`${action}`] === 'outdenting') {
163
- if (!isNullOrUndefined(data[0].parentItem)) {
164
- data[0].level = data[0].parentItem.level + 1;
165
- }
166
- }
167
- this.parent.grid.refresh();
168
- if (this.parent.enableImmutableMode && this.dropPosition === 'middleSegment') {
169
- const index: number = this.parent.allowRowDragAndDrop
170
- ? this.parent.treeColumnIndex + 1
171
- : (this.parent[`${action}`] === 'indenting' ? this.parent.treeColumnIndex : undefined);
172
- const row: HTMLTableRowElement = this.parent.getRows()[fromIndexes[0]];
173
- const dropData: Object = args.data[0];
174
- const totalRecord: Object[] = []; const rows: HTMLTableRowElement[] = [];
175
- totalRecord.push(dropData); rows.push(row);
176
- const parentUniqueID: string = 'parentUniqueID';
177
- const parentData: Object = getParentData(this.parent, args.data[0][`${parentUniqueID}`]);
178
- const parentrow: HTMLTableRowElement = this.parent.getRows()[parseInt(toIndex.toString(), 10)];
179
- totalRecord.push(parentData); rows.push(parentrow);
180
- this.updateRowAndCellElements(totalRecord, rows, index);
181
- }
182
- if (this.parent.enableImmutableMode && this.parent[`${action}`] === 'outdenting') {
183
- const index: number = this.parent.allowRowDragAndDrop
184
- ? this.parent.treeColumnIndex + 1
185
- : (this.parent[`${action}`] === 'outdenting' ? this.parent.treeColumnIndex : undefined);
186
- const record: Object = args.data[0];
187
- const row: HTMLTableRowElement = this.parent.getRows()[fromIndexes[0]];
188
- const totalRecord: Object[] = []; const rows: HTMLTableRowElement[] = [];
189
- totalRecord.push(record); rows.push(row);
190
- this.updateRowAndCellElements(totalRecord, rows, index);
191
- }
192
- }
193
- }
194
-
195
- /**
196
- * Updates the rows and cells
197
- *
198
- * @param {Object[]} records - Updates the given records
199
- * @param {HTMLTableRowElement[]} rows - Updates the given rows
200
- * @param {number} index - Updates the given cell index
201
- * @returns {void}
202
- */
203
- private updateRowAndCellElements(records: Object[], rows: HTMLTableRowElement[], index: number): void {
204
- for (let i: number = 0; i < records.length; i++) {
205
- this.parent.renderModule.cellRender({
206
- data: records[parseInt(i.toString(), 10)], cell: rows[parseInt(i.toString(), 10)].cells[parseInt(index.toString(), 10)] ,
207
- column: this.parent.grid.getColumns()[this.parent.treeColumnIndex],
208
- requestType: 'rowDragAndDrop'
209
- });
210
- if (this.parent['action'] === 'indenting' || this.parent['action'] === 'outdenting') {
211
- this.parent.renderModule.RowModifier({
212
- data: records[parseInt(i.toString(), 10)], row: rows[parseInt(i.toString(), 10)]
213
- });
214
- }
215
- }
216
- }
217
-
218
- /**
219
- * Performs indent or outdent actions on selected records in the TreeGrid.
220
- *
221
- * @param {ITreeData} [record] - The record to be indented or outdented. If undefined, the method operates on the currently selected record.
222
- * @param {string} [request] - The action to perform, either 'indent' or 'outdent'.
223
- * @returns {void}
224
- */
225
- private indentOutdentAction(record?: ITreeData, request?: string): void {
226
- const tObj: TreeGrid = this.parent; const action: string = 'action';
227
- const droppedIndex: string = 'dropIndex'; let selectedItemIndex: number = -1;
228
- if (isNullOrUndefined(record) && this.parent.selectedRowIndex === -1) {
229
- return;
230
- } else {
231
- if (this.parent.enableVirtualization && this.parent.selectedRowIndex !== -1) {
232
- selectedItemIndex = (this.parent.getSelectedRows()[0] as HTMLTableRowElement).rowIndex;
233
- } else if (this.parent.selectedRowIndex !== -1) {
234
- selectedItemIndex = this.parent.selectedRowIndex;
235
- }
236
- this.selectedItem = isNullOrUndefined(record) ?
237
- tObj.getCurrentViewRecords()[parseInt(selectedItemIndex.toString(), 10)] as ITreeData : record as ITreeData;
238
- const primaryKeyField: string = this.parent.getPrimaryKeyFieldNames()[0];
239
- const rowIndex: number = this.parent.grid.getRowIndexByPrimaryKey(this.selectedItem[`${primaryKeyField}`]);
240
- this.selectedRow = this.parent[this.selectedRows] = selectedItemIndex !== -1 ?
241
- this.parent.getSelectedRows()[0] as HTMLTableRowElement
242
- : this.parent.grid.getRowByIndex(rowIndex) as HTMLTableRowElement;
243
- this.selectedRecord = this.parent[this.selectedRecords] = selectedItemIndex !== -1 ?
244
- tObj.getCurrentViewRecords()[parseInt(selectedItemIndex.toString(), 10)] as ITreeData
245
- : this.selectedItem as ITreeData;
246
- if (request === 'indent') {
247
- const record: ITreeData = tObj.getCurrentViewRecords()[this.selectedRow.rowIndex - 1];
248
- let dropIndex: number;
249
- if (this.selectedRow.rowIndex === 0 || this.selectedRow.rowIndex === -1 ||
250
- (tObj.getCurrentViewRecords()[this.selectedRow.rowIndex] as ITreeData).level - record.level === 1) {
251
- return;
252
- }
253
- if (record.level > this.selectedRecord.level) {
254
- for (let i: number = 0; i < tObj.getCurrentViewRecords().length; i++) {
255
- if ((tObj.getCurrentViewRecords()[parseInt(i.toString(), 10)] as ITreeData).taskData ===
256
- record.parentItem.taskData) {
257
- dropIndex = i;
258
- if (tObj.enableVirtualization) {
259
- dropIndex = parseInt(tObj.getRows()[parseInt(i.toString(), 10)].getAttribute('aria-rowindex'), 10) - 1;
260
- }
261
- }
262
- }
263
- }
264
- else {
265
- dropIndex = this.selectedRow.rowIndex - 1;
266
- }
267
- if (this.parent.enableVirtualization && this.selectedRecord && !(record.level > this.selectedRecord.level)) {
268
- dropIndex = parseInt(this.selectedRow.getAttribute('aria-rowindex'), 10) - 2;
269
- }
270
- tObj[`${action}`] = 'indenting'; tObj[`${droppedIndex}`] = dropIndex;
271
- this.eventTrigger('indenting', dropIndex);
272
- } else if (request === 'outdent') {
273
- const isInvalidSelection: boolean = this.selectedRow.rowIndex === -1 || this.selectedRow.rowIndex === 0;
274
- const isRootLevel: boolean = (tObj.getCurrentViewRecords()[this.selectedRow.rowIndex] as ITreeData).level === 0;
275
- if (isInvalidSelection || isRootLevel) {
276
- return;
277
- }
278
- const parentItem: ITreeData = this.selectedRecord.parentItem;
279
- const records: object[] = tObj.getCurrentViewRecords();
280
- let dropIndex: number = records.findIndex((record: ITreeData) => record.uniqueID === parentItem.uniqueID);
281
- if (dropIndex === -1) {
282
- return;
283
- }
284
- if (this.parent.enableVirtualization && this.selectedRecord) {
285
- const ariaRowIndex: string = this.parent.getRows()[parseInt(dropIndex.toString(), 10)].getAttribute('aria-rowindex');
286
- dropIndex = parseInt(ariaRowIndex, 10) - 1;
287
- }
288
- tObj[`${action}`] = 'outdenting'; tObj[`${droppedIndex}`] = dropIndex;
289
- this.eventTrigger('outdenting', dropIndex);
290
- }
291
- }
292
- }
293
-
294
- /**
295
- * Triggers a specified event for the TreeGrid, notifying subscribers about the event occurrence.
296
- *
297
- * @param {string} action - The action to be triggered, either 'indenting' or 'outdenting'.
298
- * @param {number} dropIndex - The index at which the row should be dropped.
299
- * @returns {void}
300
- */
301
- private eventTrigger(action: string, dropIndex: number): void {
302
- const actionArgs: TreeActionEventArgs = {
303
- action: action,
304
- cancel: false,
305
- data: [this.parent[this.selectedRecords]],
306
- row: this.parent[this.selectedRows]
307
- };
308
- this.parent.trigger(events.actionBegin, actionArgs, (actionArgs: TreeActionEventArgs) => {
309
- if (!actionArgs.cancel) {
310
- if (actionArgs.action === 'indenting') {
311
- if (this.parent.enableVirtualization) {
312
- this.reorderRows([parseInt(this.selectedRow.getAttribute('aria-rowindex'), 10) - 1], dropIndex, 'child');
313
- }
314
- else {
315
- this.reorderRows([this.selectedRow.rowIndex], dropIndex, 'child');
316
- }
317
- } else if (actionArgs.action === 'outdenting') {
318
- if (this.parent.enableVirtualization) {
319
- this.reorderRows([parseInt(this.selectedRow.getAttribute('aria-rowindex'), 10) - 1], dropIndex, 'below');
320
- }
321
- else {
322
- this.reorderRows([this.selectedRow.rowIndex], dropIndex, 'below');
323
- }
324
- }
325
- }
326
- });
327
- }
328
-
329
- /**
330
- * Reorders the flat data array of the TreeGrid and updates the index of each record.
331
- *
332
- * @param {ITreeData[]} currentData - The array of tree data records to reorder.
333
- * @returns {ITreeData[]} The updated array of tree data records with indices set.
334
- */
335
- private orderToIndex(currentData: ITreeData[]): ITreeData[] {
336
- for (let i: number = 0; i < currentData.length; i++) {
337
- currentData[parseInt(i.toString(), 10)].index = i;
338
- if (!isNullOrUndefined(currentData[parseInt(i.toString(), 10)].parentItem)) {
339
- const updatedParent: ITreeData = getValue('uniqueIDCollection.' + currentData[parseInt(i.toString(), 10)].parentUniqueID, this.parent);
340
- currentData[parseInt(i.toString(), 10)].parentItem.index = updatedParent.index;
341
- }
342
- }
343
- return currentData;
344
- }
345
-
346
- /**
347
- * Handles the addition of new rows to the TreeGrid.
348
- *
349
- * @param {Object} e - The event object containing information about the rows being added.
350
- * @param {number} e.toIndex - The index at which the new rows should be added in the TreeGrid.
351
- * @param {Object[]} e.records - An array of the records to be added to the TreeGrid.
352
- *
353
- * @returns {void} This function does not return any value.
354
- */
355
- private rowsAdded(e: { toIndex: number, records: Object[] }): void {
356
- let draggedRecord: ITreeData;
357
- const dragRecords: ITreeData[] = e.records;
358
- for (let i: number = e.records.length - 1; i > -1; i--) {
359
- draggedRecord = dragRecords[parseInt(i.toString(), 10)];
360
- if (draggedRecord.parentUniqueID) {
361
- const record: ITreeData[] = dragRecords.filter((data: ITreeData) => {
362
- return data.uniqueID === draggedRecord.parentUniqueID;
363
- });
364
- if (record.length) {
365
- const index: number = record[0].childRecords.indexOf(draggedRecord);
366
- const parentRecord: ITreeData = record[0];
367
- if (index !== -1) {
368
- if (isNullOrUndefined(this.parent.idMapping)) {
369
- parentRecord.childRecords.splice(index, 1);
370
- if (!parentRecord.childRecords.length) {
371
- parentRecord.hasChildRecords = false;
372
- parentRecord.hasFilteredChildRecords = false;
373
- }
374
- }
375
- this.isDraggedWithChild = true;
376
- }
377
- }
378
- }
379
- }
380
- if (isNullOrUndefined(this.parent.dataSource as ITreeData[]) || !(this.parent.dataSource as ITreeData[]).length) {
381
- const tObj: TreeGrid = this.parent;
382
- let draggedRecord: ITreeData;
383
- const dragRecords: ITreeData[] = e.records;
384
- const dragLength: number = e.records.length;
385
- for (let i: number = dragLength - 1; i > -1; i--) {
386
- draggedRecord = dragRecords[parseInt(i.toString(), 10)];
387
- if (!i && draggedRecord.hasChildRecords) {
388
- draggedRecord.taskData[this.parent.parentIdMapping] = null;
389
- }
390
- const recordIndex1: number = 0;
391
- if (!isNullOrUndefined(tObj.parentIdMapping)) {
392
- tObj.childMapping = null;
393
- }
394
- if (!isNullOrUndefined(draggedRecord.taskData) && !isNullOrUndefined(tObj.childMapping) &&
395
- !Object.prototype.hasOwnProperty.call(draggedRecord.taskData, tObj.childMapping)) {
396
- draggedRecord.taskData[tObj.childMapping] = [];
397
- }
398
- if (!isNullOrUndefined(draggedRecord[tObj.childMapping])) {
399
- if (Object.prototype.hasOwnProperty.call(draggedRecord, tObj.childMapping) &&
400
- ((draggedRecord[tObj.childMapping]) as ITreeData[]).length && !this.isDraggedWithChild &&
401
- !isNullOrUndefined(tObj.parentIdMapping)) {
402
- const childData: ITreeData[] = (draggedRecord[tObj.childMapping]) as ITreeData[];
403
- for (let j: number = 0; j < childData.length; j++) {
404
- if (dragRecords.indexOf(childData[parseInt(j.toString(), 10)]) === -1) {
405
- dragRecords.splice(j, 0, childData[parseInt(j.toString(), 10)]);
406
- childData[parseInt(j.toString(), 10)].taskData = extend({}, childData[parseInt(j.toString(), 10)]);
407
- i += 1;
408
- }
409
- }
410
- }
411
- }
412
- if (Object.prototype.hasOwnProperty.call(draggedRecord, tObj.parentIdMapping)
413
- && draggedRecord[tObj.parentIdMapping] !== null
414
- && !this.isDraggedWithChild) {
415
- draggedRecord.taskData[tObj.parentIdMapping] = null;
416
- delete draggedRecord.parentItem;
417
- delete draggedRecord.parentUniqueID;
418
- }
419
- if (isNullOrUndefined(tObj.dataSource as ITreeData[])) {
420
- tObj.dataSource = [];
421
- }
422
- (tObj.dataSource as ITreeData[]).splice(recordIndex1, 0, draggedRecord.taskData);
423
- }
424
- tObj.setProperties({ dataSource: tObj.dataSource }, false);
425
- } else {
426
- for (let i: number = 0; i < dragRecords.length; i++) {
427
- setValue('uniqueIDCollection.' + dragRecords[parseInt(i.toString(), 10)].uniqueID, dragRecords[parseInt(i.toString(), 10)], this.parent);
428
- }
429
- const args: RowDropEventArgs = { data: e.records, dropIndex: e.toIndex };
430
- if (this.parent.dataSource instanceof DataManager) {
431
- this.treeGridData = this.parent.dataSource.dataSource.json;
432
- this.treeData = this.parent.dataSource.dataSource.json;
433
- } else {
434
- this.treeGridData = this.parent.grid.dataSource as ITreeData[];
435
- this.treeData = this.parent.dataSource as ITreeData[];
436
- }
437
- if (isNullOrUndefined(this.dropPosition)) {
438
- this.dropPosition = 'bottomSegment';
439
- args.dropIndex = this.parent.getCurrentViewRecords().length > 1 ? this.parent.getCurrentViewRecords().length - 1 :
440
- args.dropIndex;
441
- args.data = args.data.map((i: ITreeData) => {
442
- if (i.hasChildRecords && isNullOrUndefined(i.parentItem)) {
443
- i.level = 0;
444
- return i;
445
- }
446
- else {
447
- delete i.parentItem;
448
- delete i.parentUniqueID;
449
- i.level = 0;
450
- return i;
451
- }
452
- });
453
- }
454
- this.dropRows(args);
455
- }
456
- }
457
-
458
- /**
459
- * Handles the removal of specified rows from the TreeGrid.
460
- *
461
- * @param {Object} e - The event object containing information about the removed rows.
462
- * @param {number[]} e.indexes - An array of indexes of the rows that were removed.
463
- * @param {Object[]} e.records - An array of the records corresponding to the removed rows.
464
- *
465
- * @returns {void} This function does not return any value.
466
- */
467
- private rowsRemoved(e: { indexes: number[], records: Object[] }): void {
468
- for (let i: number = 0; i < e.records.length; i++) {
469
- this.draggedRecord = e.records[parseInt(i.toString(), 10)];
470
- if (this.draggedRecord.hasChildRecords || this.draggedRecord.parentItem &&
471
- (this.parent.grid.dataSource as ITreeData[]).
472
- indexOf(this.getChildrecordsByParentID(this.draggedRecord.parentUniqueID)[0]) !== -1 ||
473
- this.draggedRecord.level === 0) {
474
- this.deleteDragRow();
475
- }
476
- }
477
- }
478
-
479
- /**
480
- * Refreshes the data source of the TreeGrid.
481
- *
482
- * @returns {void} This function does not return any value.
483
- */
484
- private refreshGridDataSource(): void {
485
- const draggedRecord: ITreeData = this.draggedRecord;
486
- const droppedRecord: ITreeData = this.droppedRecord;
487
- const proxy: TreeGrid = this.parent;
488
- let temporaryDataSource: Object; let indexOfDroppedRecord: number;
489
- if (this.parent.dataSource instanceof DataManager && isOffline(this.parent)) {
490
- temporaryDataSource = (<DataManager>proxy.dataSource).dataSource.json;
491
- } else {
492
- temporaryDataSource = proxy.dataSource;
493
- }
494
- if (temporaryDataSource && (!isNullOrUndefined(droppedRecord) && !droppedRecord.parentItem)
495
- && !isNullOrUndefined(droppedRecord.taskData)) {
496
- const keys: string[] = Object.keys(temporaryDataSource);
497
- for (let i: number = 0; i < keys.length; i++) {
498
- if (temporaryDataSource[parseInt(i.toString(), 10)][this.parent.childMapping] ===
499
- droppedRecord.taskData[this.parent.childMapping]) {
500
- indexOfDroppedRecord = i;
501
- }
502
- }
503
- if (!this.parent.idMapping) {
504
- const positionAdjustment: number = this.dropPosition === 'topSegment' ? 0 : 1;
505
- if (this.dropPosition === 'topSegment' || this.dropPosition === 'bottomSegment') {
506
- (temporaryDataSource as ITreeData[]).splice(indexOfDroppedRecord + positionAdjustment, 0, draggedRecord.taskData);
507
- }
508
- }
509
- } else if (!this.parent.parentIdMapping && (!isNullOrUndefined(droppedRecord) && droppedRecord.parentItem)) {
510
- if (this.dropPosition === 'topSegment' || this.dropPosition === 'bottomSegment') {
511
- const record: ITreeData = (this.getChildrecordsByParentID(droppedRecord.parentUniqueID) as ITreeData)[0];
512
- const childRecords: ITreeData[] = record.childRecords;
513
- for (let i: number = 0; i < childRecords.length; i++) {
514
- droppedRecord.parentItem.taskData[this.parent.childMapping][parseInt(i.toString(), 10)]
515
- = childRecords[parseInt(i.toString(), 10)].taskData;
516
- }
517
- }
518
- }
519
-
520
- if (this.parent.parentIdMapping) {
521
- if (draggedRecord.parentItem) {
522
- if (this.dropPosition === 'topSegment' || this.dropPosition === 'bottomSegment') {
523
- draggedRecord[this.parent.parentIdMapping] = droppedRecord[this.parent.parentIdMapping];
524
- draggedRecord.taskData[this.parent.parentIdMapping] = droppedRecord[this.parent.parentIdMapping];
525
- } else {
526
- draggedRecord[this.parent.parentIdMapping] = droppedRecord[this.parent.idMapping];
527
- draggedRecord.taskData[this.parent.parentIdMapping] = droppedRecord[this.parent.idMapping];
528
- }
529
- } else {
530
- draggedRecord.taskData[this.parent.parentIdMapping] = null;
531
- draggedRecord[this.parent.parentIdMapping] = null;
532
- }
533
- }
534
- }
535
-
536
- /**
537
- * Removes the border from the first row of the TreeGrid.
538
- *
539
- * @param {HTMLTableRowElement} element - The table row element from which to remove the border.
540
- * @returns {void} This function does not return any value.
541
- */
542
- private removeFirstrowBorder(element: HTMLTableRowElement): void {
543
- const canremove: boolean = this.dropPosition === 'bottomSegment';
544
- if (this.parent.element.getElementsByClassName('e-firstrow-border').length > 0 && element &&
545
- ((element as HTMLTableRowElement).rowIndex !== 0 || canremove)) {
546
- this.parent.element.getElementsByClassName('e-firstrow-border')[0].remove();
547
- }
548
- }
549
-
550
- /**
551
- * Removes the border from the last row of the TreeGrid.
552
- *
553
- * @param {HTMLTableRowElement} element - The row element from which to remove the last row border.
554
- * @returns {void}
555
- */
556
- private removeLastrowBorder(element: HTMLTableRowElement): void {
557
- if (!element) { return; }
558
- const isEmptyRow: boolean = element.classList.contains('e-emptyrow') ||
559
- element.classList.contains('e-columnheader') ||
560
- element.classList.contains('e-detailrow');
561
- if (isEmptyRow) { return; }
562
- const lastRow: HTMLTableRowElement = this.parent.enableVirtualization ?
563
- this.parent.getRows()[this.parent.getCurrentViewRecords().length - 1] as HTMLTableRowElement :
564
- this.parent.getRowByIndex(this.parent.getCurrentViewRecords().length - 1) as HTMLTableRowElement;
565
- const isNotLastRow: boolean = lastRow.getAttribute('data-uid') !== element.getAttribute('data-uid');
566
- const canRemove: boolean = isNotLastRow || this.dropPosition === 'topSegment';
567
- const lastRowBorderElement: HTMLElement = this.parent.element.getElementsByClassName('e-lastrow-border')[0] as HTMLElement;
568
- if (lastRowBorderElement && canRemove) {
569
- lastRowBorderElement.remove();
570
- }
571
- }
572
-
573
- /**
574
- * Updates the icons associated with the specified rows in the TreeGrid.
575
- *
576
- * @param {Element[]} row - The array of row elements to update the icons for.
577
- * @param {number} index - The index of the row being updated.
578
- * @param {RowDragEventArgs} args - The event arguments associated with the row drag operation.
579
- * @returns {string} The drop position ('topSegment', 'middleSegment', 'bottomSegment', or 'Invalid').
580
- */
581
- private updateIcon(row: Element[], index: number, args: RowDragEventArgs): string {
582
- const rowEle: Element = args.target ? closest(args.target, 'tr') : null;
583
- this.dropPosition = undefined;
584
- let rowPositionHeight: number = 0;
585
- this.removeFirstrowBorder(rowEle as HTMLTableRowElement);
586
- this.removeLastrowBorder(rowEle as HTMLTableRowElement);
587
- for (let i: number = 0; i < args.rows.length; i++) {
588
- if (!isNullOrUndefined(rowEle) && rowEle.getAttribute('data-uid') === args.rows[parseInt(i.toString(), 10)].getAttribute('data-uid')
589
- || !parentsUntil(args.target, 'e-gridcontent')) {
590
- this.dropPosition = 'Invalid';
591
- this.addErrorElem();
592
- if (isNullOrUndefined(this.parent.rowDropSettings.targetID)) {
593
- this.removetopOrBottomBorder();
594
- this.removeChildBorder();
595
- }
596
- }
597
- }
598
- // To get the corresponding drop position related to mouse position
599
- const tObj: TreeGrid = this.parent;
600
- let rowTop: number = 0;
601
- const roundOff: number = 0;
602
- const toolHeight: number = tObj.toolbar && tObj.toolbar.length ?
603
- document.getElementById(tObj.element.id + '_gridcontrol_toolbarItems').offsetHeight : 0;
604
- // tObj.lastRow = tObj.getRowByIndex(tObj.getCurrentViewRecords().length - 1);
605
- const positionOffSet: PositionOffSet = this.getOffset(tObj.element);
606
- // let contentHeight1: number = (tObj.element.offsetHeight - (tObj.getContent() as HTMLElement).offsetHeight) + positionOffSet.top;
607
- const contentHeight: number = (tObj.getHeaderContent() as HTMLElement).offsetHeight + positionOffSet.top + toolHeight;
608
- const scrollTop: number = (tObj.getContent() as HTMLElement).firstElementChild.scrollTop;
609
- if (!isNullOrUndefined(rowEle)) {
610
- rowPositionHeight = (rowEle as HTMLElement).offsetTop - scrollTop;
611
- }
612
- // let scrollTop = (tObj.grid.scrollModule as any).content.scrollTop;
613
- if (this.parent.enableVirtualization) {
614
- rowTop = rowEle.getBoundingClientRect().top;
615
- }
616
- else {
617
- rowTop = rowPositionHeight + contentHeight + roundOff;
618
- }
619
- const rowBottom: number = (row[0] as HTMLElement).offsetHeight !== 0 && isNullOrUndefined(rowEle) ?
620
- rowTop + (row[0] as HTMLElement).offsetHeight : rowTop + (rowEle as HTMLElement).offsetHeight;
621
- const difference: number = rowBottom - rowTop;
622
- const divide: number = difference / 3;
623
- const topRowSegment: number = rowTop + divide;
624
- const middleRowSegment: number = topRowSegment + divide;
625
- const bottomRowSegment: number = middleRowSegment + divide;
626
- const mouseEvent: MouseEvent = getObject('originalEvent.event', args);
627
- const touchEvent: TouchEvent = getObject('originalEvent.event', args);
628
- let posy: number = (mouseEvent.type === 'mousemove') ? mouseEvent.pageY : ((!isNullOrUndefined(touchEvent) &&
629
- !isNullOrUndefined(touchEvent.changedTouches)) ? touchEvent.changedTouches[0].pageY : null);
630
- if (this.parent.enableVirtualization) {
631
- posy = (mouseEvent.type === 'mousemove') ? mouseEvent.clientY : ((!isNullOrUndefined(touchEvent) &&
632
- !isNullOrUndefined(touchEvent.changedTouches)) ? touchEvent.changedTouches[0].clientY : null);
633
- }
634
- const isTopSegment: boolean = posy <= topRowSegment;
635
- const isMiddleRowSegment: boolean = (posy > topRowSegment && posy <= middleRowSegment);
636
- const isBottomRowSegment: boolean = (posy > middleRowSegment && posy <= bottomRowSegment);
637
- let isBorderNeed: boolean = true;
638
- if (isTopSegment || isMiddleRowSegment || isBottomRowSegment) {
639
- if (isTopSegment && this.dropPosition !== 'Invalid') {
640
- this.removeChildBorder();
641
- this.dropPosition = 'topSegment';
642
- this.removetopOrBottomBorder();
643
- this.addFirstrowBorder(rowEle as HTMLTableRowElement);
644
- this.removeErrorElem();
645
- this.removeLastrowBorder(rowEle as HTMLTableRowElement);
646
- }
647
- if (isMiddleRowSegment && this.dropPosition !== 'Invalid') {
648
- this.removetopOrBottomBorder();
649
- this.dropPosition = 'middleSegment';
650
- this.addLastRowborder(rowEle as HTMLTableRowElement);
651
- this.addFirstrowBorder(rowEle as HTMLTableRowElement);
652
- }
653
- if (isBottomRowSegment && this.dropPosition !== 'Invalid') {
654
- this.removeErrorElem();
655
- this.removetopOrBottomBorder();
656
- this.removeChildBorder();
657
- this.dropPosition = 'bottomSegment';
658
- this.addLastRowborder(rowEle as HTMLTableRowElement);
659
- this.removeFirstrowBorder(rowEle as HTMLTableRowElement);
660
- }
661
- if ((isTopSegment || isBottomRowSegment) && this.dropPosition !== 'Invalid') {
662
- isBorderNeed = this.updateBorderStatus(row, index);
663
- this.topOrBottomBorder(args.target, isBorderNeed);
664
- }
665
- else if (isMiddleRowSegment && this.dropPosition !== 'Invalid') {
666
- let rowElement: HTMLElement[] = [];
667
- const element: Element = closest(args.target, 'tr');
668
- rowElement = [].slice.call(element.querySelectorAll('.e-rowcell,.e-rowdragdrop,.e-detailrowcollapse'));
669
- isBorderNeed = this.updateBorderStatus(row, index);
670
- if (rowElement.length > 0 && isBorderNeed) {
671
- this.addRemoveClasses(rowElement, true, 'e-childborder');
672
- }
673
- }
674
- }
675
- return this.dropPosition;
676
- }
677
-
678
- /**
679
- * Updates the border status for a specified row and index.
680
- *
681
- * @private
682
- * @param {Element[]} row - The array of row elements to be updated.
683
- * @param {number} index - The index of the row element for which the border status is to be updated.
684
- * @returns {boolean} - Returns true if the border status was successfully updated, otherwise false.
685
- */
686
- private updateBorderStatus(row: Element[], index: number): boolean {
687
- let isBorderNeed: boolean = true;
688
- let rows: any[] = this.parent.grid.getRows();
689
- const childRows: any[] = [];
690
- let hasDetailTemplate: boolean = false;
691
- if (!isNullOrUndefined(this.parent.detailTemplate)) {
692
- rows = this.parent.getDataRows();
693
- hasDetailTemplate = true;
694
- }
695
- const treegridColumnIndex: number = this.parent.treeColumnIndex;
696
- let treeColIndex: number = this.parent.allowRowDragAndDrop ?
697
- (hasDetailTemplate ? treegridColumnIndex + 2 : treegridColumnIndex + 1) :
698
- (hasDetailTemplate ? treegridColumnIndex + 1 : treegridColumnIndex);
699
- if (!isNullOrUndefined(this.parent.rowDropSettings.targetID)) {
700
- treeColIndex = treegridColumnIndex;
701
- }
702
- const dragRows: any[] = row;
703
- const targetRow: any[] = [rows[`${index}`]];
704
- if (this.dropPosition === 'topSegment') {
705
- row.filter((e: any) => {
706
- if (isNullOrUndefined(e) || isNullOrUndefined(e.cells) || isNullOrUndefined(targetRow[0]) ||
707
- isNullOrUndefined(targetRow[0].cells)) {
708
- return true;
709
- }
710
- const regex: RegExp = /index(\d+)|level(\d+)/g;
711
- const parentIndexLevel: number = e === null || e === undefined ? undefined : e.cells[`${treeColIndex}`].className.match(regex);
712
- const dropIndexLevel: number = targetRow[0].cells[`${treeColIndex}`].className.match(regex);
713
- if (isNullOrUndefined(dropIndexLevel) || isNullOrUndefined(dropIndexLevel) || isNullOrUndefined(parentIndexLevel)) {
714
- return true;
715
- }
716
- const parentLevel: number = +parentIndexLevel[1].match(/\d+/)[0];
717
- const dropParentLevel: number = +dropIndexLevel[1].match(/\d+/)[0];
718
- let InDraggedRowIndex: boolean = false;
719
- if (parentLevel !== 0 && parentLevel !== dropParentLevel) {
720
- return true;
721
- }
722
- for (let i: number = 0; i < rows.length; i++) {
723
- if (rows[parseInt(i.toString(), 10)] === dragRows[0]) {
724
- InDraggedRowIndex = true;
725
- }
726
- if (InDraggedRowIndex && rows[parseInt(i.toString(), 10)] !== dragRows[0]) {
727
- const parentIndexLevelInRow: any = rows[parseInt(i.toString(), 10)].cells[`${treeColIndex}`].className.match(regex);
728
- const parentLevelInRow: number = +parentIndexLevelInRow[1].match(/\d+/)[0];
729
- if (parentLevelInRow !== parentLevel && parentLevelInRow > parentLevel) {
730
- childRows.push(rows[parseInt(i.toString(), 10)]);
731
- } else {
732
- break;
733
- }
734
- }
735
- }
736
- if (parentLevel === dropParentLevel && ((childRows.length > 0 && parseInt(row[0].getAttribute('aria-rowindex')!, 10) - 1 === index - (childRows.length + 1)) || (childRows.length === 0 && parseInt(row[0].getAttribute('aria-rowindex')!, 10) - 1 === index - 1))) {
737
- isBorderNeed = false;
738
- }
739
- return true;
740
- });
741
- isBorderNeed = (!isNullOrUndefined(row) && childRows.length === 0 && !isNullOrUndefined(row[0].getAttribute('aria-rowindex')) && parseInt(row[0].getAttribute('aria-rowindex'), 10) - 1 === index - 1) && isNullOrUndefined(row[0]) ? false : isBorderNeed;
742
- }
743
- if (this.dropPosition === 'bottomSegment') {
744
- targetRow.filter((e: any) => {
745
- if (isNullOrUndefined(e) || isNullOrUndefined(e.cells) || isNullOrUndefined(dragRows[0]) ||
746
- isNullOrUndefined(dragRows[0].cells)) {
747
- return true;
748
- }
749
- const regex: RegExp = /index(\d+)|level(\d+)/g;
750
- const parentIndexLevel: number = e === null || e === undefined ? undefined : e.cells[`${treeColIndex}`].className.match(regex);
751
- const dragIndexLevel: number = dragRows[0].cells[`${treeColIndex}`].className.match(regex);
752
- if (isNullOrUndefined(dragIndexLevel) || isNullOrUndefined(parentIndexLevel)) {
753
- return true;
754
- }
755
- const parentLevel: number = +parentIndexLevel[1].match(/\d+/)[0];
756
- const dragParentLevel: number = +dragIndexLevel[1].match(/\d+/)[0];
757
- let InDraggedRowIndex: boolean = false;
758
- if (parentLevel !== 0 && parentLevel !== dragParentLevel) {
759
- return true;
760
- }
761
- for (let i: number = 0; i < rows.length; i++) {
762
- if (rows[parseInt(i.toString(), 10)] === targetRow[0]) {
763
- InDraggedRowIndex = true;
764
- }
765
- if (InDraggedRowIndex && rows[parseInt(i.toString(), 10)] !== targetRow[0]) {
766
- const parentIndexLevelInRow: any = rows[parseInt(i.toString(), 10)].cells[`${treeColIndex}`].className.match(regex);
767
- const parentLevelInRow: number = +parentIndexLevelInRow[1].match(/\d+/)[0];
768
- if (parentLevelInRow !== parentLevel && parentLevelInRow > parentLevel) {
769
- childRows.push(rows[parseInt(i.toString(), 10)]);
770
- } else {
771
- break;
772
- }
773
- }
774
- }
775
- if (!isNullOrUndefined(row) && parentLevel === dragParentLevel && ((childRows.length > 0 && !isNullOrUndefined(row[0].getAttribute('aria-rowindex')) && parseInt(row[0].getAttribute('aria-rowindex'), 10) - 1 === index + (childRows.length + 1)) || (childRows.length === 0 && !isNullOrUndefined(row[0].getAttribute('aria-rowindex')) && parseInt(row[0].getAttribute('aria-rowindex'), 10) - 1 === index + 1))) {
776
- isBorderNeed = false;
777
- }
778
- return true;
779
- });
780
- isBorderNeed = (!isNullOrUndefined(row) && childRows.length === 0 && !isNullOrUndefined(row[0].getAttribute('aria-rowindex')) && parseInt(row[0].getAttribute('aria-rowindex'), 10) - 1 === index + 1) && isNullOrUndefined(row[0]) ? false : isBorderNeed;
781
- }
782
- if (this.dropPosition === 'middleSegment') {
783
- targetRow.filter((e: any) => {
784
- if (isNullOrUndefined(e) || isNullOrUndefined(e.cells) || isNullOrUndefined(dragRows[0]) ||
785
- isNullOrUndefined(dragRows[0].cells)) {
786
- return true;
787
- }
788
- for (let i: number = 0; i < dragRows.length; i++) {
789
- const regex: RegExp = /index(\d+)|level(\d+)/g;
790
- let dropActualIndex: number = targetRow[0].rowIndex;
791
- const dragIndexLevel: RegExpMatchArray | null = dragRows[parseInt(i.toString(), 10)].cells[`${treeColIndex}`].className.match(regex);
792
- if (!dragIndexLevel) { return true; }
793
- const dragIndex: number = parseInt(dragIndexLevel.find((item: string) => item.includes('index')).match(/\d+/)[0] || '0', 10);
794
- if (hasDetailTemplate) {
795
- dropActualIndex = dropActualIndex / 2;
796
- }
797
- if (dragIndex === dropActualIndex && !this.parent.rowDropSettings.targetID) {
798
- isBorderNeed = false;
799
- }
800
- else {
801
- isBorderNeed = true;
802
- break;
803
- }
804
- }
805
- if (!isBorderNeed) {
806
- this.dropPosition = 'Invalid';
807
- this.addErrorElem();
808
- }
809
- return isBorderNeed;
810
- });
811
- }
812
- this.canDrop = isBorderNeed;
813
- return isBorderNeed;
814
- }
815
-
816
- /**
817
- * Removes the visual border from all child rows within the TreeGrid.
818
- *
819
- * @returns {void} No return value.
820
- */
821
- private removeChildBorder(): void {
822
- let borderElem: HTMLElement[] = [];
823
- borderElem = [].slice.call(this.parent.element.querySelectorAll('.e-childborder'));
824
- if (borderElem.length > 0) {
825
- this.addRemoveClasses(borderElem, false, 'e-childborder');
826
- }
827
- }
828
-
829
- /**
830
- * Adds a visual border to the first row of the TreeGrid.
831
- *
832
- * @param {HTMLTableRowElement} targetRow - The target row element to which the border will be added, if it is the first row.
833
- * @returns {void} No return value.
834
- */
835
- private addFirstrowBorder(targetRow: HTMLTableRowElement): void {
836
- const node: Element = this.parent.element;
837
- const tObj: TreeGrid = this.parent;
838
- if (targetRow && targetRow.rowIndex === 0 && !targetRow.classList.contains('e-emptyrow')) {
839
- const div: HTMLElement = this.parent.createElement('div', { className: 'e-firstrow-border' });
840
- const gridheaderEle: Element = this.parent.getHeaderContent();
841
- let toolbarHeight: number = 0;
842
- if (tObj.toolbar) {
843
- toolbarHeight = (tObj.toolbarModule.getToolbar() as HTMLElement).offsetHeight;
844
- }
845
- const multiplegrid: boolean = !isNullOrUndefined(this.parent.rowDropSettings.targetID);
846
- if (multiplegrid) {
847
- div.style.top = (this.parent.grid.element.getElementsByClassName('e-gridheader')[0] as HTMLElement).offsetHeight
848
- + toolbarHeight + 'px';
849
- }
850
- div.style.width = multiplegrid ? (node as HTMLElement).offsetWidth + 'px' :
851
- (node as HTMLElement).offsetWidth - this.getScrollWidth() + 'px';
852
- if (!gridheaderEle.querySelectorAll('.e-firstrow-border').length) {
853
- gridheaderEle.appendChild(div);
854
- }
855
- }
856
- }
857
-
858
- /**
859
- * Adds a visual border to the last row of the TreeGrid.
860
- *
861
- * @param {HTMLTableRowElement} trElement - The table row element to which the border will be added, if it is the last row.
862
- * @returns {void} No return value.
863
- */
864
- private addLastRowborder(trElement: HTMLTableRowElement): void {
865
- if (!trElement) { return; }
866
- const isEmptyRow: boolean = trElement && (trElement.classList.contains('e-emptyrow') ||
867
- trElement.classList.contains('e-columnheader') || trElement.classList.contains('e-detailrow'));
868
- if (isEmptyRow) { return; }
869
- if (trElement && !isEmptyRow && this.parent.getRows()[this.parent.getCurrentViewRecords().length - 1].getAttribute('data-uid') ===
870
- trElement.getAttribute('data-uid')) {
871
- const bottomborder: HTMLElement = this.parent.createElement('div', { className: 'e-lastrow-border' });
872
- const gridcontentEle: Element = this.parent.getContent();
873
- bottomborder.style.width = (this.parent.element as HTMLElement).offsetWidth - this.getScrollWidth() + 'px';
874
- if (!gridcontentEle.querySelectorAll('.e-lastrow-border').length) {
875
- gridcontentEle.classList.add('e-treegrid-relative');
876
- gridcontentEle.appendChild(bottomborder);
877
- bottomborder.style.bottom = this.getScrollWidth() + 'px';
878
- }
879
- }
880
- }
881
-
882
- /**
883
- * Retrieves the total scroll width of the TreeGrid content area.
884
- *
885
- * @returns {number} The width of the scrollbar if content overflows, otherwise 0.
886
- */
887
- private getScrollWidth(): number {
888
- const scrollElem: HTMLElement = this.parent.getContent().firstElementChild as HTMLElement;
889
- return scrollElem.scrollWidth > scrollElem.offsetWidth ? Scroll.getScrollBarWidth() : 0;
890
- }
891
-
892
- /**
893
- * Adds an error element to the dragged row element during a row drag-and-drop operation.
894
- *
895
- * @returns {void} No return value.
896
- */
897
- private addErrorElem(): void {
898
- const dragelem: Element = document.getElementsByClassName('e-cloneproperties')[0];
899
- const errorelemCount: number = dragelem.querySelectorAll('.e-errorelem').length;
900
- const sanitize: string = 'sanitize';
901
- if (!errorelemCount && !this.parent.rowDropSettings.targetID) {
902
- const errorContainer: HTMLElement = document.createElement('div');
903
- errorContainer.classList.add('e-errorcontainer', 'e-icons', 'e-errorelem');
904
- const rowCell: HTMLElement = dragelem.querySelector('.e-rowcell') as HTMLElement;
905
- const errorVal: Element = dragelem.querySelector('.errorValue');
906
- let content: string = rowCell.innerHTML;
907
- if (errorVal) {
908
- content = this.parent[`${sanitize}`](errorVal.innerHTML);
909
- errorVal.parentNode.removeChild(errorVal);
910
- }
911
- rowCell.innerHTML = '';
912
- const spanContent: HTMLElement = document.createElement('span');
913
- spanContent.className = 'errorValue';
914
- spanContent.style.paddingLeft = '16px';
915
- spanContent.innerHTML = this.parent[`${sanitize}`](content);
916
- rowCell.appendChild(errorContainer);
917
- rowCell.appendChild(spanContent);
918
- const dropItemSpan: HTMLElement = document.querySelector('.e-dropitemscount');
919
- if (this.hasDropItem && dropItemSpan) {
920
- const dropItemLeft: number = parseInt(dropItemSpan.style.left, 10) + errorContainer.offsetWidth + 16;
921
- const spanLeft: number = !this.parent.enableRtl ? dropItemLeft : 0;
922
- dropItemSpan.style.left = `${spanLeft}px`;
923
- this.hasDropItem = false;
924
- }
925
- }
926
- }
927
-
928
- /**
929
- * Removes the error element from the DOM and adjusts the position of the drop item count if necessary.
930
- *
931
- * @returns {void} No return value.
932
- */
933
- private removeErrorElem(): void {
934
- const errorelem: HTMLElement = document.querySelector('.e-errorelem');
935
- const errorValue: HTMLElement = document.querySelector('.errorValue');
936
- const dropItemSpan: HTMLElement = document.querySelector('.e-dropitemscount');
937
- if (errorelem) {
938
- if (dropItemSpan) {
939
- const dropItemLeft: number = parseInt(dropItemSpan.style.left, 10) - errorelem.offsetWidth - 16;
940
- setStyleAttribute(errorValue, {
941
- paddingLeft: '0px'
942
- });
943
- if (!this.parent.enableRtl) {
944
- setStyleAttribute(dropItemSpan, {
945
- left: `${dropItemLeft}px`
946
- });
947
- }
948
- }
949
- errorelem.remove();
950
- }
951
- this.hasDropItem = true;
952
- }
953
-
954
- /**
955
- * Applies drop border styles to row elements based on the current drop position ('topSegment' or 'bottomSegment').
956
- *
957
- * @param {Element} target - The target element where the drop action is taking place.
958
- * @param {boolean} [isBorderNeed=true] - Indicates whether a border is needed during the drop action. Defaults to `true`.
959
- * @returns {void} No return value.
960
- */
961
- private topOrBottomBorder(target: Element, isBorderNeed: boolean = true): void {
962
- const element: Element = closest(target, 'tr');
963
- const rowElements: HTMLElement[] = element ?
964
- Array.from(element.querySelectorAll('.e-rowcell, .e-rowdragdrop, .e-detailrowcollapse')) : [];
965
- if (!rowElements.length) { return; }
966
- const classAction: any = isBorderNeed ? this.addRemoveClasses.bind(this, rowElements, true) : this.addRemoveClasses.bind(this, rowElements, false, 'e-dragborder');
967
- if (this.dropPosition === 'topSegment') {
968
- classAction('e-droptop');
969
- const lastRowDragBorder: Element = this.parent.element.querySelector('.e-lastrow-dragborder');
970
- if (lastRowDragBorder) {
971
- lastRowDragBorder.remove();
972
- }
973
- }
974
- if (this.dropPosition === 'bottomSegment') {
975
- classAction('e-dropbottom');
976
- }
977
- }
978
-
979
- /**
980
- * Removes the drop border classes ('e-dropbottom' and 'e-droptop') from the parent element if present.
981
- *
982
- * @returns {void} No return value.
983
- */
984
- private removetopOrBottomBorder(): void {
985
- let border: HTMLElement[] = [];
986
- border = [].slice.call(this.parent.element.querySelectorAll('.e-dropbottom, .e-droptop'));
987
- if (this.parent.rowDropSettings.targetID) {
988
- border = [].slice.call(document.querySelectorAll('.e-dropbottom, .e-droptop'));
989
- }
990
- if (border.length) {
991
- this.addRemoveClasses(border, false, 'e-dropbottom');
992
- this.addRemoveClasses(border, false, 'e-droptop');
993
- }
994
- }
995
-
996
- /**
997
- * Adds or removes a specified class from a list of HTML elements.
998
- *
999
- * @param {Element[]} cells - The list of HTML elements to which the class will be added or removed.
1000
- * @param {boolean} add - A flag indicating whether to add (`true`) or remove (`false`) the class.
1001
- * @param {string} className - The class name to be added or removed from each element in `cells`.
1002
- * @returns {void} No return value.
1003
- */
1004
- private addRemoveClasses(cells: Element[], add: boolean, className: string): void {
1005
- for (let i: number = 0, len: number = cells.length; i < len; i++) {
1006
- if (add) {
1007
- cells[parseInt(i.toString(), 10)].classList.add(className);
1008
- } else {
1009
- cells[parseInt(i.toString(), 10)].classList.remove(className);
1010
- }
1011
- }
1012
- }
1013
-
1014
- /**
1015
- * Calculates the offset position of the specified HTML element relative to the document.
1016
- *
1017
- * @param {Element} element - The HTML element for which the offset position is calculated.
1018
- * @returns {PositionOffSet} The offset position containing `top` and `left` values.
1019
- */
1020
- private getOffset(element: Element): PositionOffSet {
1021
- const box: DOMRect | ClientRect = element.getBoundingClientRect();
1022
- const body: HTMLElement = document.body;
1023
- const docElem: HTMLElement = document.documentElement;
1024
- const scrollTop: number = window.pageYOffset || docElem.scrollTop || body.scrollTop;
1025
- const scrollLeft: number = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
1026
- const clientTop: number = docElem.clientTop || body.clientTop || 0;
1027
- const clientLeft: number = docElem.clientLeft || body.clientLeft || 0;
1028
- const top: number = box.top + scrollTop - clientTop;
1029
- const left: number = box.left + scrollLeft - clientLeft;
1030
- return { top: Math.round(top), left: Math.round(left) };
1031
- }
1032
-
1033
- /**
1034
- * Handles the dragging of rows in the TreeGrid.
1035
- *
1036
- * @param {RowDragEventArgs} args - The event arguments for the row drag action.
1037
- * @returns {void} This function does not return a value.
1038
- */
1039
- private Rowdraging(args: RowDragEventArgs): void {
1040
- const tObj: TreeGrid = this.parent;
1041
- const cloneElement: HTMLElement = this.parent.element.querySelector('.e-cloneproperties') as HTMLElement;
1042
- if (!cloneElement) { return; }
1043
- cloneElement.style.cursor = '';
1044
- const rowEle: Element = args.target ? closest(args.target, 'tr') : null;
1045
- let rowIdx: number = -1;
1046
- if (!isNullOrUndefined(this.parent.detailTemplate)) {
1047
- rowIdx = rowEle ? this.parent.getDataRows().indexOf(rowEle as HTMLTableRowElement) : -1;
1048
- }
1049
- else {
1050
- rowIdx = rowEle ? (rowEle as HTMLTableRowElement).rowIndex : -1;
1051
- }
1052
- if (rowIdx === -1) {
1053
- this.canDrop = false;
1054
- this.addErrorElem();
1055
- this.removetopOrBottomBorder();
1056
- this.removeChildBorder();
1057
- return;
1058
- }
1059
- const dragRecords: ITreeData[] = Array.isArray(args.data) ? args.data : [args.data as ITreeData];
1060
- let droppedRecord: ITreeData = tObj.getCurrentViewRecords()[parseInt(rowIdx.toString(), 10)];
1061
- if (tObj.rowDropSettings.targetID) {
1062
- const dropElement: Element = parentsUntil(args.target, 'e-treegrid');
1063
- if (dropElement && dropElement.id === this.parent.rowDropSettings.targetID) {
1064
- const srcControl: TreeGrid = (<EJ2Intance>dropElement).ej2_instances[0];
1065
- droppedRecord = srcControl.getCurrentViewRecords()[parseInt(rowIdx.toString(), 10)];
1066
- }
1067
- }
1068
- this.removeErrorElem();
1069
- this.canDrop = true;
1070
- this.ensuredropPosition(dragRecords, droppedRecord);
1071
- if (!tObj.rowDropSettings.targetID && this.canDrop && !isNullOrUndefined(args.rows[0])) {
1072
- tObj.rowDragAndDropModule.updateIcon(args.rows, rowIdx, args);
1073
- }
1074
- if (tObj.rowDropSettings.targetID) {
1075
- const dropElement: Element = parentsUntil(args.target, 'e-treegrid');
1076
- if (dropElement && dropElement.id === this.parent.rowDropSettings.targetID) {
1077
- const srcControl: TreeGrid = (<EJ2Intance>dropElement).ej2_instances[0];
1078
- srcControl.rowDragAndDropModule.updateIcon(args.rows, rowIdx, args);
1079
- this.dropPosition = srcControl.rowDragAndDropModule.dropPosition;
1080
- }
1081
- }
1082
- if (args.target && closest(args.target, '#' + tObj.rowDropSettings.targetID)) {
1083
- const dropElement: Element = parentsUntil(args.target, 'e-treegrid');
1084
- if (!dropElement) {
1085
- cloneElement.style.cursor = 'default';
1086
- }
1087
- }
1088
- }
1089
-
1090
- /**
1091
- * Handles the row drop event for the TreeGrid.
1092
- *
1093
- * @param {RowDropEventArgs} args - The event arguments for the row drop action.
1094
- * @returns {void} This function does not return a value.
1095
- */
1096
- private rowDropped(args: RowDropEventArgs): void {
1097
- const tObj: TreeGrid = this.parent;
1098
- const parentItem: string = 'parentItem';
1099
- if (!tObj.rowDropSettings.targetID) {
1100
- if (parentsUntil(args.target, 'e-content') || (this.dropPosition === 'Invalid' || !this.canDrop)) {
1101
- if (this.parent.element.querySelector('.e-errorelem') || !this.canDrop) {
1102
- this.dropPosition = 'Invalid';
1103
- }
1104
- setValue('dropPosition', this.dropPosition, args);
1105
- tObj.trigger(events.rowDrop, args);
1106
- if (!args.cancel) {
1107
- if (!isCountRequired(this.parent) && (this.dropPosition === 'Invalid' && !this.canDrop)) {
1108
- return;
1109
- }
1110
- if (!isCountRequired(this.parent)) {
1111
- this.dropRows(args);
1112
- }
1113
- if (tObj.isLocalData) {
1114
- tObj.flatData = this.orderToIndex(tObj.flatData);
1115
- }
1116
- tObj.grid.refresh();
1117
- this.removeRowBorders();
1118
- }
1119
- }
1120
- } else {
1121
- if (args.target && closest(args.target, '#' + tObj.rowDropSettings.targetID) || parentsUntil(args.target, 'e-treegrid') &&
1122
- parentsUntil(args.target, 'e-treegrid').id === tObj.rowDropSettings.targetID || args.target && document.getElementById(tObj.rowDropSettings.targetID)) {
1123
- if (this.parent.element.querySelector('.e-errorelem') || !this.canDrop) {
1124
- this.dropPosition = 'Invalid';
1125
- }
1126
- setValue('dropPosition', this.dropPosition, args);
1127
- tObj.trigger(events.rowDrop, args);
1128
- if (!args.cancel && tObj.rowDropSettings.targetID) {
1129
- if (this.dropPosition === 'Invalid' && !this.canDrop) {
1130
- return;
1131
- }
1132
- this.dragDropGrid(args);
1133
- if (tObj.isLocalData) {
1134
- tObj.flatData = this.orderToIndex(tObj.flatData);
1135
- }
1136
- }
1137
- }
1138
- }
1139
- this.removetopOrBottomBorder();
1140
- this.removeChildBorder();
1141
- this.removeRowBorders();
1142
- if (this.parent.enableImmutableMode && !this.parent.allowPaging && !isNullOrUndefined(args.data[0][`${parentItem}`])) {
1143
- let index: number = this.parent.treeColumnIndex;
1144
- index = index + 1;
1145
- const primaryKeyField: string = this.parent.getPrimaryKeyFieldNames()[0];
1146
- let rowIndex: number = this.parent.grid.getRowIndexByPrimaryKey(args.data[0][`${primaryKeyField}`]);
1147
- const row: HTMLTableRowElement = this.parent.getRows()[parseInt(rowIndex.toString(), 10)];
1148
- let data: Object = args.data[0];
1149
- if (this.dropPosition === 'middleSegment') {
1150
- const record: Object[] = []; const rows: HTMLTableRowElement[] = [];
1151
- record.push(data); rows.push(row);
1152
- const parentUniqueID: string = 'parentUniqueID';
1153
- data = getParentData(this.parent, args.data[0][`${parentUniqueID}`]);
1154
- rowIndex = this.parent.grid.getRowIndexByPrimaryKey(data[`${primaryKeyField}`]);
1155
- const parentrow: HTMLTableRowElement = this.parent.getRows()[parseInt(rowIndex.toString(), 10)];
1156
- record.push(data); rows.push(parentrow);
1157
- for (let i: number = 0; i < record.length; i++) {
1158
- this.parent.renderModule.cellRender({
1159
- data: record[parseInt(i.toString(), 10)],
1160
- cell: rows[parseInt(i.toString(), 10)].cells[parseInt(index.toString(), 10)],
1161
- column: this.parent.grid.getColumns()[this.parent.treeColumnIndex],
1162
- requestType: 'rowDragAndDrop'
1163
- });
1164
- }
1165
- const targetEle: Element = parentrow.getElementsByClassName('e-treegridcollapse')[0];
1166
- if (!isNullOrUndefined(targetEle)) {
1167
- removeClass([targetEle], 'e-treegridcollapse');
1168
- addClass([targetEle], 'e-treegridexpand');
1169
- }
1170
- } else {
1171
- this.parent.renderModule.cellRender({
1172
- data: data, cell: row.cells[parseInt(index.toString(), 10)],
1173
- column: this.parent.grid.getColumns()[this.parent.treeColumnIndex],
1174
- requestType: 'rowDragAndDrop'
1175
- });
1176
- }
1177
- }
1178
- }
1179
-
1180
- /**
1181
- * Removes the border elements for the first and last rows of the TreeGrid.
1182
- *
1183
- * @returns {void} This function does not return a value.
1184
- */
1185
- private removeRowBorders(): void {
1186
- ['e-firstrow-border', 'e-lastrow-border'].forEach((className: string): void => {
1187
- const element: HTMLElement = this.parent.element.getElementsByClassName(className)[0] as HTMLElement;
1188
- if (element) {
1189
- element.remove();
1190
- }
1191
- });
1192
- }
1193
-
1194
- /**
1195
- * Handles the drag-and-drop operation between TreeGrids, updating the source and target grids.
1196
- *
1197
- * @param {RowDropEventArgs} args - The arguments related to the row drop event, including target information and data being dropped.
1198
- * @returns {void} - This function does not return any value.
1199
- */
1200
- private dragDropGrid(args: RowDropEventArgs): void {
1201
- const tObj: TreeGrid = this.parent;
1202
- const targetRow: HTMLTableRowElement = closest(args.target, 'tr') as HTMLTableRowElement;
1203
- const targetIndex: number = isNaN(this.getTargetIdx(targetRow)) ? 0 : this.getTargetIdx(targetRow);
1204
- const dropElement: Element = parentsUntil(args.target, 'e-treegrid');
1205
- let srcControl: TreeGrid;
1206
- if (dropElement && dropElement.id === this.parent.rowDropSettings.targetID && !isRemoteData(this.parent)
1207
- && !isCountRequired(this.parent)) {
1208
- srcControl = (<EJ2Intance>dropElement).ej2_instances[0];
1209
- let records: ITreeData[] = tObj.getSelectedRecords();
1210
- const indexes: number[] = [];
1211
- for (let i: number = 0; i < records.length; i++) {
1212
- indexes[parseInt(i.toString(), 10)] = records[parseInt(i.toString(), 10)].index;
1213
- }
1214
- const data: ITreeData[] = srcControl.dataSource as ITreeData[];
1215
- if (this.parent.idMapping !== null && (isNullOrUndefined(this.dropPosition) || this.dropPosition === 'bottomSegment' || this.dropPosition === 'Invalid') && !(data.length)) {
1216
- const actualData: ITreeData[] = [];
1217
- for (let i: number = 0; i < records.length; i++) {
1218
- if (records[parseInt(i.toString(), 10)].hasChildRecords) {
1219
- actualData.push(records[parseInt(i.toString(), 10)]);
1220
- const child: ITreeData[] = findChildrenRecords(records[parseInt(i.toString(), 10)]);
1221
- for (let i: number = 0; i < child.length; i++) {
1222
- actualData.push(child[parseInt(i.toString(), 10)]); // push child records to drop the parent record along with its child records
1223
- }
1224
- }
1225
- }
1226
- if (actualData.length) {
1227
- records = actualData;
1228
- }
1229
- }
1230
- tObj.notify(events.rowsRemove, { indexes: indexes, records: records });
1231
- srcControl.notify(events.rowsAdd, { toIndex: targetIndex, records: records });
1232
- const srcControlFlatData: ITreeData[] = srcControl.rowDragAndDropModule.treeGridData;
1233
- if (!isNullOrUndefined(srcControlFlatData)) {
1234
- for (let i: number = 0; i < srcControlFlatData.length; i++) {
1235
- srcControlFlatData[parseInt(i.toString(), 10)].index = i;
1236
- if (!isNullOrUndefined(srcControlFlatData[parseInt(i.toString(), 10)].parentItem)) {
1237
- const actualIndex: number =
1238
- <number>getValue('uniqueIDCollection.' + srcControlFlatData[parseInt(i.toString(), 10)].parentUniqueID + '.index', srcControl);
1239
- srcControlFlatData[parseInt(i.toString(), 10)].parentItem.index = actualIndex;
1240
- }
1241
- }
1242
- }
1243
- tObj.grid.refresh();
1244
- srcControl.grid.refresh();
1245
- if ((<ITreeData[]>srcControl.grid.dataSource).length > 1) {
1246
- srcControl.grid.refresh();
1247
- if (!isNullOrUndefined(srcControl.getHeaderContent().querySelector('.e-firstrow-border'))) {
1248
- srcControl.getHeaderContent().querySelector('.e-firstrow-border').remove();
1249
- }
1250
- if (!isNullOrUndefined(srcControl.getContent().querySelector('.e-lastrow-border'))) {
1251
- srcControl.getContent().querySelector('.e-lastrow-border').remove();
1252
- }
1253
- }
1254
- }
1255
- if (isCountRequired(this.parent)) {
1256
- srcControl = (<EJ2Intance>dropElement).ej2_instances[0];
1257
- tObj.grid.refresh();
1258
- srcControl.grid.refresh();
1259
- }
1260
- }
1261
-
1262
- /**
1263
- * Retrieves the index of the target row based on its 'aria-rowindex' attribute.
1264
- *
1265
- * @param {Element} targetRow - The target row element from which to retrieve the index.
1266
- * @returns {number} - The index of the target row, or 0 if the targetRow is null or undefined.
1267
- */
1268
- private getTargetIdx(targetRow: Element): number {
1269
- return targetRow ? parseInt(targetRow.getAttribute('aria-rowindex'), 10) - 1 : 0;
1270
- }
1271
-
1272
- /**
1273
- * Retrieves the parent data of a given record during a row drag-and-drop operation.
1274
- *
1275
- * @param {ITreeData} record - The record for which to retrieve the parent data.
1276
- * @param {Object[]} [data] - Optional data array containing additional information related to the drop operation.
1277
- * @returns {void} - This function does not return any value.
1278
- */
1279
- private getParentData(record: ITreeData, data?: Object[]): void {
1280
- const parentItem: ITreeData = record.parentItem; let selectedItemIndex: number = -1;
1281
- if (this.parent.enableVirtualization && this.parent.selectedRowIndex !== -1) {
1282
- selectedItemIndex = (this.parent.getSelectedRows()[0] as HTMLTableRowElement).rowIndex;
1283
- } else if (this.parent.selectedRowIndex !== -1) {
1284
- selectedItemIndex = this.parent.selectedRowIndex;
1285
- }
1286
- if (this.dropPosition === 'bottomSegment') {
1287
- const primaryKeyField: string = this.parent.getPrimaryKeyFieldNames()[0];
1288
- const rowIndex: number = selectedItemIndex === -1 ?
1289
- (this.parent.grid.getRowIndexByPrimaryKey(data[0][`${primaryKeyField}`]))
1290
- : this.parent.getSelectedRowIndexes()[0];
1291
- const selectedRecord: ITreeData = this.parent.getCurrentViewRecords()[parseInt(rowIndex.toString(), 10)];
1292
- this.droppedRecord = getParentData(this.parent, selectedRecord.parentItem.uniqueID);
1293
- }
1294
- if (this.dropPosition === 'middleSegment') {
1295
- const level: number = (this.parent.getCurrentViewRecords()[parseInt(selectedItemIndex.toString(), 10)] as ITreeData).level;
1296
- if (level === parentItem.level) {
1297
- this.droppedRecord = getParentData(this.parent, parentItem.uniqueID);
1298
- } else {
1299
- this.getParentData(parentItem);
1300
- }
1301
- }
1302
- }
1303
-
1304
- /**
1305
- * Handles the row drop operation for the tree grid.
1306
- *
1307
- * @param {RowDropEventArgs} args - The event arguments containing details about the drop operation, including the target index and data.
1308
- * @param {boolean} [isByMethod=false] - Optional flag indicating if the drop operation is triggered by a method.
1309
- * @returns {void} - This function does not return any value.
1310
- */
1311
- private dropRows(args: RowDropEventArgs, isByMethod?: boolean): void {
1312
- if (this.dropPosition !== 'Invalid' && !isRemoteData(this.parent)) {
1313
- const tObj: TreeGrid = this.parent;
1314
- let draggedRecord: ITreeData; let droppedRecord: ITreeData;
1315
- if (isNullOrUndefined(args.dropIndex)) {
1316
- const primaryKeyField: string = this.parent.getPrimaryKeyFieldNames()[0];
1317
- const rowIndex: number = tObj.selectedRowIndex === -1 ?
1318
- (this.parent.grid.getRowIndexByPrimaryKey(args.data[0][`${primaryKeyField}`])) - 1
1319
- : tObj.getSelectedRowIndexes()[0] - 1;
1320
- const record: ITreeData = (tObj.getCurrentViewRecords()[parseInt(rowIndex.toString(), 10)] as ITreeData);
1321
- this.getParentData(record, args.data);
1322
- } else {
1323
- args.dropIndex = args.dropIndex === args.fromIndex ? this.getTargetIdx(args.target.parentElement) : args.dropIndex;
1324
- if (this.parent.enableVirtualization) {
1325
- const index: number = (this.parent.getRowByIndex(args.dropIndex) as HTMLTableRowElement).rowIndex;
1326
- this.droppedRecord = tObj.getCurrentViewRecords()[parseInt(index.toString(), 10)];
1327
- }
1328
- else {
1329
- if (!isNullOrUndefined(this.parent.rowDropSettings.targetID)) {
1330
- const rowsObject: Row<Column>[] = this.parent.grid.getRowsObject();
1331
- this.droppedRecord = rowsObject.length > 0 ? rowsObject[args.dropIndex].data : undefined;
1332
- }
1333
- else {
1334
- this.droppedRecord = tObj.getCurrentViewRecords()[args.dropIndex];
1335
- }
1336
- }
1337
- }
1338
- let dragRecords: ITreeData[] = [];
1339
- droppedRecord = this.droppedRecord;
1340
- if (!args.data[0]) {
1341
- dragRecords.push(args.data as ITreeData);
1342
- } else {
1343
- dragRecords = args.data;
1344
- }
1345
- this.parent[this.modifiedRecords].push(args.data[0], droppedRecord);
1346
- let count: number = 0;
1347
- const multiplegrid: string = this.parent.rowDropSettings.targetID;
1348
- this.isMultipleGrid = multiplegrid;
1349
- if (!multiplegrid) {
1350
- this.ensuredropPosition(dragRecords, droppedRecord);
1351
- } else {
1352
- this.isaddtoBottom = multiplegrid && this.isDraggedWithChild;
1353
- }
1354
- const dragLength: number = dragRecords.length;
1355
- if (!isNullOrUndefined(this.parent.idMapping)) {
1356
- dragRecords.reverse();
1357
- }
1358
- for (let i: number = 0; i < dragLength; i++) {
1359
- draggedRecord = dragRecords[parseInt(i.toString(), 10)];
1360
- this.draggedRecord = draggedRecord;
1361
- if (!this.draggedRecord.hasChildRecords) {
1362
- for (const dragRecord of dragRecords) {
1363
- if (!isNullOrUndefined(dragRecord.childRecords) &&
1364
- dragRecord.childRecords.indexOf(this.draggedRecord) !== -1) {
1365
- this.draggedRecord = undefined;
1366
- }
1367
- }
1368
- }
1369
- if (!isNullOrUndefined(this.draggedRecord)) {
1370
- if (this.dropPosition !== 'Invalid' && !isNullOrUndefined(this.droppedRecord)) {
1371
- if (!tObj.rowDropSettings.targetID || isByMethod) {
1372
- this.deleteDragRow();
1373
- }
1374
- if (this.draggedRecord === this.droppedRecord) {
1375
- let correctIndex: number = this.getTargetIdx((<HTMLElement>args.target).offsetParent.parentElement);
1376
- if (isNaN(correctIndex)) {
1377
- correctIndex = this.getTargetIdx(args.target.parentElement);
1378
- }
1379
- args.dropIndex = correctIndex;
1380
- droppedRecord = this.droppedRecord = this.parent.getCurrentViewRecords()[args.dropIndex];
1381
- }
1382
- if (droppedRecord.parentItem || this.dropPosition === 'middleSegment') {
1383
- const parentRecords: ITreeData[] = tObj.parentData;
1384
- const newParentIndex: number = parentRecords.indexOf(this.draggedRecord);
1385
- if (newParentIndex !== -1) {
1386
- parentRecords.splice(newParentIndex, 1);
1387
- }
1388
- }
1389
- const recordIndex1: number = this.treeGridData.indexOf(droppedRecord);
1390
- this.dropAtTop(recordIndex1);
1391
- if (this.dropPosition === 'bottomSegment') {
1392
- if (!droppedRecord.hasChildRecords) {
1393
- if (this.parent.parentIdMapping) {
1394
- this.treeData.splice(recordIndex1 + 1, 0, this.draggedRecord.taskData);
1395
- }
1396
- this.treeGridData.splice(recordIndex1 + 1, 0, this.draggedRecord);
1397
- } else {
1398
- count = this.getChildCount(droppedRecord, 0);
1399
- if (this.parent.parentIdMapping) {
1400
- this.treeData.splice(recordIndex1 + count + 1, 0, this.draggedRecord.taskData);
1401
- }
1402
- this.treeGridData.splice(recordIndex1 + count + 1, 0, this.draggedRecord);
1403
- }
1404
- if (isNullOrUndefined(droppedRecord.parentItem)) {
1405
- delete draggedRecord.parentItem;
1406
- delete draggedRecord.parentUniqueID;
1407
- draggedRecord.level = 0;
1408
- if (this.parent.parentIdMapping) {
1409
- draggedRecord[this.parent.parentIdMapping] = null;
1410
- }
1411
- }
1412
- if (droppedRecord.parentItem) {
1413
- const rec: ITreeData[] = this.getChildrecordsByParentID(droppedRecord.parentUniqueID);
1414
- const childRecords: ITreeData[] = rec[0].childRecords;
1415
- const droppedRecordIndex: number = childRecords.indexOf(droppedRecord) + 1;
1416
- childRecords.splice(droppedRecordIndex, 0, draggedRecord);
1417
- draggedRecord.parentItem = droppedRecord.parentItem;
1418
- draggedRecord.parentUniqueID = droppedRecord.parentUniqueID;
1419
- draggedRecord.level = droppedRecord.level;
1420
- if (this.parent.parentIdMapping) {
1421
- draggedRecord[this.parent.parentIdMapping] = droppedRecord[this.parent.parentIdMapping];
1422
- draggedRecord.parentItem = droppedRecord.parentItem;
1423
- draggedRecord.level = droppedRecord.level;
1424
- }
1425
- }
1426
- if (draggedRecord.hasChildRecords) {
1427
- const level: number = 1;
1428
- this.updateChildRecordLevel(draggedRecord, level);
1429
- this.updateChildRecord(draggedRecord, recordIndex1 + count + 1);
1430
- }
1431
- }
1432
- this.dropMiddle(recordIndex1);
1433
- }
1434
- if (isNullOrUndefined(draggedRecord.parentItem)) {
1435
- const parentRecords: ITreeData[] = tObj.parentData;
1436
- const newParentIndex: number = parentRecords.indexOf(this.droppedRecord);
1437
- let nonRepeat: number = 0;
1438
- parentRecords.filter((e: ITreeData) => {
1439
- if (draggedRecord.uniqueID === e.uniqueID) {
1440
- nonRepeat++;
1441
- }
1442
- });
1443
- if (this.dropPosition === 'bottomSegment' && nonRepeat === 0) {
1444
- parentRecords.splice(newParentIndex + 1, 0, draggedRecord);
1445
- } else if (this.dropPosition === 'topSegment' && nonRepeat === 0) {
1446
- parentRecords.splice(newParentIndex, 0, draggedRecord);
1447
- }
1448
- }
1449
- tObj.rowDragAndDropModule.refreshGridDataSource();
1450
- }
1451
- }
1452
- }
1453
- }
1454
-
1455
- /**
1456
- * Handles the logic for inserting a dragged record into the middle of a parent record's child records.
1457
- *
1458
- * @param {number} recordIndex - The index at which to insert the dragged record relative to the parent record's child records.
1459
- * @returns {void} - This function does not return any value.
1460
- */
1461
- private dropMiddle(recordIndex: number): void {
1462
- const tObj: TreeGrid = this.parent;
1463
- const childRecords: ITreeData[] = findChildrenRecords(this.droppedRecord);
1464
- const childRecordsLength: number = (isNullOrUndefined(childRecords) ||
1465
- childRecords.length === 0) ? recordIndex + 1 :
1466
- childRecords.length + recordIndex + 1;
1467
- if (this.dropPosition === 'middleSegment') {
1468
- if (tObj.parentIdMapping) {
1469
- this.treeData.splice(childRecordsLength, 0, this.draggedRecord.taskData);
1470
- this.treeGridData.splice(childRecordsLength, 0, this.draggedRecord);
1471
- } else {
1472
- this.treeGridData.splice(childRecordsLength, 0, this.draggedRecord);
1473
- }
1474
- this.recordLevel();
1475
- if (this.draggedRecord.hasChildRecords) {
1476
- this.updateChildRecord(this.draggedRecord, childRecordsLength);
1477
- }
1478
- }
1479
- }
1480
-
1481
- /**
1482
- * Handles the logic for inserting a dragged record at the top of a parent record's child records.
1483
- *
1484
- * @param {number} recordIndex1 - The index at which to insert the dragged record in the tree grid data.
1485
- * @returns {void} - This function does not return any value.
1486
- */
1487
- private dropAtTop(recordIndex1: number): void {
1488
- const tObj: TreeGrid = this.parent;
1489
- if (this.dropPosition === 'topSegment') {
1490
- if (tObj.parentIdMapping) {
1491
- this.treeData.splice(recordIndex1, 0, this.draggedRecord.taskData);
1492
- }
1493
- const targetRecord: ITreeData = this.treeGridData[parseInt(recordIndex1.toString(), 10)];
1494
- this.draggedRecord.parentItem = targetRecord.parentItem;
1495
- this.draggedRecord.parentUniqueID = targetRecord.parentUniqueID;
1496
- this.draggedRecord.level = targetRecord.level;
1497
- // Insert dragged record into the grid data
1498
- this.treeGridData.splice(parseInt(recordIndex1.toString(), 10), 0, this.draggedRecord);
1499
- if (this.draggedRecord.hasChildRecords) {
1500
- const level: number = 1;
1501
- this.updateChildRecord(this.draggedRecord, recordIndex1);
1502
- this.updateChildRecordLevel(this.draggedRecord, level);
1503
- }
1504
- if (this.droppedRecord.parentItem) {
1505
- const rec: ITreeData[] = this.getChildrecordsByParentID(this.droppedRecord.parentUniqueID);
1506
- const childRecords: ITreeData[] = rec[0].childRecords;
1507
- const droppedRecordIndex: number = childRecords.indexOf(this.droppedRecord);
1508
- // Insert the dragged record into the child records at the appropriate position
1509
- childRecords.splice(droppedRecordIndex, 0, this.draggedRecord);
1510
- }
1511
- }
1512
- }
1513
-
1514
- /**
1515
- * Updates the level and hierarchy of the dragged record based on the drop position.
1516
- *
1517
- * @returns {void} - This function does not return any value.
1518
- */
1519
- private recordLevel(): void {
1520
- const tObj: TreeGrid = this.parent;
1521
- const draggedRecord: ITreeData = this.draggedRecord;
1522
- const droppedRecord: ITreeData = this.droppedRecord;
1523
- const childItem: string = tObj.childMapping;
1524
- if (!droppedRecord.hasChildRecords) {
1525
- droppedRecord.hasChildRecords = true;
1526
- droppedRecord.hasFilteredChildRecords = true;
1527
- if (isNullOrUndefined(droppedRecord.childRecords) || droppedRecord.childRecords.length === 0) {
1528
- droppedRecord.childRecords = [];
1529
- if (!tObj.parentIdMapping && isNullOrUndefined(droppedRecord.taskData[`${childItem}`])) {
1530
- droppedRecord.taskData[`${childItem}`] = [];
1531
- }
1532
- }
1533
- }
1534
- if (this.dropPosition === 'middleSegment') {
1535
- const parentItem: ITreeData = extend({}, droppedRecord);
1536
- delete parentItem.childRecords;
1537
- draggedRecord.parentItem = parentItem;
1538
- draggedRecord.parentUniqueID = droppedRecord.uniqueID;
1539
- droppedRecord.childRecords.splice(droppedRecord.childRecords.length, 0, draggedRecord);
1540
- setValue('uniqueIDCollection.' + draggedRecord.uniqueID, draggedRecord, tObj);
1541
- const isSelfReference: string = 'isSelfReference';
1542
- if (tObj[`${isSelfReference}`]) {
1543
- droppedRecord[tObj.childMapping] = [];
1544
- droppedRecord[tObj.childMapping].splice(droppedRecord[tObj.childMapping].length, 0, draggedRecord);
1545
- }
1546
- if (!isNullOrUndefined(draggedRecord) && !tObj.parentIdMapping && !isNullOrUndefined(droppedRecord.taskData[`${childItem}`])) {
1547
- droppedRecord.taskData[tObj.childMapping].splice(droppedRecord.childRecords.length, 0, draggedRecord.taskData);
1548
- }
1549
- if (!draggedRecord.hasChildRecords) {
1550
- draggedRecord.level = droppedRecord.level + 1;
1551
- } else {
1552
- const level: number = 1;
1553
- draggedRecord.level = droppedRecord.level + 1;
1554
- this.updateChildRecordLevel(draggedRecord, level);
1555
- }
1556
- droppedRecord.expanded = true;
1557
- }
1558
- }
1559
-
1560
- /**
1561
- * Deletes the currently dragged row from the TreeGrid.
1562
- *
1563
- * @returns {void} - This function does not return any value.
1564
- */
1565
- private deleteDragRow(): void {
1566
- if (this.parent.dataSource instanceof DataManager && isOffline(this.parent)) {
1567
- this.treeGridData = (<DataManager>this.parent.grid.dataSource).dataSource.json;
1568
- this.treeData = (<DataManager>this.parent.dataSource).dataSource.json;
1569
- } else {
1570
- this.treeGridData = this.parent.grid.dataSource as ITreeData[];
1571
- this.treeData = this.parent.dataSource as ITreeData[];
1572
- }
1573
- const deletedRow: ITreeData = getParentData(this.parent, this.draggedRecord.uniqueID);
1574
- if (!isNullOrUndefined(deletedRow.childRecords) && deletedRow.childRecords.length) {
1575
- deletedRow.hasChildRecords = true;
1576
- }
1577
- this.removeRecords(deletedRow);
1578
- }
1579
-
1580
- /**
1581
- * Updates the child records of a specified parent record in the TreeGrid.
1582
- *
1583
- * @param {ITreeData} record - The parent record whose child records will be updated.
1584
- * @param {number} count - The initial count to keep track of record positioning.
1585
- * @returns {number} - The updated count after processing all child records.
1586
- */
1587
- private updateChildRecord(record: ITreeData, count: number): number {
1588
- let currentRecord: ITreeData;
1589
- const tObj: TreeGrid = this.parent;
1590
- let length: number = 0;
1591
- if (!record.hasChildRecords) {
1592
- return 0;
1593
- }
1594
- length = record.childRecords.length;
1595
- for (let i: number = 0; i < length; i++) {
1596
- if (!this.isMultipleGrid) {
1597
- currentRecord = getValue('uniqueIDCollection.' + record.childRecords[parseInt(i.toString(), 10)].uniqueID, tObj);
1598
- } else {
1599
- currentRecord = record.childRecords[parseInt(i.toString(), 10)];
1600
- }
1601
- count++;
1602
- tObj.flatData.splice(count, 0, currentRecord);
1603
- setValue('uniqueIDCollection.' + currentRecord.uniqueID, currentRecord, this.parent);
1604
- if (tObj.parentIdMapping) {
1605
- this.treeData.splice(count, 0, currentRecord.taskData);
1606
- }
1607
- if (currentRecord.hasChildRecords) {
1608
- count = this.updateChildRecord(currentRecord, count);
1609
- }
1610
- }
1611
- return count;
1612
- }
1613
-
1614
- /**
1615
- * Updates the level of child records for a specified parent record in the TreeGrid.
1616
- *
1617
- * @param {ITreeData} record - The parent record whose child records' levels will be updated.
1618
- * @param {number} level - The current level of the parent record.
1619
- * @returns {number} - The updated level after processing all child records.
1620
- */
1621
- private updateChildRecordLevel(record: ITreeData, level: number): number {
1622
- let length: number = 0;
1623
- let currentRecord: ITreeData;
1624
- level++;
1625
- if (!record.hasChildRecords) {
1626
- return 0;
1627
- }
1628
- length = record.childRecords.length;
1629
- for (let i: number = 0; i < length; i++) {
1630
- if (!this.isMultipleGrid) {
1631
- currentRecord = getValue('uniqueIDCollection.' + record.childRecords[parseInt(i.toString(), 10)].uniqueID, this.parent);
1632
- } else {
1633
- currentRecord = record.childRecords[parseInt(i.toString(), 10)];
1634
- }
1635
- let parentData: ITreeData;
1636
- if (record.parentItem) {
1637
- parentData = getParentData(this.parent, record.parentItem.uniqueID);
1638
- }
1639
- if (isNullOrUndefined(parentData) && !isNullOrUndefined(record.parentItem)) { parentData = record.parentItem; }
1640
- currentRecord.level = record.parentItem ? parentData.level + level : record.level + 1;
1641
- if (currentRecord.hasChildRecords) {
1642
- level--;
1643
- level = this.updateChildRecordLevel(currentRecord, level);
1644
- }
1645
- }
1646
- return level;
1647
- }
1648
-
1649
- /**
1650
- * Removes specified records from the TreeGrid data source.
1651
- *
1652
- * @param {ITreeData} record - The record to be removed, including any child records if applicable.
1653
- * @returns {void} - This method does not return a value.
1654
- */
1655
- private removeRecords(record: ITreeData): void {
1656
- const tObj: TreeGrid = this.parent;
1657
- let dataSource: Object;
1658
- if (this.parent.dataSource instanceof DataManager && isOffline(this.parent)) {
1659
- dataSource = (<DataManager>this.parent.dataSource).dataSource.json;
1660
- } else {
1661
- dataSource = this.parent.dataSource;
1662
- }
1663
- const deletedRow: ITreeData = record;
1664
- const isSelfReference: boolean = !isNullOrUndefined(tObj.parentIdMapping);
1665
- const flatParentData: ITreeData = (this.getChildrecordsByParentID(deletedRow.parentUniqueID) as ITreeData)[0];
1666
- if (deletedRow) {
1667
- if (deletedRow.parentItem) {
1668
- const childRecords: ITreeData[] = flatParentData ? flatParentData.childRecords : [];
1669
- let childIndex: number = 0;
1670
- if (childRecords && childRecords.length > 0) {
1671
- childIndex = childRecords.indexOf(deletedRow);
1672
- flatParentData.childRecords.splice(childIndex, 1);
1673
- if (!this.parent.parentIdMapping || tObj.enableImmutableMode) {
1674
- editAction({ value: deletedRow, action: 'delete' }, this.parent,
1675
- isSelfReference, deletedRow.index, deletedRow.index);
1676
- }
1677
- }
1678
- }
1679
- if (tObj.parentIdMapping) {
1680
- if (deletedRow.hasChildRecords && deletedRow.childRecords.length > 0) {
1681
- this.removeChildItem(deletedRow);
1682
- }
1683
- const treeGridData: ITreeData[] = dataSource as ITreeData[];
1684
- const idx: number = treeGridData.findIndex((data: ITreeData) => {
1685
- return data[this.parent.idMapping] === deletedRow.taskData[this.parent.idMapping];
1686
- });
1687
- const idz: number = this.treeGridData.findIndex((data: ITreeData) => {
1688
- return data[this.parent.idMapping] === deletedRow.taskData[this.parent.idMapping];
1689
- });
1690
- if (idx !== -1 && !isNullOrUndefined(idx)) {
1691
- (dataSource as ITreeData[]).splice(idx, 1);
1692
- }
1693
- if (idz !== -1 && !isNullOrUndefined(idz)) {
1694
- this.treeGridData.splice(idz, 1);
1695
- }
1696
- }
1697
- let recordIndex: number = this.treeGridData.indexOf(deletedRow);
1698
- if (!tObj.parentIdMapping) {
1699
- const parentIndex: number = this.parent.parentData.indexOf(deletedRow);
1700
- if (parentIndex !== -1) {
1701
- tObj.parentData.splice(parentIndex, 1);
1702
- (dataSource as ITreeData[]).splice(parentIndex, 1);
1703
- }
1704
- }
1705
- if (recordIndex === -1 && !tObj.parentIdMapping) {
1706
- const primaryKeyField: string = tObj.getPrimaryKeyFieldNames()[0];
1707
- for (let j: number = 0; j < this.treeGridData.length; j++) {
1708
- if (this.treeGridData[parseInt(j.toString(), 10)][`${primaryKeyField}`] === deletedRow[`${primaryKeyField}`]) {
1709
- recordIndex = j;
1710
- }
1711
- }
1712
- }
1713
- if (!tObj.parentIdMapping) {
1714
- const deletedRecordCount: number = this.getChildCount(deletedRow, 0);
1715
- this.treeGridData.splice(recordIndex, deletedRecordCount + 1);
1716
- }
1717
- if (deletedRow.parentItem && flatParentData && flatParentData.childRecords && !flatParentData.childRecords.length) {
1718
- flatParentData.expanded = false;
1719
- flatParentData.hasChildRecords = false;
1720
- flatParentData.hasFilteredChildRecords = false;
1721
- }
1722
- if (this.parent[this.modifiedRecords].indexOf(flatParentData) === -1 && !isNullOrUndefined(flatParentData)) {
1723
- this.parent[this.modifiedRecords].push(flatParentData);
1724
- }
1725
- if (!isNullOrUndefined(flatParentData)) {
1726
- this.updateModifiedRecords(flatParentData);
1727
- }
1728
- }
1729
- }
1730
-
1731
- /**
1732
- * Updates the records in the TreeGrid data source that have been modified.
1733
- *
1734
- * @param {ITreeData} record - The record to update, along with its parent records if applicable.
1735
- * @returns {void} - This method does not return a value.
1736
- */
1737
- private updateModifiedRecords(record: ITreeData): void {
1738
- const parentData: Object = getParentData(this.parent, record.parentUniqueID);
1739
- if (!isNullOrUndefined(parentData)) {
1740
- this.parent[this.modifiedRecords].push(parentData);
1741
- this.updateModifiedRecords(parentData);
1742
- }
1743
- }
1744
-
1745
- /**
1746
- * Recursively removes child records from the specified record and updates the data source.
1747
- *
1748
- * @param {ITreeData} record - The parent record whose child records are to be removed.
1749
- * @returns {void} - This method does not return a value.
1750
- */
1751
- private removeChildItem(record: ITreeData): void {
1752
- let currentRecord: ITreeData;
1753
- let idx: number;
1754
- let idz: number;
1755
- let dataSource: Object;
1756
- if (this.parent.dataSource instanceof DataManager && isOffline(this.parent)) {
1757
- dataSource = (<DataManager>this.parent.dataSource).dataSource.json;
1758
- } else {
1759
- dataSource = this.parent.dataSource;
1760
- }
1761
- for (let i: number = 0; i < record.childRecords.length; i++) {
1762
- currentRecord = record.childRecords[parseInt(i.toString(), 10)];
1763
- if (!isNullOrUndefined(currentRecord.childRecords) && currentRecord.childRecords.length) {
1764
- currentRecord.hasChildRecords = true;
1765
- }
1766
- let treeGridData: Object;
1767
- if (this.parent.dataSource instanceof DataManager && isOffline(this.parent)) {
1768
- treeGridData = (<DataManager>this.parent.dataSource).dataSource.json;
1769
- } else {
1770
- treeGridData = this.parent.dataSource;
1771
- }
1772
- for (let i: number = 0; i < (<ITreeData[]>treeGridData).length; i++) {
1773
- if (treeGridData[parseInt(i.toString(), 10)][this.parent.idMapping] === currentRecord.taskData[this.parent.idMapping]) {
1774
- idx = i;
1775
- }
1776
- }
1777
- for (let i: number = 0; i < this.treeGridData.length; i++) {
1778
- if (this.treeGridData[parseInt(i.toString(), 10)][this.parent.idMapping]
1779
- === currentRecord.taskData[this.parent.idMapping]) {
1780
- idz = i;
1781
- break;
1782
- }
1783
- }
1784
- if (idx !== -1 && !isNullOrUndefined(idx)) {
1785
- (dataSource as ITreeData[]).splice(idx, 1);
1786
- }
1787
- if (idz !== -1 && !isNullOrUndefined(idz)) {
1788
- this.treeGridData.splice(idz, 1);
1789
- }
1790
- if (currentRecord.hasChildRecords) {
1791
- this.removeChildItem(currentRecord);
1792
- }
1793
- }
1794
- }
1795
-
1796
- /**
1797
- * Retrieves the count of child records associated with the specified parent record.
1798
- *
1799
- * @param {ITreeData} record - The parent record for which child count is to be calculated.
1800
- * @param {number} count - The initial count to start with, usually passed as 0.
1801
- * @returns {number} - The total count of child records.
1802
- */
1803
- private getChildCount(record: ITreeData, count: number): number {
1804
- let currentRecord: ITreeData;
1805
- if (!record.hasChildRecords) {
1806
- return 0;
1807
- }
1808
- for (let i: number = 0; i < record.childRecords.length; i++) {
1809
- currentRecord = record.childRecords[parseInt(i.toString(), 10)];
1810
- count++;
1811
- if (currentRecord.hasChildRecords) {
1812
- count = this.getChildCount(currentRecord, count);
1813
- }
1814
- }
1815
- return count;
1816
- }
1817
-
1818
- /**
1819
- * Ensures the validity of the drop position for the dragged records by verifying the hierarchy and position constraints.
1820
- * If the current record is found in the dragged records' children, sets the drop position to 'Invalid'.
1821
- *
1822
- * @param {ITreeData[]} draggedRecords - The array of dragged records being verified.
1823
- * @param {ITreeData} currentRecord - The current record to check against dragged records.
1824
- * @returns {void} - This function does not return a value.
1825
- */
1826
- private ensuredropPosition(draggedRecords: ITreeData[], currentRecord: ITreeData): void {
1827
- draggedRecords.filter((e: ITreeData) => {
1828
- if (e.hasChildRecords && !isNullOrUndefined(e.childRecords)) {
1829
- const valid: number = e.childRecords.indexOf(currentRecord);
1830
- if (valid === -1) {
1831
- this.ensuredropPosition(e.childRecords, currentRecord);
1832
- } else {
1833
- this.dropPosition = 'Invalid';
1834
- this.addErrorElem();
1835
- this.canDrop = false;
1836
- if (isNullOrUndefined(this.parent.rowDropSettings.targetID)) {
1837
- this.removetopOrBottomBorder();
1838
- this.removeChildBorder();
1839
- }
1840
- return;
1841
- }
1842
- }
1843
- });
1844
- }
1845
-
1846
- private isDuplicateData(currentData: any): boolean {
1847
- const primaryKeys: string[] = this.parent.getPrimaryKeyFieldNames();
1848
- if (primaryKeys.length === 0) {
1849
- return false;
1850
- }
1851
- return this.parent.flatData.some((data: any) =>
1852
- // eslint-disable-next-line
1853
- primaryKeys.every((key: string) => data[key] === currentData[key])
1854
- );
1855
- }
1856
-
1857
- /**
1858
- * Cleans up resources, event listeners, and DOM elements when the TreeGrid component is destroyed.
1859
- *
1860
- * @returns {void}
1861
- */
1862
- public destroy(): void {
1863
- this.removeEventListener();
1864
- }
1865
-
1866
- /**
1867
- * @hidden
1868
- * @returns {void}
1869
- */
1870
- public removeEventListener(): void {
1871
- if (this.parent.isDestroyed) { return; }
1872
- this.parent.off(events.rowdraging, this.Rowdraging);
1873
- this.parent.off(events.rowDropped, this.rowDropped);
1874
- this.parent.off(events.rowsAdd, this.rowsAdded);
1875
- this.parent.off(events.rowsRemove, this.rowsRemoved);
1876
- }
1877
- /**
1878
- * hidden
1879
- */
1880
- /**
1881
- * For internal use only - Get the module name.
1882
- *
1883
- * @private
1884
- * @returns {string} Returns RowDragAndDrop module name
1885
- */
1886
- private getModuleName(): string {
1887
- return 'rowDragAndDrop';
1888
- }
1889
- }
1890
-
1891
-
1892
- interface PositionOffSet {
1893
- left: number;
1894
- top: number;
1895
- }
1896
-