Skip to content

Commit f574fe4

Browse files
authored
fix(filter): Grid Preset Filters should work with Tree Data View (#522)
* fix(filter): Grid Preset Filters should work with Tree Data View - the Tree Data must execute pre-filtering with Tree Data when having Grid Preset Filters
1 parent bacec1f commit f574fe4

10 files changed

+213
-147
lines changed

src/app/examples/grid-rowselection.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ export class GridRowSelectionComponent implements OnInit {
177177
// the RECOMMENDED is to use "dataContextIds" since that will always work even with Pagination, while "gridRowIndexes" is only good for 1 page
178178
rowSelection: {
179179
// gridRowIndexes: [2], // the row position of what you see on the screen (UI)
180-
dataContextIds: [3, 12, 13, 522] // (recommended) select by the your data object IDs
180+
dataContextIds: [3, 12, 13, 522] // (recommended) select by your data object IDs
181181
}
182182
},
183183
};

src/app/examples/grid-tree-data-parent-child.component.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class GridTreeDataParentChildComponent implements OnInit {
6060
{ id: 'duration', name: 'Duration', field: 'duration', minWidth: 90, filterable: true },
6161
{
6262
id: 'percentComplete', name: '% Complete', field: 'percentComplete', minWidth: 120, maxWidth: 200,
63-
sortable: true, filterable: true, filter: { model: Filters.slider, operator: '>=' },
63+
sortable: true, filterable: true, filter: { model: Filters.compoundSlider, operator: '>=' },
6464
formatter: Formatters.percentCompleteBar, type: FieldType.number,
6565
},
6666
{
@@ -104,6 +104,9 @@ export class GridTreeDataParentChildComponent implements OnInit {
104104
// change header/cell row height for material design theme
105105
headerRowHeight: 45,
106106
rowHeight: 40,
107+
presets: {
108+
filters: [{ columnId: 'percentComplete', searchTerms: [25], operator: '>=' }]
109+
},
107110

108111
// use Material Design SVG icons
109112
contextMenu: {
@@ -175,7 +178,7 @@ export class GridTreeDataParentChildComponent implements OnInit {
175178
// force a resort because of the tree data structure
176179
setTimeout(() => {
177180
const titleColumn = this.columnDefinitions.find(col => col.id === 'title');
178-
this.angularGrid.sortService.onLocalSortChanged(this.gridObj, this.dataViewObj, [{ columnId: 'title', sortCol: titleColumn, sortAsc: true }]);
181+
this.angularGrid.sortService.onLocalSortChanged(this.gridObj, [{ columnId: 'title', sortCol: titleColumn, sortAsc: true }]);
179182

180183
// scroll into the position, after insertion cycle, where the item was added
181184
const rowIndex = this.dataViewObj.getRowById(newItem.id);

src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid-constructor.spec.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ const mockGrid = {
213213
invalidate: jest.fn(),
214214
getActiveCellNode: jest.fn(),
215215
getColumns: jest.fn(),
216+
getData: () => mockDataView,
216217
getSelectionModel: jest.fn(),
217218
getEditorLock: () => mockGetEditorLock,
218219
getOptions: jest.fn(),
@@ -598,7 +599,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
598599
component.gridOptions = { enableFiltering: true } as GridOption;
599600
component.ngAfterViewInit();
600601

601-
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
602+
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid);
602603
});
603604

604605
it('should bind local sort when "enableSorting" is set', () => {
@@ -607,7 +608,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
607608
component.gridOptions = { enableSorting: true } as GridOption;
608609
component.ngAfterViewInit();
609610

610-
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
611+
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid);
611612
});
612613
});
613614

@@ -1024,7 +1025,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
10241025
} as GridOption;
10251026
component.ngAfterViewInit();
10261027

1027-
expect(bindBackendSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
1028+
expect(bindBackendSpy).toHaveBeenCalledWith(mockGrid);
10281029
expect(initSpy).toHaveBeenCalledWith(mockGraphqlOptions, mockPagination, mockGrid);
10291030
});
10301031

@@ -1041,7 +1042,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
10411042
} as GridOption;
10421043
component.ngAfterViewInit();
10431044

1044-
expect(bindBackendSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
1045+
expect(bindBackendSpy).toHaveBeenCalledWith(mockGrid);
10451046
});
10461047

10471048
it('should call bind local sorting when "enableSorting" is set and "useLocalSorting" is set as well', () => {
@@ -1058,7 +1059,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
10581059
} as GridOption;
10591060
component.ngAfterViewInit();
10601061

1061-
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
1062+
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid);
10621063
});
10631064

