Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/examples/grid-draggrouping.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ export class GridDraggableGroupingComponent implements OnInit {
showPreHeaderPanel: true,
preHeaderPanelHeight: 40,
enableFiltering: true,
// you could debounce/throttle the input text filter if you have lots of data
// filterTypingDebounce: 250,
enableSorting: true,
exportOptions: {
sanitizeDataExport: true
Expand Down
2 changes: 2 additions & 0 deletions src/app/examples/grid-grouping.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export class GridGroupingComponent implements OnInit {
},
enableExcelExport: true,
enableFiltering: true,
// you could debounce/throttle the input text filter if you have lots of data
// filterTypingDebounce: 250,
enableGrouping: true,
exportOptions: {
sanitizeDataExport: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
private executeAfterDataviewCreated(grid: any, gridOptions: GridOption, dataView: any) {
// if user entered some Sort "presets", we need to reflect them all in the DOM
if (gridOptions.enableSorting) {
if (gridOptions.presets && Array.isArray(gridOptions.presets.sorters) && gridOptions.presets.sorters.length > 0) {
if (gridOptions.presets && Array.isArray(gridOptions.presets.sorters)) {
this.sortService.loadGridSorters(gridOptions.presets.sorters);
}
}
Expand Down Expand Up @@ -1018,7 +1018,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
private loadPresetsWhenDatasetInitialized() {
if (this.gridOptions && !this.customDataView) {
// if user entered some Filter "presets", we need to reflect them all in the DOM
if (this.gridOptions.presets && Array.isArray(this.gridOptions.presets.filters) && this.gridOptions.presets.filters.length > 0) {
if (this.gridOptions.presets && Array.isArray(this.gridOptions.presets.filters)) {
this.filterService.populateColumnFilterSearchTermPresets(this.gridOptions.presets.filters);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TestBed } from '@angular/core/testing';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

import { Column, FilterArguments, FieldType, GridOption, OperatorType } from '../../models';
import { BackendServiceApi, Column, FilterArguments, FieldType, GridOption, OperatorType, } from '../../models';
import { Filters } from '..';
import { CompoundInputFilter } from '../compoundInputFilter';

Expand Down Expand Up @@ -119,7 +119,7 @@ describe('CompoundInputFilter', () => {
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

filterInputElm.focus();
filterInputElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterInputElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.search-filter.filter-duration.filled');

expect(filterFilledElms.length).toBe(1);
Expand All @@ -143,23 +143,6 @@ describe('CompoundInputFilter', () => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '', searchTerms: ['abc'], shouldTriggerQuery: true });
});

it('should call "setValues" and expect that value NOT to be in the callback when triggered by a keyup event that is NOT the ENTER key', () => {
const spyCallback = jest.spyOn(filterArguments, 'callback');

filter.init(filterArguments);
filter.setValues(['abc']);
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

filterInputElm.focus();
const event = new (window.window as any).Event('keyup', { bubbles: true, cancelable: true });
event.key = 'a';
filterInputElm.dispatchEvent(event);
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('.search-filter.filter-duration.filled');

expect(filterFilledElms.length).toBe(0);
expect(spyCallback).not.toHaveBeenCalled();
});

it('should call "setValues" with "operator" set in the filter arguments and expect that value to be in the callback when triggered', () => {
mockColumn.type = FieldType.number;
const filterArgs = { ...filterArguments, operator: '>' } as FilterArguments;
Expand All @@ -170,7 +153,7 @@ describe('CompoundInputFilter', () => {
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

filterInputElm.focus();
filterInputElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterInputElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));

expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '>', searchTerms: ['9'], shouldTriggerQuery: true });
});
Expand Down Expand Up @@ -215,7 +198,7 @@ describe('CompoundInputFilter', () => {
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

filterInputElm.focus();
filterInputElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterInputElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));

expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '>', searchTerms: ['987'], shouldTriggerQuery: true });
});
Expand All @@ -232,7 +215,7 @@ describe('CompoundInputFilter', () => {
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

filterInputElm.focus();
filterInputElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterInputElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));

expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '>', searchTerms: ['987'], shouldTriggerQuery: true });
});
Expand All @@ -245,11 +228,49 @@ describe('CompoundInputFilter', () => {

filterInputElm.focus();
filterInputElm.value = 'a';
filterInputElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterInputElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));

expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '', searchTerms: ['a'], shouldTriggerQuery: true });
});

it('should trigger the callback method with a delay when "filterTypingDebounce" is set in grid options and user types something in the input', (done) => {
const spyCallback = jest.spyOn(filterArguments, 'callback');
gridOptionMock.filterTypingDebounce = 2;

filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

filterInputElm.focus();
filterInputElm.value = 'a';
filterInputElm.dispatchEvent(new (window.window as any).Event('keyup', { key: 'a', keyCode: 97, bubbles: true, cancelable: true }));

setTimeout(() => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '', searchTerms: ['a'], shouldTriggerQuery: true });
done();
}, 2);
});

