@syncfusion/ej2-treegrid 32.2.9 → 33.1.45

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 (33) 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 +237 -70
  5. package/dist/es6/ej2-treegrid.es2015.js.map +1 -1
  6. package/dist/es6/ej2-treegrid.es5.js +244 -71
  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 +5 -5
  12. package/src/treegrid/actions/batch-edit.js +1 -1
  13. package/src/treegrid/actions/edit.js +3 -0
  14. package/src/treegrid/actions/filter.js +20 -0
  15. package/src/treegrid/actions/rowdragdrop.js +17 -4
  16. package/src/treegrid/actions/virtual-scroll.js +2 -1
  17. package/src/treegrid/base/data.js +2 -33
  18. package/src/treegrid/base/treegrid-model.d.ts +1 -1
  19. package/src/treegrid/base/treegrid.d.ts +34 -0
  20. package/src/treegrid/base/treegrid.js +124 -4
  21. package/src/treegrid/renderer/render.js +15 -0
  22. package/src/treegrid/renderer/virtual-tree-content-render.d.ts +4 -5
  23. package/src/treegrid/renderer/virtual-tree-content-render.js +62 -29
  24. package/styles/fluent2.css +1 -0
  25. package/styles/material3-dark-lite.css +2 -2
  26. package/styles/material3-dark.css +2 -2
  27. package/styles/material3-lite.css +2 -2
  28. package/styles/material3.css +2 -2
  29. package/styles/treegrid/_bigger.scss +3 -0
  30. package/styles/treegrid/fluent2.css +1 -0
  31. package/styles/treegrid/icons/_material3.scss +2 -2
  32. package/styles/treegrid/material3-dark.css +2 -2
  33. package/styles/treegrid/material3.css +2 -2
@@ -1,5 +1,5 @@
1
1
  import { merge, Property, ChildProperty, Collection, isNullOrUndefined, Browser, removeClass, addClass, getValue, createElement, setValue, extend as extend$1, Internationalization, getEnumValue, compile, Component, L10n, EventHandler, KeyboardEvents, SanitizeHtmlHelper, Complex, Event, NotifyPropertyChanges, closest, setStyleAttribute, select, classList, debounce, remove } from '@syncfusion/ej2-base';
2
- import { Logger as Logger$1, Grid, detailLists, Clipboard, getObject, parentsUntil, Print as Print$1, templateCompiler, appendChildren, extend, CellRenderer, getUid, CellType, Freeze as Freeze$1, getNumberFormat, getActualProperties, iterateArrayOrObject, RowDropSettings as RowDropSettings$1, Reorder as Reorder$1, Resize as Resize$1, RowDD as RowDD$1, Scroll, VirtualRowModelGenerator, Filter as Filter$1, ExcelExport as ExcelExport$1, Data, ExportHelper, PdfExport as PdfExport$1, Page as Page$1, Toolbar as Toolbar$1, Aggregate as Aggregate$1, calculateAggregate, Sort as Sort$1, ColumnMenu as ColumnMenu$1, ContextMenu as ContextMenu$1, Edit as Edit$1, resetRowIndex, CommandColumn as CommandColumn$1, DetailRow as DetailRow$1, VirtualContentRenderer, Cell, getVisiblePage, InterSectionObserver, getTransformValues, VirtualScroll as VirtualScroll$1, RenderType, VirtualHeaderRenderer, ColumnChooser as ColumnChooser$1, InfiniteScroll as InfiniteScroll$1, getRowIndexFromElement, RowRenderer } from '@syncfusion/ej2-grids';
2
+ import { Logger as Logger$1, Grid, detailLists, Clipboard, getObject, parentsUntil, Print as Print$1, templateCompiler, appendChildren, extend, CellRenderer, getUid, CellType, Freeze as Freeze$1, getNumberFormat, setEnableSeamlessScrolling, getActualProperties, iterateArrayOrObject, RowDropSettings as RowDropSettings$1, Reorder as Reorder$1, Resize as Resize$1, RowDD as RowDD$1, Scroll, VirtualRowModelGenerator, Filter as Filter$1, ExcelExport as ExcelExport$1, Data, ExportHelper, PdfExport as PdfExport$1, Page as Page$1, Toolbar as Toolbar$1, Aggregate as Aggregate$1, calculateAggregate, Sort as Sort$1, ColumnMenu as ColumnMenu$1, ContextMenu as ContextMenu$1, Edit as Edit$1, resetRowIndex, CommandColumn as CommandColumn$1, DetailRow as DetailRow$1, VirtualContentRenderer, Cell, getVisiblePage, InterSectionObserver, getTransformValues, VirtualScroll as VirtualScroll$1, RenderType, VirtualHeaderRenderer, ColumnChooser as ColumnChooser$1, InfiniteScroll as InfiniteScroll$1, getRowIndexFromElement, RowRenderer } from '@syncfusion/ej2-grids';
3
3
  import { createCheckBox } from '@syncfusion/ej2-buttons';
