diff --git a/components/doc/common/apidoc/index.json b/components/doc/common/apidoc/index.json index a482a9582a..3115eae269 100644 --- a/components/doc/common/apidoc/index.json +++ b/components/doc/common/apidoc/index.json @@ -13913,7 +13913,7 @@ "name": "matchMode", "optional": false, "readonly": false, - "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", + "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", "description": "Type of filter match." } ], @@ -16328,7 +16328,7 @@ }, { "name": "mode", - "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notContains\" | \"lt\" | \"lte\" | \"gt\" | \"gte\" | \"between\" | \"dateIs\" | \"dateIsNot\" | \"dateBefore\" | \"dateAfter\"", + "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notContains\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\" | \"between\" | \"dateIs\" | \"dateIsNot\" | \"dateBefore\" | \"dateAfter\"", "description": "Filter match mode" }, { @@ -16709,9 +16709,9 @@ "name": "globalFilterMatchMode", "optional": true, "readonly": false, - "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", + "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", "default": "contains", - "description": "Defines filterMatchMode; \"startsWith\", \"contains\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"lt\", \"lte\", \"gt\", \"gte\" and \"custom\"." + "description": "Defines filterMatchMode; \"startsWith\", \"contains\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"notIn\", \"lt\", \"lte\", \"gt\", \"gte\" and \"custom\"." }, { "name": "groupRowsBy", @@ -18639,7 +18639,7 @@ "name": "matchMode", "optional": false, "readonly": false, - "type": "undefined | \"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notContains\" | \"lt\" | \"lte\" | \"gt\" | \"gte\" | \"between\" | \"dateIs\" | \"dateIsNot\" | \"dateBefore\" | \"dateAfter\"", + "type": "undefined | \"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notContains\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\" | \"between\" | \"dateIs\" | \"dateIsNot\" | \"dateBefore\" | \"dateAfter\"", "description": "Type of filter match." } ], @@ -19623,8 +19623,8 @@ "name": "globalFilterMatchMode", "optional": true, "readonly": false, - "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", - "description": "Defines filterMatchMode; \"startsWith\", \"contains\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"lt\", \"lte\", \"gt\", \"gte\" and \"custom\"." + "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", + "description": "Defines filterMatchMode; \"startsWith\", \"contains\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"notIn\", \"lt\", \"lte\", \"gt\", \"gte\" and \"custom\"." }, { "name": "groupRowsBy", @@ -41177,7 +41177,7 @@ "readonly": false, "type": "string", "default": "contains", - "description": "Defines how the items are filtered, valid values are \"contains\" (default) \"startsWith\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"lt\", \"lte\", \"gt\" and \"gte\"." + "description": "Defines how the items are filtered, valid values are \"contains\" (default) \"startsWith\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"notIn\", \"lt\", \"lte\", \"gt\" and \"gte\"." }, { "name": "id", @@ -53153,7 +53153,7 @@ }, { "name": "mode", - "type": "undefined | \"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", + "type": "undefined | \"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", "description": "Filter match mode." } ], @@ -53343,9 +53343,9 @@ "name": "globalFilterMatchMode", "optional": true, "readonly": false, - "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notContains\" | \"lt\" | \"lte\" | \"gt\" | \"gte\" | \"between\" | \"dateIs\" | \"dateIsNot\" | \"dateBefore\" | \"dateAfter\"", + "type": "\"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notContains\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\" | \"between\" | \"dateIs\" | \"dateIsNot\" | \"dateBefore\" | \"dateAfter\"", "default": "contains", - "description": "Defines filterMatchMode; \"startsWith\", \"contains\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"lt\", \"lte\", \"gt\", \"gte\" and \"custom\"." + "description": "Defines filterMatchMode; \"startsWith\", \"contains\", \"endsWith\", \"equals\", \"notEquals\", \"in\", \"notIn\", \"lt\", \"lte\", \"gt\", \"gte\" and \"custom\"." }, { "name": "header", @@ -54762,7 +54762,7 @@ "name": "matchMode", "optional": false, "readonly": false, - "type": "undefined | \"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", + "type": "undefined | \"endsWith\" | \"startsWith\" | \"custom\" | \"contains\" | \"in\" | \"equals\" | \"notEquals\" | \"notIn\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"", "description": "Type of filter match." } ], diff --git a/components/lib/api/FilterService.js b/components/lib/api/FilterService.js index 08842992c3..bedf45bb59 100644 --- a/components/lib/api/FilterService.js +++ b/components/lib/api/FilterService.js @@ -122,6 +122,19 @@ export const FilterService = { return false; }, + notIn(value, filter) { + if (filter === undefined || filter === null || filter.length === 0) { + return true; + } + + for (let i = 0; i < filter.length; i++) { + if (ObjectUtils.equals(value, filter[i])) { + return false; + } + } + + return true; + }, between(value, filter) { if (filter == null || filter[0] == null || filter[1] == null) { return true; diff --git a/components/lib/api/test/FilterService.spec.js b/components/lib/api/test/FilterService.spec.js index 2d4d551102..51e0169a65 100644 --- a/components/lib/api/test/FilterService.spec.js +++ b/components/lib/api/test/FilterService.spec.js @@ -8,20 +8,20 @@ afterEach(() => { }); const checkParametersNullOrUndefined = (filterType) => { - it('When value parameter is undefined', () => { + it('When filter parameter is undefined', () => { expect(filters[filterType]('value', undefined)).toBeTruthy(); }); - it('When value parameter is null', () => { + it('When filter parameter is null', () => { expect(filters[filterType]('value', null)).toBeTruthy(); }); - it('When filter parameter is undefined', () => { + it('When value parameter is undefined', () => { expect(filters[filterType](undefined, 'filter')).toBeFalsy(); }); - it('When filter parameter is null', () => { - expect(filters[filterType](undefined, 'filter')).toBeFalsy(); + it('When value parameter is null', () => { + expect(filters[filterType](null, 'filter')).toBeFalsy(); }); }; @@ -141,6 +141,40 @@ describe('FilterService', () => { }); }); + describe('notIn filter test', () => { + it('When filter parameter is undefined', () => { + expect(filters.notIn('value', undefined)).toBeTruthy(); + }); + + it('When filter parameter is null', () => { + expect(filters.notIn('value', null)).toBeTruthy(); + }); + + it('When value parameter is undefined', () => { + expect(filters.notIn(undefined, 'filter')).toBeTruthy(); + }); + + it('When value parameter is null', () => { + expect(filters.notIn(null, 'filter')).toBeTruthy(); + }); + + it('When value parameter equal to any filter word', () => { + jest.spyOn(ObjectUtils, 'removeAccents').mockImplementation((value, filter) => value === filter); + + const notInFilter = filters.notIn('e', 'filter'); + + expect(notInFilter).toBeFalsy(); + }); + + it('When value parameter not equal to any filter word', () => { + jest.spyOn(ObjectUtils, 'removeAccents').mockImplementation((value, filter) => value === filter); + + const notInFilter = filters.notIn('d', 'filter'); + + expect(notInFilter).toBeTruthy(); + }); + }); + describe('between filter test', () => { checkParametersNullOrUndefined('between'); it('When value has getTime func and smaller than filter[0]', () => { diff --git a/components/lib/column/column.d.ts b/components/lib/column/column.d.ts index 3621252555..5f51fab3ed 100644 --- a/components/lib/column/column.d.ts +++ b/components/lib/column/column.d.ts @@ -682,7 +682,7 @@ interface ColumnFilterMetaData { /** * Type of filter match. */ - matchMode: 'startsWith' | 'contains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte' | 'custom'; + matchMode: 'startsWith' | 'contains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'notIn' | 'lt' | 'lte' | 'gt' | 'gte' | 'custom'; } interface ColumnFilterMetaDataWithConstraint { diff --git a/components/lib/datatable/datatable.d.ts b/components/lib/datatable/datatable.d.ts index 51a7642cdf..8e54490817 100644 --- a/components/lib/datatable/datatable.d.ts +++ b/components/lib/datatable/datatable.d.ts @@ -91,7 +91,7 @@ interface DataTableFilterMetaData { /** * Type of filter match. */ - matchMode: 'startsWith' | 'contains' | 'notContains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter' | 'custom' | undefined; + matchMode: 'startsWith' | 'contains' | 'notContains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'notIn' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter' | 'custom' | undefined; } /** @@ -1173,10 +1173,10 @@ interface DataTableBaseProps extends Omit extends React * Filters the data. * @param {T} value - The filter value * @param {string} field - The filter field - * @param {'startsWith' | 'contains' | 'notContains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter' | 'custom'} mode - Filter match mode + * @param {'startsWith' | 'contains' | 'notContains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'notIn' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter' | 'custom'} mode - Filter match mode * @param {number} index - Index of the filter */ public filter( @@ -1819,7 +1819,7 @@ export declare class DataTable extends React /** * Filter match mode. */ - mode: 'startsWith' | 'contains' | 'notContains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter' | 'custom', + mode: 'startsWith' | 'contains' | 'notContains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'notIn' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter' | 'custom', /** * Index of the filter. */ diff --git a/components/lib/picklist/picklist.d.ts b/components/lib/picklist/picklist.d.ts index c4336af677..36c825069c 100755 --- a/components/lib/picklist/picklist.d.ts +++ b/components/lib/picklist/picklist.d.ts @@ -363,7 +363,7 @@ export interface PickListProps { */ filterBy?: string | undefined; /** - * Defines how the items are filtered, valid values are "contains" (default) "startsWith", "endsWith", "equals", "notEquals", "in", "lt", "lte", "gt" and "gte". + * Defines how the items are filtered, valid values are "contains" (default) "startsWith", "endsWith", "equals", "notEquals", "in", "notIn", "lt", "lte", "gt" and "gte". * @defaultValue contains */ filterMatchMode?: string | undefined; diff --git a/components/lib/treetable/treetable.d.ts b/components/lib/treetable/treetable.d.ts index 4583df72f4..b6dc664262 100644 --- a/components/lib/treetable/treetable.d.ts +++ b/components/lib/treetable/treetable.d.ts @@ -396,7 +396,7 @@ interface TreeTableFilterMetaData { /** * Type of filter match. */ - matchMode: 'startsWith' | 'contains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte' | 'custom' | undefined; + matchMode: 'startsWith' | 'contains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'notIn' | 'lt' | 'lte' | 'gt' | 'gte' | 'custom' | undefined; } /** @@ -676,10 +676,10 @@ export interface TreeTableProps extends Omit { /** * Filter match mode. */ - mode: 'startsWith' | 'contains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte' | 'custom' | undefined + mode: 'startsWith' | 'contains' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'notIn' | 'lt' | 'lte' | 'gt' | 'gte' | 'custom' | undefined ): void; /** * Used to get container element.