diff --git a/examples/webpack-demo-vanilla-bundle/src/examples/example05.ts b/examples/webpack-demo-vanilla-bundle/src/examples/example05.ts
index 14289e7c7..e34ba4e65 100644
--- a/examples/webpack-demo-vanilla-bundle/src/examples/example05.ts
+++ b/examples/webpack-demo-vanilla-bundle/src/examples/example05.ts
@@ -41,6 +41,9 @@ export class Example5 {
this.sgb = new Slicker.GridBundle(gridContainerElm, this.columnDefinitions, { ...ExampleGridOptions, ...this.gridOptions });
this.dataset = this.loadData(NB_ITEMS);
+ // optionally display only the parent items count on the right footer
+ // this.sgb.slickFooter.rightFooterText = `${this.sgb.treeDataService.getItemCount(0)} parent items`;
+
// with large dataset you maybe want to show spinner before/after these events: sorting/filtering/collapsing/expanding
this._bindingEventService.bind(gridContainerElm, 'onbeforefilterchange', this.showSpinner.bind(this));
this._bindingEventService.bind(gridContainerElm, 'onfilterchanged', this.hideSpinner.bind(this));
@@ -125,7 +128,7 @@ export class Example5 {
showCustomFooter: true, // display some metrics in the bottom custom footer
customFooterOptions: {
// optionally display some text on the left footer container
- leftFooterText: 'Grid created with Slickgrid-Universal',
+ leftFooterText: 'Grid created with Slickgrid-Universal ',
},
enableTreeData: true, // you must enable this flag for the filtering & sorting to work as expected
treeDataOptions: {
diff --git a/packages/common/src/services/__tests__/treeData.service.spec.ts b/packages/common/src/services/__tests__/treeData.service.spec.ts
index db7b73c1f..8ed1f7bd4 100644
--- a/packages/common/src/services/__tests__/treeData.service.spec.ts
+++ b/packages/common/src/services/__tests__/treeData.service.spec.ts
@@ -32,6 +32,7 @@ const dataViewStub = {
endUpdate: jest.fn(),
getItem: jest.fn(),
getItemById: jest.fn(),
+ getItemCount: jest.fn(),
getItems: jest.fn(),
refresh: jest.fn(),
sort: jest.fn(),
@@ -321,11 +322,11 @@ describe('TreeData Service', () => {
beforeEach(() => {
jest.clearAllMocks();
mockFlatDataset = [
- { id: 0, file: 'TXT', size: 5.8, __hasChildren: true },
- { id: 1, file: 'myFile.txt', size: 0.5 },
- { id: 2, file: 'myMusic.txt', size: 5.3 },
- { id: 4, file: 'MP3', size: 3.4, __hasChildren: true },
- { id: 5, file: 'relaxation.mp3', size: 3.4 }
+ { id: 0, file: 'TXT', size: 5.8, __hasChildren: true, __treeLevel: 0 },
+ { id: 1, file: 'myFile.txt', size: 0.5, __treeLevel: 1 },
+ { id: 2, file: 'myMusic.txt', size: 5.3, __treeLevel: 1 },
+ { id: 4, file: 'MP3', size: 3.4, __hasChildren: true, __treeLevel: 0 },
+ { id: 5, file: 'relaxation.mp3', size: 3.4, __treeLevel: 1 }
];
mockHierarchical = [
{ id: 0, file: 'TXT', files: [{ id: 1, file: 'myFile.txt', size: 0.5, }, { id: 2, file: 'myMusic.txt', size: 5.3, }] },
@@ -336,6 +337,7 @@ describe('TreeData Service', () => {
it('should collapse all items when calling the method with collapsing True', async () => {
const dataGetItemsSpy = jest.spyOn(dataViewStub, 'getItems').mockReturnValue(mockFlatDataset);
+ jest.spyOn(dataViewStub, 'getItemCount').mockReturnValue(mockFlatDataset.length);
jest.spyOn(SharedService.prototype, 'hierarchicalDataset', 'get').mockReturnValue(mockHierarchical);
const beginUpdateSpy = jest.spyOn(dataViewStub, 'beginUpdate');
const endUpdateSpy = jest.spyOn(dataViewStub, 'endUpdate');
@@ -349,12 +351,15 @@ describe('TreeData Service', () => {
expect(pubSubSpy).toHaveBeenCalledWith(`onTreeFullToggleEnd`, { type: 'full-collapse', previousFullToggleType: 'full-collapse', toggledItems: null, });
expect(dataGetItemsSpy).toHaveBeenCalled();
expect(beginUpdateSpy).toHaveBeenCalled();
- expect(updateItemSpy).toHaveBeenNthCalledWith(1, 0, { __collapsed: true, __hasChildren: true, id: 0, file: 'TXT', size: 5.8 });
- expect(updateItemSpy).toHaveBeenNthCalledWith(2, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4 });
- expect(SharedService.prototype.hierarchicalDataset[0].file).toBe('TXT');
+ expect(updateItemSpy).toHaveBeenNthCalledWith(1, 0, { __collapsed: true, __hasChildren: true, id: 0, file: 'TXT', size: 5.8, __treeLevel: 0 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(2, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4, __treeLevel: 0 });
+ expect(SharedService.prototype.hierarchicalDataset[0].file).toBe('TXT')
expect(SharedService.prototype.hierarchicalDataset[0].__collapsed).toBeTrue();
expect(SharedService.prototype.hierarchicalDataset[1].file).toBe('MP3');
expect(SharedService.prototype.hierarchicalDataset[1].__collapsed).toBeTrue();
+ expect(service.getItemCount(0)).toBe(2); // get count by tree level 0
+ expect(service.getItemCount(1)).toBe(3);
+ expect(service.getItemCount()).toBe(5); // get full count of all tree
expect(endUpdateSpy).toHaveBeenCalled();
});
@@ -374,8 +379,8 @@ describe('TreeData Service', () => {
expect(dataGetItemsSpy).toHaveBeenCalled();
expect(dataGetItemsSpy).toHaveBeenCalled();
expect(beginUpdateSpy).toHaveBeenCalled();
- expect(updateItemSpy).toHaveBeenNthCalledWith(1, 0, { customCollapsed: true, __hasChildren: true, id: 0, file: 'TXT', size: 5.8 });
- expect(updateItemSpy).toHaveBeenNthCalledWith(2, 4, { customCollapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(1, 0, { customCollapsed: true, __hasChildren: true, id: 0, file: 'TXT', size: 5.8, __treeLevel: 0 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(2, 4, { customCollapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4, __treeLevel: 0 });
expect(endUpdateSpy).toHaveBeenCalled();
});
@@ -393,8 +398,8 @@ describe('TreeData Service', () => {
expect(pubSubSpy).toHaveBeenCalledWith(`onTreeFullToggleEnd`, { type: 'full-expand', previousFullToggleType: 'full-expand', toggledItems: null, });
expect(dataGetItemsSpy).toHaveBeenCalled();
expect(beginUpdateSpy).toHaveBeenCalled();
- expect(updateItemSpy).toHaveBeenNthCalledWith(1, 0, { __collapsed: false, __hasChildren: true, id: 0, file: 'TXT', size: 5.8 });
- expect(updateItemSpy).toHaveBeenNthCalledWith(2, 4, { __collapsed: false, __hasChildren: true, id: 4, file: 'MP3', size: 3.4 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(1, 0, { __collapsed: false, __hasChildren: true, id: 0, file: 'TXT', size: 5.8, __treeLevel: 0 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(2, 4, { __collapsed: false, __hasChildren: true, id: 4, file: 'MP3', size: 3.4, __treeLevel: 0 });
expect(endUpdateSpy).toHaveBeenCalled();
});
@@ -413,7 +418,7 @@ describe('TreeData Service', () => {
expect(dataGetItemsSpy).toHaveBeenCalled();
expect(beginUpdateSpy).toHaveBeenCalled();
- expect(updateItemSpy).toHaveBeenNthCalledWith(1, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(1, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4, __treeLevel: 0 });
expect(pubSubSpy).not.toHaveBeenCalledWith(`onTreeItemToggled`);
expect(endUpdateSpy).toHaveBeenCalled();
});
@@ -432,7 +437,7 @@ describe('TreeData Service', () => {
expect(dataGetItemsSpy).not.toHaveBeenCalled();
expect(beginUpdateSpy).toHaveBeenCalled();
- expect(updateItemSpy).toHaveBeenNthCalledWith(1, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(1, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4, __treeLevel: 0 });
expect(pubSubSpy).toHaveBeenCalledWith(`onTreeItemToggled`, { fromItemId: 4, previousFullToggleType: 'full-collapse', toggledItems: [{ itemId: 4, isCollapsed: true }], type: 'toggle-collapse' });
expect(endUpdateSpy).toHaveBeenCalled();
});
@@ -452,7 +457,7 @@ describe('TreeData Service', () => {
expect(dataGetItemsSpy).toHaveBeenCalled();
expect(beginUpdateSpy).toHaveBeenCalled();
- expect(updateItemSpy).toHaveBeenNthCalledWith(1, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4 });
+ expect(updateItemSpy).toHaveBeenNthCalledWith(1, 4, { __collapsed: true, __hasChildren: true, id: 4, file: 'MP3', size: 3.4, __treeLevel: 0 });
expect(pubSubSpy).toHaveBeenCalledWith(`onTreeItemToggled`, { fromItemId: 4, previousFullToggleType: 'full-collapse', toggledItems: [{ itemId: 4, isCollapsed: true }], type: 'toggle-collapse' });
expect(endUpdateSpy).toHaveBeenCalled();
});
diff --git a/packages/common/src/services/treeData.service.ts b/packages/common/src/services/treeData.service.ts
index a52fed994..8dc93cf07 100644
--- a/packages/common/src/services/treeData.service.ts
+++ b/packages/common/src/services/treeData.service.ts
@@ -190,6 +190,20 @@ export class TreeDataService {
};
}
+ /**
+ * Get the full item count of the Tree.
+ * When an optional tree level is provided, it will return the count for only that dedicated level (for example providing 0 would return the item count of all parent items)
+ * @param {Number} [treeLevel] - optional tree level to get item count from
+ * @returns
+ */
+ getItemCount(treeLevel?: number) {
+ if (treeLevel !== undefined) {
+ const levelPropName = this.getTreeDataOptionPropName('levelPropName');
+ return this.dataView.getItems().filter(dataContext => dataContext[levelPropName] === treeLevel).length;
+ }
+ return this.dataView.getItemCount();
+ }
+
/**
* Get the current list of Tree Data item(s) that got toggled in the grid (basically the parents that the user clicked on the toggle icon to expand/collapse the child)
* @returns {Array} treeDataToggledItems - items that were toggled (array of `parentId` and `isCollapsed` flag)