diff --git a/src/app/modules/angular-slickgrid/services/__tests__/filter.service.spec.ts b/src/app/modules/angular-slickgrid/services/__tests__/filter.service.spec.ts index c2512fb2e..df9d1707a 100644 --- a/src/app/modules/angular-slickgrid/services/__tests__/filter.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/__tests__/filter.service.spec.ts @@ -965,7 +965,25 @@ describe('FilterService', () => { }); }); - it('should call "clearFilters" without triggering a clear event but trigger an "emitFilterChanged" remote when using "bindLocalOnFilter" and also expect filters to be set in ColumnFilters', () => { + it('should expect filters to be set in ColumnFilters when using "bindLocalOnFilter" without triggering a filter changed event when 2nd flag argument is set to false', () => { + const clearSpy = jest.spyOn(service, 'clearFilters'); + const emitSpy = jest.spyOn(service, 'emitFilterChanged'); + + service.init(gridStub); + service.bindLocalOnFilter(gridStub, dataViewStub); + gridStub.onHeaderRowCellRendered.notify(mockArgs1, new Slick.EventData(), gridStub); + gridStub.onHeaderRowCellRendered.notify(mockArgs2, new Slick.EventData(), gridStub); + service.updateFilters(mockNewFilters, false); + + expect(emitSpy).not.toHaveBeenCalled(); + expect(clearSpy).toHaveBeenCalledWith(false); + expect(service.getColumnFilters()).toEqual({ + firstName: { columnId: 'firstName', columnDef: mockColumn1, searchTerms: ['Jane'], operator: 'StartsWith' }, + isActive: { columnId: 'isActive', columnDef: mockColumn2, searchTerms: [false], operator: 'EQ' } + }); + }); + + it('should call "clearFilters" without triggering a clear event but trigger an "emitFilterChanged" remote when using "bindBackendOnFilter" and also expect filters to be set in ColumnFilters', () => { gridOptionMock.backendServiceApi = { filterTypingDebounce: 0, service: backendServiceStub, @@ -976,7 +994,7 @@ describe('FilterService', () => { const backendUpdateSpy = jest.spyOn(backendServiceStub, 'updateFilters'); service.init(gridStub); - service.bindLocalOnFilter(gridStub, dataViewStub); + service.bindBackendOnFilter(gridStub, dataViewStub); gridStub.onHeaderRowCellRendered.notify(mockArgs1, new Slick.EventData(), gridStub); gridStub.onHeaderRowCellRendered.notify(mockArgs2, new Slick.EventData(), gridStub); service.updateFilters(mockNewFilters); @@ -990,5 +1008,31 @@ describe('FilterService', () => { expect(clearSpy).toHaveBeenCalledWith(false); expect(mockRefreshBackendDataset).toHaveBeenCalledWith(gridOptionMock); }); + + it('should expect filters to be sent to the backend when using "bindBackendOnFilter" without triggering a filter changed event neither a backend query when both flag arguments are set to false', () => { + gridOptionMock.backendServiceApi = { + filterTypingDebounce: 0, + service: backendServiceStub, + process: () => new Promise((resolve) => resolve(jest.fn())), + }; + const clearSpy = jest.spyOn(service, 'clearFilters'); + const emitSpy = jest.spyOn(service, 'emitFilterChanged'); + const backendUpdateSpy = jest.spyOn(backendServiceStub, 'updateFilters'); + + service.init(gridStub); + service.bindBackendOnFilter(gridStub, dataViewStub); + gridStub.onHeaderRowCellRendered.notify(mockArgs1, new Slick.EventData(), gridStub); + gridStub.onHeaderRowCellRendered.notify(mockArgs2, new Slick.EventData(), gridStub); + service.updateFilters(mockNewFilters, false, false); + + expect(emitSpy).not.toHaveBeenCalled(); + expect(mockRefreshBackendDataset).not.toHaveBeenCalled(); + expect(backendUpdateSpy).toHaveBeenCalledWith(mockNewFilters, true); + expect(service.getColumnFilters()).toEqual({ + firstName: { columnId: 'firstName', columnDef: mockColumn1, searchTerms: ['Jane'], operator: 'StartsWith' }, + isActive: { columnId: 'isActive', columnDef: mockColumn2, searchTerms: [false], operator: 'EQ' } + }); + expect(clearSpy).toHaveBeenCalledWith(false); + }); }); }); diff --git a/src/app/modules/angular-slickgrid/services/filter.service.ts b/src/app/modules/angular-slickgrid/services/filter.service.ts index 1b50818d0..7ae7e0ee8 100644 --- a/src/app/modules/angular-slickgrid/services/filter.service.ts +++ b/src/app/modules/angular-slickgrid/services/filter.service.ts @@ -475,13 +475,23 @@ export class FilterService { return this._columnDefinitions; } - updateFilters(filters: CurrentFilter[]) { + /** + * Update Filters dynamically just by providing an array of filter(s). + * You can also choose emit (default) a Filter Changed event that will be picked by the Grid State Service. + * + * Also for backend service only, you can choose to trigger a backend query (default) or not if you wish to do it later, + * this could be useful when using updateFilters & updateSorting and you wish to only send the backend query once. + * @param filters array + * @param triggerEvent defaults to True, do we want to emit a filter changed event? + * @param triggerBackendQuery defaults to True, which will query the backend. + */ + updateFilters(filters: CurrentFilter[], emitChangedEvent = true, triggerBackendQuery = true) { if (!this._filtersMetadata || this._filtersMetadata.length === 0 || !this._gridOptions || !this._gridOptions.enableFiltering) { throw new Error('[Angular-Slickgrid] in order to use "updateFilters" method, you need to have Filterable Columns defined in your grid and "enableFiltering" set in your Grid Options'); } if (Array.isArray(filters)) { - // start by clearing all filters, without trigger an event, before applying any new ones + // start by clearing all filters (without triggering an event) before applying any new filters this.clearFilters(false); // pre-fill (value + operator) and render all filters in the DOM @@ -505,11 +515,15 @@ export class FilterService { const backendApiService = backendApi && backendApi.service; if (backendApiService) { backendApiService.updateFilters(filters, true); - refreshBackendDataset(this._gridOptions); - this.emitFilterChanged(EmitterType.remote); + if (triggerBackendQuery) { + refreshBackendDataset(this._gridOptions); + } } - } else { - this.emitFilterChanged(EmitterType.local); + } + + if (emitChangedEvent) { + const emitterType = backendApi ? EmitterType.remote : EmitterType.local; + this.emitFilterChanged(emitterType); } } }