10641065
it('should call bind backend filtering when "enableFiltering" is set', () => {
@@ -1070,7 +1071,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
10701071
component.ngAfterViewInit();
10711072

10721073
expect(initSpy).toHaveBeenCalledWith(mockGrid);
1073-
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
1074+
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid);
10741075
expect(populateSpy).not.toHaveBeenCalled();
10751076
});
10761077

@@ -1088,7 +1089,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
10881089
} as GridOption;
10891090
component.ngAfterViewInit();
10901091

1091-
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
1092+
expect(bindLocalSpy).toHaveBeenCalledWith(mockGrid);
10921093
});
10931094

10941095
it('should reflect column filters when "enableFiltering" is set', () => {
@@ -1107,7 +1108,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
11071108
component.ngAfterViewInit();
11081109

11091110
expect(initSpy).toHaveBeenCalledWith(mockGrid);
1110-
expect(bindBackendSpy).toHaveBeenCalledWith(mockGrid, mockDataView);
1111+
expect(bindBackendSpy).toHaveBeenCalledWith(mockGrid);
11111112
expect(populateSpy).not.toHaveBeenCalled();
11121113
});
11131114

src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts

+50-37
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
367367
if (!this._isDatasetInitialized && this.gridOptions.enableCheckboxSelector) {
368368
this.loadRowSelectionPresetWhenExists();
369369
}
370+
this.loadPresetsWhenDatasetInitialized();
370371
this._isDatasetInitialized = true;
371372

372373
// also update the hierarchical dataset
@@ -487,49 +488,34 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
487488
);
488489
}
489490

490-
// if user entered some Columns "presets", we need to reflect them all in the grid
491-
if (gridOptions.presets && Array.isArray(gridOptions.presets.columns) && gridOptions.presets.columns.length > 0) {
492-
const gridColumns: Column[] = this.gridStateService.getAssociatedGridColumns(grid, gridOptions.presets.columns);
493-
if (gridColumns && Array.isArray(gridColumns) && gridColumns.length > 0) {
494-
// make sure that the checkbox selector is also visible if it is enabled
495-
if (gridOptions.enableCheckboxSelector) {
496-
const checkboxColumn = (Array.isArray(this._columnDefinitions) && this._columnDefinitions.length > 0) ? this._columnDefinitions[0] : null;
497-
if (checkboxColumn && checkboxColumn.id === '_checkbox_selector' && gridColumns[0].id !== '_checkbox_selector') {
498-
gridColumns.unshift(checkboxColumn);
499-
}
491+
if (!this.customDataView) {
492+
// bind external sorting (backend) when available or default onSort (dataView)
493+
if (gridOptions.enableSorting) {
494+
// bind external sorting (backend) unless specified to use the local one
495+
if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalSorting) {
496+
this.sortService.bindBackendOnSort(grid);
497+
} else {
498+
this.sortService.bindLocalOnSort(grid);
500499
}
501-
502-
// finally set the new presets columns (including checkbox selector if need be)
503-
grid.setColumns(gridColumns);
504-
}
505-
}
506-
507-
// bind external sorting (backend) when available or default onSort (dataView)
508-
if (gridOptions.enableSorting && !this.customDataView) {
509-
// bind external sorting (backend) unless specified to use the local one
510-
if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalSorting) {
511-
this.sortService.bindBackendOnSort(grid, dataView);
512-
} else {
513-
this.sortService.bindLocalOnSort(grid, dataView);
514500
}
515-
}
516501

517-
// bind external filter (backend) when available or default onFilter (dataView)
518-
if (gridOptions.enableFiltering && !this.customDataView) {
519-
this.filterService.init(grid);
502+
// bind external filter (backend) when available or default onFilter (dataView)
503+
if (gridOptions.enableFiltering) {
504+
this.filterService.init(grid);
520505

521-
// if user entered some Filter "presets", we need to reflect them all in the DOM
522-
if (gridOptions.presets && Array.isArray(gridOptions.presets.filters) && gridOptions.presets.filters.length > 0) {
523-
this.filterService.populateColumnFilterSearchTermPresets(gridOptions.presets.filters);
524-
}
525-
// bind external filter (backend) unless specified to use the local one
526-
if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalFiltering) {
527-
this.filterService.bindBackendOnFilter(grid, dataView);
528-
} else {
529-
this.filterService.bindLocalOnFilter(grid, dataView);
506+
// bind external filter (backend) unless specified to use the local one
507+
if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalFiltering) {
508+
this.filterService.bindBackendOnFilter(grid);
509+
} else {
510+
this.filterService.bindLocalOnFilter(grid);
511+
}
530512
}
513+
514+
// load any presets if any (after dataset is initialized)
515+
this.loadPresetsWhenDatasetInitialized();
531516
}
532517