it('should trigger the callback method with a delay when BackendService is used with a "filterTypingDebounce" is set in grid options and user types something in the input', (done) => {
const spyCallback = jest.spyOn(filterArguments, 'callback');
gridOptionMock.defaultBackendServiceFilterTypingDebounce = 2;
gridOptionMock.backendServiceApi = {
filterTypingDebounce: 2,
service: {}
} as unknown as BackendServiceApi;

filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

filterInputElm.focus();
filterInputElm.value = 'a';
filterInputElm.dispatchEvent(new (window.window as any).Event('keyup', { key: 'a', keyCode: 97, bubbles: true, cancelable: true }));

setTimeout(() => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '', searchTerms: ['a'], shouldTriggerQuery: true });
done();
}, 2);
});

it('should create the input filter with a default search term when passed as a filter argument', () => {
filterArguments.searchTerms = ['xyz'];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InputFilter } from '../inputFilter';
import { GridOption, FilterArguments, Column } from '../../models';
import { BackendServiceApi, Column, FilterArguments, GridOption, } from '../../models';
import { Filters } from '..';

const containerId = 'demo-container';
Expand Down Expand Up @@ -78,7 +78,7 @@ describe('InputFilter', () => {
const filterElm = divContainer.querySelector('input.filter-duration') as HTMLInputElement;

filterElm.focus();
filterElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('input.filter-duration.filled');

expect(filterFilledElms.length).toBe(1);
Expand All @@ -102,23 +102,6 @@ describe('InputFilter', () => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '', searchTerms: ['abc'], shouldTriggerQuery: true });
});

it('should call "setValues" and expect that value NOT to be in the callback when triggered by a keyup event that is NOT the ENTER key', () => {
const spyCallback = jest.spyOn(filterArguments, 'callback');

filter.init(filterArguments);
filter.setValues('abc');
const filterElm = divContainer.querySelector('input.filter-duration') as HTMLInputElement;

filterElm.focus();
const event = new (window.window as any).Event('keyup', { bubbles: true, cancelable: true });
event.key = 'a';
filterElm.dispatchEvent(event);
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('input.filter-duration.filled');

expect(filterFilledElms.length).toBe(0);
expect(spyCallback).not.toHaveBeenCalled();
});

it('should call "setValues" an operator and with extra spaces at the beginning of the searchTerms and trim value when "enableFilterTrimWhiteSpace" is enabled in grid options', () => {
gridOptionMock.enableFilterTrimWhiteSpace = true;
const spyCallback = jest.spyOn(filterArguments, 'callback');
Expand All @@ -128,7 +111,7 @@ describe('InputFilter', () => {
const filterElm = divContainer.querySelector('input.filter-duration') as HTMLInputElement;

filterElm.focus();
filterElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('input.filter-duration.filled');

expect(filterFilledElms.length).toBe(1);
Expand All @@ -145,7 +128,7 @@ describe('InputFilter', () => {
const filterElm = divContainer.querySelector('input.filter-duration') as HTMLInputElement;

filterElm.focus();
filterElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
const filterFilledElms = divContainer.querySelectorAll<HTMLInputElement>('input.filter-duration.filled');

expect(filterFilledElms.length).toBe(1);
Expand Down Expand Up @@ -201,11 +184,48 @@ describe('InputFilter', () => {

filterElm.focus();
filterElm.value = 'a';
filterElm.dispatchEvent(new (window.window as any).Event('input', { keyCode: 97, bubbles: true, cancelable: true }));
filterElm.dispatchEvent(new (window.window as any).Event('keyup', { keyCode: 97, bubbles: true, cancelable: true }));

expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'EQ', searchTerms: ['a'], shouldTriggerQuery: true });
});

it('should trigger the callback method with a delay when "filterTypingDebounce" is set in grid options and user types something in the input', (done) => {
const spyCallback = jest.spyOn(filterArguments, 'callback');
gridOptionMock.filterTypingDebounce = 2;

filter.init(filterArguments);
const filterElm = divContainer.querySelector('input.filter-duration') as HTMLInputElement;

filterElm.focus();
filterElm.value = 'a';
filterElm.dispatchEvent(new (window.window as any).Event('keyup', { key: 'a', keyCode: 97, bubbles: true, cancelable: true }));

setTimeout(() => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'EQ', searchTerms: ['a'], shouldTriggerQuery: true });
done();
}, 2);
});

it('should trigger the callback method with a delay when BackendService is used with a "filterTypingDebounce" is set in grid options and user types something in the input', (done) => {
const spyCallback = jest.spyOn(filterArguments, 'callback');
gridOptionMock.defaultBackendServiceFilterTypingDebounce = 2;
gridOptionMock.backendServiceApi = {
service: {}
} as unknown as BackendServiceApi;

filter.init(filterArguments);
const filterElm = divContainer.querySelector('input.filter-duration') as HTMLInputElement;

filterElm.focus();
filterElm.value = 'a';
filterElm.dispatchEvent(new (window.window as any).Event('keyup', { key: 'a', keyCode: 97, bubbles: true, cancelable: true }));

setTimeout(() => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'EQ', searchTerms: ['a'], shouldTriggerQuery: true });
done();
}, 2);
});

it('should create the input filter with a default search term when passed as a filter argument', () => {
filterArguments.searchTerms = ['xyz'];

Expand Down
Loading