4
4
  import { DataManager, ODataAdaptor, WebApiAdaptor, WebMethodAdaptor, CacheAdaptor, UrlAdaptor, Query, DataUtil, RemoteSaveAdaptor, Deferred, JsonAdaptor, Predicate as Predicate$1 } from '@syncfusion/ej2-data';
5
5
  import { showSpinner, hideSpinner, createSpinner } from '@syncfusion/ej2-popups';
@@ -2019,6 +2019,16 @@ class Render {
2019
2019
  }
2020
2020
  const data = args.data;
2021
2021
  const parentData = data.parentItem;
2022
+ if (!isNullOrUndefined(parentData) && data.isCollapsedChild && !isNullOrUndefined(args.row)) {
2023
+ this.parent['toggleRowVisibility'](args.row, 'e-childrow-hidden');
2024
+ const rowsObj = this.parent.grid.getRowsObject();
2025
+ if (!this.parent.grid.isFrozenGrid() && !isNullOrUndefined(args.row.getAttribute('data-uid'))) {
2026
+ const row = rowsObj.filter((e) => e.uid === args.row.getAttribute('data-uid'))[0];
2027
+ if (row) {
2028
+ row.visible = false;
2029
+ }
2030
+ }
2031
+ }
2022
2032
  if (!isNullOrUndefined(data.parentItem) && !isFilterChildHierarchy(this.parent) &&
2023
2033
  (!(this.parent.allowPaging && !(this.parent.pageSettings.pageSizeMode === 'Root')) ||
2024
2034
  (isRemoteData(this.parent) && !isOffline(this.parent)))) {
@@ -2047,6 +2057,11 @@ class Render {
2047
2057
  const summaryRow = getObject('isSummaryRow', args.data);
2048
2058
  if (summaryRow) {
2049
2059
  addClass([args.row], 'e-summaryrow');
2060
+ const isDragandDropCell = args.row.querySelector('.e-rowdragdrop') || args.row.querySelector('.e-rowdragdrop.e-dragging');
2061
+ if (isDragandDropCell) {
2062
+ args.row.cells[0].className = 'e-rowcell e-summarycell';
2063
+ args.row.cells[0].innerHTML = '';
2064
+ }
2050
2065
  }
2051
2066
  if (!isNullOrUndefined(args.row)) {
2052
2067
  if (args.row.querySelector('.e-treegridexpand')) {
@@ -3136,7 +3151,6 @@ class DataManipulation {
3136
3151
  let results = dataObj instanceof DataManager ? dataObj.dataSource.json : dataObj;
3137
3152
  let count = isCountRequired(this.parent) ? getValue('count', this.parent.dataSource)
3138
3153
  : results.length;
3139
- const qry = new Query();
3140
3154
  let gridQuery = getObject('query', args);
3141
3155
  let filterQuery;
3142
3156
  let searchQuery;
@@ -3152,11 +3166,7 @@ class DataManipulation {
3152
3166
  gridQuery = getValue('grid.renderModule.data', this.parent).filterQuery(gridQuery);
3153
3167
  gridQuery = getValue('grid.renderModule.data', this.parent).searchQuery(gridQuery);
3154
3168
  }
3155
- const fltrQuery = gridQuery.queries.filter((q) => q.fn === 'onWhere');
3156
- const srchQuery = gridQuery.queries.filter((q) => q.fn === 'onSearch');
3157
- qry.queries = fltrQuery.concat(srchQuery);
3158
- const filteredData = new DataManager(results).executeLocal(qry);
3159
- this.parent.notify('updateFilterRecs', { data: filteredData });
3169
+ this.parent.getData({ query: gridQuery, isFilter: true });
3160
3170
  results = this.dataResults.result;
3161
3171
  this.dataResults.result = null;
3162
3172
  if (this.parent.grid.aggregates.length > 0) {
@@ -3181,34 +3191,8 @@ class DataManipulation {
3181
3191
  }
3182
3192
  if (this.parent.grid.sortSettings.columns.length > 0 || this.isSortAction) {
3183
3193
  this.isSortAction = false;
3184
- const parentData = this.parent.parentData;
3185
3194
  const query = getObject('query', args);
3186
- const srtQry = new Query();
3187
- for (let srt = this.parent.grid.sortSettings.columns.length - 1; srt >= 0; srt--) {
3188
- const getColumnByField = 'getColumnByField';
3189
- const col = this.parent.grid.renderModule.data[`${getColumnByField}`](this.parent.grid.
3190
- sortSettings.columns[parseInt(srt.toString(), 10)].field);
3191
- const compFun = col.sortComparer && isOffline(this.parent) ?
3192
- col.sortComparer.bind(col) :
3193
- this.parent.grid.sortSettings.columns[parseInt(srt.toString(), 10)].direction;
3194
- srtQry.sortBy(this.parent.grid.sortSettings.columns[parseInt(srt.toString(), 10)].field, compFun);
3195
- }
3196
- const modifiedData = new DataManager(parentData).executeLocal(srtQry);
3197
- if (this.parent.allowRowDragAndDrop && !isNullOrUndefined(this.parent.rowDragAndDropModule['draggedRecord']) &&
3198
- this.parent.rowDragAndDropModule['droppedRecord'].hasChildRecords && this.parent.rowDragAndDropModule['dropPosition'] !== 'middleSegment') {
3199
- const dragdIndex = modifiedData.indexOf(this.parent.rowDragAndDropModule['draggedRecord']);
3200
- modifiedData.splice(dragdIndex, 1);
3201
- const dropdIndex = modifiedData.indexOf(this.parent.rowDragAndDropModule['droppedRecord']);
3202
- if (this.parent.rowDragAndDropModule['droppedRecord'].hasChildRecords && this.parent.rowDragAndDropModule['dropPosition'] === 'topSegment') {
3203
- modifiedData.splice(dropdIndex, 0, this.parent.rowDragAndDropModule['draggedRecord']);
3204
- }
3205
- else if (this.parent.rowDragAndDropModule['dropPosition'] === 'bottomSegment') {
3206
- modifiedData.splice(dropdIndex + 1, 0, this.parent.rowDragAndDropModule['draggedRecord']);
3207
- }
3208
- }
3209
- const sortArgs = { modifiedData: modifiedData, filteredData: results, srtQry: srtQry };
3210
- this.parent.notify('createSort', sortArgs);
3211
- results = sortArgs.modifiedData;
3195
+ results = this.parent.getData({ query: query, isSort: true });
3212
3196
  this.dataResults.result = null;
3213
3197
  this.sortedData = results;
3214
3198
  this.parent.notify('updateModel', {});
@@ -4038,6 +4022,8 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
4038
4022
  this.isComponentRefresh = false;
4039
4023
  this.isVirtualExpandCollapse = false;
4040
4024
  this.isInfiniteCollapse = false;
4025
+ /** @hidden */
4026
+ this.enableSeamlessScrolling = false;
4041
4027
  this.objectEqualityChecker = (old, current) => {
4042
4028
  if (old) {
4043
4029
  const keys = Object.keys(old);
@@ -4781,7 +4767,15 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
4781
4767
  this.renderModule = new Render(this);
4782
4768
  this.dataModule = new DataManipulation(this);
4783
4769
  this.printModule = new Print(this);
4784
- this.trigger(load);
4770
+ if (this.enableVirtualization || this.enableColumnVirtualization) {
4771
+ const args = { enableSeamlessScrolling: this.enableSeamlessScrolling };
4772
+ this.trigger(load, args);
4773
+ this.enableSeamlessScrolling = args.enableSeamlessScrolling;
4774
+ setEnableSeamlessScrolling(this.enableSeamlessScrolling);
4775
+ }
4776
+ else {
4777
+ this.trigger(load);
4778
+ }
4785
4779
  this.autoGenerateColumns();
4786
4780
  this.initialRender = true;
4787
4781
  if (!isNullOrUndefined(this.dataSource)) {
@@ -5047,6 +5041,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
5047
5041
  this.grid.clipMode = getActualProperties(this.clipMode);
5048
5042
  this.grid.enableColumnSpan = this.enableColumnSpan;
5049
5043
  this.grid.enableRowSpan = this.enableRowSpan;
5044
+ this.grid.enableSeamlessScrolling = this.enableSeamlessScrolling;
5050
5045
  const templateInstance = 'templateDotnetInstance';
5051
5046
  this.grid[`${templateInstance}`] = this[`${templateInstance}`];
5052
5047
  const isJsComponent = 'isJsComponent';
@@ -5518,7 +5513,7 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
5518
5513
  }
5519
5514
  this.notify('updateGridActions', args);
5520
5515
  this.isVirtualExpandCollapse = false;
5521
- if (args.requestType === 'save' && this.aggregates.map((ag) => ag.showChildSummary === true).length) {
5516
+ if (args.requestType === 'save' && this.aggregates.some((ag) => ag.showChildSummary === true)) {
5522
5517
  this.grid.refresh();
5523
5518
  }
5524
5519
  if ((args.action === 'clearFilter' || args.action === 'clear-filter' || args.requestType === 'sorting') && this.enableInfiniteScrolling) {
@@ -6257,6 +6252,114 @@ let TreeGrid = TreeGrid_1 = class TreeGrid extends Component {
6257
6252
  }
6258
6253
  }
6259
6254
  }
6255
+ /**
6256
+ * Retrieves all records that match the current search criteria and are sorted according to the active sort settings.
6257
+ *
6258
+ * This method processes the data source by applying search filters and sort operations,
6259
+ * returning the searched and sorted records excluding summary rows.
6260
+ *
6261
+ * @param {Object} args - Optional arguments object to control query execution behavior.
6262
+ * @param {Query} args.query - Optional custom Query object to override the default generated query.
6263
+ * @param {boolean} args.isFilter - Optional flag to include only filtered records without sorting (default: false).
6264
+ * @param {boolean} args.isSort - Optional flag to apply only sorting without filtering (default: false).
6265
+ *
6266
+ * @returns {ITreeData[]} - Array of searched and sorted TreeGrid records with summary rows excluded.
6267
+ * @hidden
6268
+ */
6269
+ getData(args) {
6270
+ const dataObj = isCountRequired(this) ? getValue('result', this.grid.dataSource)
6271
+ : this.grid.dataSource;
6272
+ let results = dataObj instanceof DataManager ? dataObj.dataSource.json : dataObj;
6273
+ const gridQuery = (!isNullOrUndefined(args) && args.query) ? args.query : this.getDataModule().baseModule.generateQuery();
6274
+ let filterQuery;
6275
+ let searchQuery;
6276
+ if (!isNullOrUndefined(gridQuery)) {
6277
+ filterQuery = gridQuery.queries.filter((q) => q.fn === 'onWhere');
6278
+ searchQuery = gridQuery.queries.filter((q) => q.fn === 'onSearch');
6279
+ }
6280
+ const skipFilterSearch = (!isNullOrUndefined(args) && args.isSort);
6281
+ if (!skipFilterSearch && (this.grid.allowFiltering && this.grid.filterSettings.columns.length) ||
6282
+ (this.grid.searchSettings.key.length > 0) && (!isNullOrUndefined(gridQuery))
6283
+ || ((filterQuery && filterQuery.length > 0) || (searchQuery && searchQuery.length > 0))) {
6284
+ const filterQuery = gridQuery.queries.filter((q) => q.fn === 'onWhere');
6285
+ const searchQuery = gridQuery.queries.filter((q) => q.fn === 'onSearch');
6286
+ const query = new Query();
6287
+ query.queries = filterQuery.concat(searchQuery);
6288
+ const filteredData = new DataManager(results).executeLocal(query);
6289
+ this.notify('updateFilterRecs', { data: filteredData });
6290
+ results = isRemoteData(this) ? this.dataResults : this.filterModule.filteredResult;
6291
+ if (!isNullOrUndefined(args) && args.isFilter) {
6292
+ return isRemoteData(this) ? results.result.filter((item) => !item.isSummaryRow)
6293
+ : results.filter((item) => !item.isSummaryRow);
6294
+ }
6295
+ }
6296
+ const sortQuery = gridQuery.queries.filter((q) => q.fn === 'onSortBy');
6297
+ if (this.grid.sortSettings.columns.length > 0 || sortQuery.length) {
6298
+ const parentData = this.parentData;
6299
+ const query = new Query();
6300
+ query.queries = sortQuery;
6301
+ const modifiedData = new DataManager(parentData).executeLocal(query);
6302
+ if (this.allowRowDragAndDrop && !isNullOrUndefined(this.rowDragAndDropModule['draggedRecord']) &&
6303
+ this.rowDragAndDropModule['droppedRecord'].hasChildRecords && this.rowDragAndDropModule['dropPosition'] !== 'middleSegment') {
6304
+ const dragdIndex = modifiedData.indexOf(this.rowDragAndDropModule['draggedRecord']);
6305
+ modifiedData.splice(dragdIndex, 1);
6306
+ const dropdIndex = modifiedData.indexOf(this.rowDragAndDropModule['droppedRecord']);
6307
+ if (this.rowDragAndDropModule['droppedRecord'].hasChildRecords && this.rowDragAndDropModule['dropPosition'] === 'topSegment') {
6308
+ modifiedData.splice(dropdIndex, 0, this.rowDragAndDropModule['draggedRecord']);
6309
+ }
6310
+ else if (this.rowDragAndDropModule['dropPosition'] === 'bottomSegment') {
6311
+ modifiedData.splice(dropdIndex + 1, 0, this.rowDragAndDropModule['draggedRecord']);
6312
+ }
6313
+ }
6314
+ const sortArgs = { modifiedData: modifiedData, filteredData: results, srtQry: query };
6315
+ this.notify('createSort', sortArgs);
6316
+ results = isRemoteData(this) ? this.dataResults : sortArgs.modifiedData;
6317
+ }
6318
+ return isRemoteData(this) ? this.dataResults.result.filter((item) => !item.isSummaryRow)
6319
+ : results.filter((item) => !item.isSummaryRow);
6320
+ }
6321
+ /**
6322
+ * Retrieves the processed Tree Grid data based on current operations such as
6323
+ * sorting, filtering, and searching. Maintains hierarchy and current structure.
6324
+ *
6325
+ * For local data: when skipPage is true (the default), it returns all available records;
6326
+ * when skipPage is false, it returns only the records for the current page.
6327
+ * For remote data: it always returns only the records for the current page.
6328
+ *
6329
+ * @param {boolean} skipPage - if set to false, returns only the records for the current page.
6330
+ * @returns {ITreeData[]} - Array of tree records (summary rows excluded).
6331
+ * @hidden
6332
+ */
6333
+ getProcessedRecords(skipPage) {
6334
+ let result;
6335
+ if (skipPage !== true || isRemoteData(this)) {
6336
+ result = this.getData();
6337
+ const dm = new DataManager(result);
6338
+ const expanded = new Predicate$1('expanded', 'notequal', null).or('expanded', 'notequal', undefined);
6339
+ const parents = dm.executeLocal(new Query().where(expanded));
6340
+ const visualData = parents.filter((e) => {
6341
+ return getExpandStatus(this, e);
6342
+ });
6343
+ let query = new Query();
6344
+ if (this.allowPaging || this.enableVirtualization || this.enableInfiniteScrolling) {
6345
+ const pageSize = this.grid.pageSettings.pageSize;
6346
+ let currentPage = this.grid.pageSettings.currentPage;
6347
+ if (visualData.length < (currentPage * pageSize)) {
6348
+ currentPage = (Math.floor(visualData.length / pageSize)) + ((visualData.length % pageSize) ? 1 : 0);
6349
+ currentPage = currentPage ? currentPage : 1;
6350
+ this.grid.setProperties({ pageSettings: { currentPage: currentPage } }, true);
6351
+ }
6352
+ const skip = pageSize * (currentPage - 1);
6353
+ query = query.skip(skip).take(pageSize);
6354
+ }
6355
+ dm.dataSource.json = visualData;
6356
+ result = dm.executeLocal(query);
6357
+ }
6358
+ else {
6359
+ result = this.getData();
6360
+ }
6361
+ return result;
6362
+ }
6260
6363
  /**
6261
6364
  * Retrieves all the TreeGrid row elements.
6262
6365
  *
@@ -9637,8 +9740,10 @@ class RowDD {
9637
9740
  const record = this.getChildrecordsByParentID(droppedRecord.parentUniqueID)[0];
9638
9741
  const childRecords = record.childRecords;
9639
9742
  for (let i = 0; i < childRecords.length; i++) {
9640
- droppedRecord.parentItem.taskData[this.parent.childMapping][parseInt(i.toString(), 10)]
9641
- = childRecords[parseInt(i.toString(), 10)].taskData;
9743
+ if (!isNullOrUndefined(childRecords[parseInt(i.toString(), 10)].taskData)) {
9744
+ droppedRecord.parentItem.taskData[this.parent.childMapping][parseInt(i.toString(), 10)]
9745
+ = childRecords[parseInt(i.toString(), 10)].taskData;
9746
+ }
9642
9747
  }
9643
9748
  }
9644
9749
  }
@@ -10222,6 +10327,11 @@ class RowDD {
10222
10327
  * @returns {void} This function does not return a value.
10223
10328
  */
10224
10329
  rowDropped(args) {
10330
+ if (!isNullOrUndefined(this.parent.aggregates[0]) && this.parent.aggregates[0].showChildSummary) {
10331
+ const records = this.parent.grid.getCurrentViewRecords();
10332
+ args.fromIndex = records[args.fromIndex].index;
10333
+ args.dropIndex = records[args.dropIndex].index;
10334
+ }
10225
10335
  const tObj = this.parent;
10226
10336
  const parentItem = 'parentItem';
10227
10337
  if (!tObj.rowDropSettings.targetID) {
@@ -10448,7 +10558,13 @@ class RowDD {
10448
10558
  const rowIndex = tObj.selectedRowIndex === -1 ?
10449
10559
  (this.parent.grid.getRowIndexByPrimaryKey(args.data[0][`${primaryKeyField}`])) - 1
10450
10560
  : tObj.getSelectedRowIndexes()[0] - 1;
10451
- const record = tObj.getCurrentViewRecords()[parseInt(rowIndex.toString(), 10)];
10561
+ let record;
10562
+ if (this.parent.enableVirtualization) {
10563
+ record = tObj.getCurrentViewRecords().find((e) => e.index === rowIndex);
10564
+ }
10565
+ else {
10566
+ record = tObj.getCurrentViewRecords()[parseInt(rowIndex.toString(), 10)];
10567
+ }
10452
10568
  this.getParentData(record, args.data);
10453
10569
  }
10454
10570
  else {
@@ -11221,6 +11337,21 @@ class Filter {
11221
11337
  if (this.flatFilteredData.length > 0 && this.isHierarchyFilter) {
11222
11338
  this.updateFilterLevel();
11223
11339
  }
11340
+ for (let i = 0; i < this.filteredResult.length; i++) {
11341
+ const record = this.filteredResult[parseInt(i.toString(), 10)];
11342
+ if (!isNullOrUndefined(record.parentItem)) {
11343
+ const parentUID = record.parentItem.uniqueID;
11344
+ const parentPresent = this.filteredResult.some((r) => {
11345
+ return !isNullOrUndefined(r.uniqueID) && r.uniqueID === parentUID;
11346
+ });
11347
+ if (parentPresent) {
11348
+ record.isCollapsedChild = !getExpandStatus(this.parent, record, this.parent.parentData);
11349
+ }
11350
+ else {
11351
+ record.isCollapsedChild = false;
11352
+ }
11353
+ }
11354
+ }
11224
11355
  this.parent.notify('updateAction', { result: this.filteredResult });
11225
11356
  }
11226
11357
  updateParentFilteredRecord(record) {
@@ -12912,7 +13043,7 @@ class BatchEdit {
12912
13043
  added.childRecords = [];
12913
13044
  this.batchRecords.splice(added.index, 0, added);
12914
13045
  this.currentViewRecords.splice(added.index, 0, added);
12915
- if (currentDataIndex) {
13046
+ if (currentDataIndex > -1) {
12916
13047
  indexvalue = currentDataIndex;
12917
13048
  }
12918
13049
  else {
@@ -13538,6 +13669,9 @@ class Edit {
13538
13669
  }
13539
13670
  }
13540
13671
  }
13672
+ if (eventName === 'actionComplete' && eventArgs.requestType === 'save') {
13673
+ this.addRowRecord = null;
13674
+ }
13541
13675
  if (this.parent.enableInfiniteScrolling && eventName === 'actionComplete') {
13542
13676
  this.infiniteAddAction(eventArgs);
13543
13677
  }
@@ -14807,7 +14941,11 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
14807
14941
  && this.parent.dataSource.dataSource.offline && this.parent.dataSource.dataSource.url !== '') || !isCountRequired(this.parent)) {
14808
14942
  this.parent[`${action}`]('data-ready', this.onDataReady, this);
14809
14943
  this.parent[`${action}`]('refresh-virtual-block', this.refreshContentRows, this);
14944
+ this.parent.on(destroy, this.destroy, this);
14810
14945
  this.fn = () => {
14946
+ if (this.parent.root.enableSeamlessScrolling) {
14947
+ window.addEventListener('resize', this.updateScrollbar.bind(this));
14948
+ }
14811
14949
  this.observers.observes((scrollArgs) => this.scrollListeners(scrollArgs), this.onEnteredAction(), this.parent);
14812
14950
  const gObj = this.parent;
14813
14951
  if (gObj.root.enablePersistence && gObj.root.scrollPosition) {
@@ -14857,6 +14995,10 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
14857
14995
  const virtualCellFocus = 'virtualCellFocus';
14858
14996
  super[`${virtualCellFocus}`](e);
14859
14997
  }
14998
+ updateScrollbar() {
14999
+ const updateScrollbarOnResize = 'updateScrollbarOnResize';
15000
+ super[`${updateScrollbarOnResize}`]();
15001
+ }
14860
15002
  /**
14861
15003
  * Handles the data ready event for the virtual tree grid content renderer.
14862
15004
  *
@@ -14897,9 +15039,6 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
14897
15039
  super.renderTable();
14898
15040
  if (!(this.parent.dataSource instanceof DataManager && this.parent.dataSource.dataSource.url !== undefined
14899
15041
  && this.parent.dataSource.dataSource.offline && this.parent.dataSource.dataSource.url !== '') || !isCountRequired(this.parent)) {
14900
- if (this.observers) {
14901
- this.observers.disconnect();
14902
- }
14903
15042
  getValue('observer', this).options.debounceEvent = false;
14904
15043
  this.observers = new TreeInterSectionObserver(getValue('observer', this).element, getValue('observer', this).options);
14905
15044
  this.contents = this.getPanel().firstChild;
@@ -14980,7 +15119,7 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
14980
15119
  }
14981
15120
  const treeGridParent = this.parent.clipboardModule['treeGridParent'];
14982
15121
  if (isNullOrUndefined(treeGridParent.editModule) ||
14983
- isNullOrUndefined(treeGridParent.editModule['addRowIndex']) || args.selectedIndex !== 0) {
15122
+ isNullOrUndefined(treeGridParent.editModule['addRowIndex']) || args.selectedIndex !== -1) {
14984
15123
  if (!isNullOrUndefined(treeGridParent.grid.sortModule) && treeGridParent.grid.sortModule['sortedColumns'].length > 0) {
14985
15124
  const sortedData = treeGridParent.dataModule['sortedData'];
14986
15125
  if (!isNullOrUndefined(sortedData) && sortedData.length > 0) {
@@ -15279,16 +15418,28 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
15279
15418
  const maxLeft = this.vgenerator.cOffsets[idx - 1];
15280
15419
  x = x > maxLeft ? maxLeft : x; //TODO: This fix horizontal scrollbar jumping issue in column virtualization.
15281
15420
  }
15282
- let y = this.getTranslateY(e.top, height, xAxis && top === e.top ? this.prevInfo : undefined, true);
15421
+ const isRowScrollAction = this.prevInfo && this.prevInfo.page === 1 &&
15422
+ (direction !== this.prevInfo.direction || direction !== this.prevInfo.direction);
15423
+ let translateY = this.getTranslateY(e.top, height, xAxis && top === e.top ? this.prevInfo : undefined, isRowScrollAction ? false : true);
15283
15424
  if (!this.parent.isFrozenGrid() || this.parent.enableVirtualMaskRow) {
15284
15425
  if (this.parent.enableVirtualMaskRow) {
15285
15426
  const upScroll = (e.top - this.translateY) < 0;
15286
- y = (Math.round(this.translateY) > y && !upScroll) ? Math.round(this.translateY) : y;
15287
- this.virtualEle.adjustTable(x, y);
15427
+ translateY = (Math.round(this.translateY) > translateY && !upScroll) ? Math.round(this.translateY) : translateY;
15428
+ this.virtualEle.adjustTable(x, translateY);
15288
15429
  }
15289
15430
  else {
15290
15431
  this.virtualEle.adjustTable(x, this.translateY);
15291
15432
  }
15433
+ const wrapperBottom = this.virtualEle.wrapper.getBoundingClientRect().bottom;
15434
+ const contentBottom = this.virtualEle.content.getBoundingClientRect().bottom;
15435
+ if (direction === 'up' && this.prevInfo.page === Math.ceil(this.getTotalBlocks() / 2) &&
15436
+ Math.round(wrapperBottom) < Math.round(contentBottom)) {
15437
+ const bottomGap = Math.round(contentBottom) - Math.round(wrapperBottom);
15438
+ const adjustedTranslateY = Math.min(translateY + bottomGap, this.offsets[this['maxBlock']]);
15439
+ if (adjustedTranslateY !== translateY) {
15440
+ this.virtualEle.adjustTable(x, adjustedTranslateY);
15441
+ }
15442
+ }
15292
15443
  if (this.parent.enableColumnVirtualization) {
15293
15444
  this.header.virtualEle.adjustTable(x, 0);
15294
15445
  if (this.parent.isFrozenGrid()) {
@@ -15617,10 +15768,17 @@ class VirtualTreeContentRenderer extends VirtualContentRenderer {
15617
15768
  this.parent.off('refresh-virtual-editform-cells', this.refreshCell);
15618
15769
  this.parent.off('virtaul-cell-focus', this.cellFocus);
15619
15770
  this.parent.off('virtual-scroll-edit', this.restoreEditState);
15620
- if (this.observers) {
15621
- this.observers.disconnect();
15771
+ this.parent.off(destroy, this.destroy);
15772
+ if (this.parent.root.enableSeamlessScrolling) {
15773
+ window.removeEventListener('resize', this.updateScrollbar);
15622
15774
  }
15623
15775
  }
15776
+ destroy() {
15777
+ if (this.parent.isDestroyed) {
15778
+ return;
15779
+ }
15780
+ this.removeEventListener();
15781
+ }
15624
15782
  }
15625
15783
  class TreeInterSectionObserver extends InterSectionObserver {
15626
15784
  constructor() {
@@ -15630,6 +15788,9 @@ class TreeInterSectionObserver extends InterSectionObserver {
15630
15788
  this.lastPos = 0;
15631
15789
  this.timer = 0;
15632
15790
  }
15791
+ onWheelEvent() {
15792
+ this.isWheeling = true;
15793
+ }
15633
15794
  /**
15634
15795
  * Sets up observers to monitor scroll events on a given container
15635
15796
  * and its movable companion within a virtual grid setup.
@@ -15642,28 +15803,27 @@ class TreeInterSectionObserver extends InterSectionObserver {
15642
15803
  observes(callback, onEnterCallback, instance) {
15643
15804
  const containerRect = 'containerRect';
15644
15805
  super[`${containerRect}`] = getValue('options', this).container.getBoundingClientRect();
15645
- this.containerEl = getValue('options', this).container;
15646
- this.containerScrollHandler = this.virtualScrollHandlers(callback, onEnterCallback, instance);
15647
- EventHandler.add(this.containerEl, 'scroll', this.containerScrollHandler, this);
15648
- if (getValue('options', this).movableContainer) {
15649
- const movableContainerRect = 'movableContainerRect';
15650
- super[`${movableContainerRect}`] = getValue('options', this).movableContainer.getBoundingClientRect();
15651
- this.movableContainerEl = getValue('options', this).movableContainer;
15652
- this.movableScrollHandler = this.virtualScrollHandlers(callback, onEnterCallback, instance);
15653
- EventHandler.add(this.movableContainerEl, 'scroll', this.movableScrollHandler, this);
15654
- }
15655
- }
15656
- disconnect() {
15657
- if (this.containerEl && this.containerScrollHandler) {
15658
- EventHandler.remove(this.containerEl, 'scroll', this.containerScrollHandler);
15659
- this.containerScrollHandler = null;
15806
+ const options = getValue('options', this);
15807
+ EventHandler.add(options.container, 'wheel', this.onWheelEvent, this);
15808
+ if (!isNullOrUndefined(options.horizontalScrollbar)) {
15809
+ EventHandler.add(options.horizontalScrollbar, 'wheel', this.onWheelEvent, this);
15810
+ EventHandler.add(options.horizontalScrollbar, 'scroll', this.onVirtualContentScrolling(), this);
15660
15811
  }
15661
- if (this.movableContainerEl && this.movableScrollHandler) {
15662
- EventHandler.remove(this.movableContainerEl, 'scroll', this.movableScrollHandler);
15663
- this.movableScrollHandler = null;
15812
+ if (!isNullOrUndefined(options.verticalScrollbar)) {
15813
+ EventHandler.add(options.verticalScrollbar, 'wheel', this.onWheelEvent, this);
15814
+ EventHandler.add(options.verticalScrollbar, 'scroll', this.onVirtualContentScrolling(), this);
15664
15815
  }
15665
- this.containerEl = null;
15666
- this.movableContainerEl = null;
15816
+ EventHandler.add(options.container, 'scroll', this.virtualScrollHandlers(callback, onEnterCallback, instance), this);
15817
+ }
15818
+ onVirtualContentScrolling() {
15819
+ return (e) => {
15820
+ if (e.target.classList.contains('e-virtual-vertical-scrollbar')) {
15821
+ getValue('options', this).container.scrollTop = e.target.scrollTop;
15822
+ }
15823
+ if (e.target.classList.contains('e-virtual-horizontal-scrollbar')) {
15824
+ getValue('options', this).container.scrollLeft = e.target.scrollLeft;
15825
+ }
15826
+ };
15667
15827
  }
15668
15828
  /**
15669
15829
  * Clears the last known position.
@@ -15708,6 +15868,12 @@ class TreeInterSectionObserver extends InterSectionObserver {
15708
15868
  direction = this[`${options}`].prevLeft === left ? direction : this[`${options}`].prevLeft < left ? 'right' : 'left';
15709
15869
  this[`${options}`].prevTop = top;
15710
15870
  this[`${options}`].prevLeft = left;
15871
+ if (!isNullOrUndefined(this[`${options}`].verticalScrollbar)) {
15872
+ this[`${options}`].verticalScrollbar.scrollTop = this[`${options}`].container.scrollTop;
15873
+ }
15874
+ if (!isNullOrUndefined(this[`${options}`].horizontalScrollbar)) {
15875
+ this[`${options}`].horizontalScrollbar.scrollLeft = this[`${options}`].container.scrollLeft;
15876
+ }
15711
15877
  const current = this.sentinelInfo[`${direction}`];
15712
15878
  let delta = 0;
15713
15879
  this.newPos = top;
@@ -15872,7 +16038,8 @@ class VirtualScroll {
15872
16038
  const dm = new DataManager(pageingDetails.result);
15873
16039
  const expanded = new Predicate$1('expanded', 'notequal', null).or('expanded', 'notequal', undefined);
15874
16040
  const parents = dm.executeLocal(new Query().where(expanded));
15875
- const isFiltering = pageingDetails.actionArgs.requestType === 'filtering';
16041
+ const isFiltering = (pageingDetails.actionArgs.requestType === 'filtering' && pageingDetails.actionArgs.action !== 'clear-filter') ||
16042
+ (!isNullOrUndefined(this.parent['filterModule']) && (this.parent['filterModule'].filteredResult && this.parent['filterModule'].filteredResult.length > 0));
15876
16043
  const isFlatHierarchy = this.parent.filterSettings.hierarchyMode === 'Child' ||
15877
16044
  this.parent.filterSettings.hierarchyMode === 'None';
15878
16045
  const visualData = isFiltering && isFlatHierarchy