518+
533519
// if user set an onInit Backend, we'll run it right away (and if so, we also need to run preProcess, internalPostProcess & postProcess)
534520
if (gridOptions.backendServiceApi) {
535521
const backendApi = gridOptions.backendServiceApi;
@@ -812,6 +798,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
812798
if (!this._isDatasetInitialized && (this.gridOptions.enableCheckboxSelector || this.gridOptions.enableRowSelection)) {
813799
this.loadRowSelectionPresetWhenExists();
814800
}
801+
this.loadPresetsWhenDatasetInitialized();
815802
this._isDatasetInitialized = true;
816803
}
817804
}
@@ -917,6 +904,32 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
917904
}
918905
}
919906

907+
private loadPresetsWhenDatasetInitialized() {
908+
if (this.gridOptions && !this.customDataView) {
909+
// if user entered some Filter "presets", we need to reflect them all in the DOM
910+
if (this.gridOptions.presets && Array.isArray(this.gridOptions.presets.filters) && this.gridOptions.presets.filters.length > 0) {
911+
this.filterService.populateColumnFilterSearchTermPresets(this.gridOptions.presets.filters);
912+
}
913+
914+
// if user entered some Columns "presets", we need to reflect them all in the grid
915+
if (this.gridOptions.presets && Array.isArray(this.gridOptions.presets.columns) && this.gridOptions.presets.columns.length > 0) {
916+
const gridColumns: Column[] = this.gridStateService.getAssociatedGridColumns(this.grid, this.gridOptions.presets.columns);
917+
if (gridColumns && Array.isArray(gridColumns) && gridColumns.length > 0) {
918+
// make sure that the checkbox selector is also visible if it is enabled
919+
if (this.gridOptions.enableCheckboxSelector) {
920+
const checkboxColumn = (Array.isArray(this._columnDefinitions) && this._columnDefinitions.length > 0) ? this._columnDefinitions[0] : null;
921+
if (checkboxColumn && checkboxColumn.id === '_checkbox_selector' && gridColumns[0].id !== '_checkbox_selector') {
922+
gridColumns.unshift(checkboxColumn);
923+
}
924+
}
925+
926+
// finally set the new presets columns (including checkbox selector if need be)
927+
this.grid.setColumns(gridColumns);
928+
}
929+
}
930+
}
931+
}
932+
920933
/**
921934
* local grid, check if we need to show the Pagination
922935
* if so then also check if there's any presets and finally initialize the PaginationService
@@ -1016,7 +1029,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
10161029
}
10171030

10181031
// we will display the custom footer only when there's no Pagination
1019-
if (!this.gridOptions.enablePagination) {
1032+
if (!this.gridOptions.enablePagination && !this._isPaginationInitialized) {
10201033
this.showCustomFooter = this.gridOptions.hasOwnProperty('showCustomFooter') ? this.gridOptions.showCustomFooter : false;
10211034
this.customFooterOptions = this.gridOptions.customFooterOptions || {};
10221035
}

src/app/modules/angular-slickgrid/extensions/__tests__/headerMenuExtension.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ describe('headerMenuExtension', () => {
517517
instance.onCommand.notify({ column: mockSortedCols[1].sortCol, grid: gridStub, command: 'sort-desc' }, new Slick.EventData(), gridStub);
518518

519519
expect(previousSortSpy).toHaveBeenCalled();
520-
expect(localSortSpy).toHaveBeenCalledWith(gridStub, dataViewStub, mockSortedOuput);
520+
expect(localSortSpy).toHaveBeenCalledWith(gridStub, mockSortedOuput);
521521
expect(onCommandSpy).toHaveBeenCalled();
522522
expect(setSortSpy).toHaveBeenCalled();
523523
});

src/app/modules/angular-slickgrid/extensions/headerMenuExtension.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ export class HeaderMenuExtension implements Extension {
363363
this.sortService.onBackendSortChanged(event, { multiColumnSort: true, sortCols: sortedColsWithoutCurrent, grid: this.sharedService.grid });
364364
emitterType = EmitterType.remote;
365365
} else if (this.sharedService.dataView) {
366-
this.sortService.onLocalSortChanged(this.sharedService.grid, this.sharedService.dataView, sortedColsWithoutCurrent);
366+
this.sortService.onLocalSortChanged(this.sharedService.grid, sortedColsWithoutCurrent);
367367
emitterType = EmitterType.local;
368368
} else {
369369
// when using customDataView, we will simply send it as a onSort event with notify

0 commit comments

Comments
 (0)