diff --git a/src/demo-app/table/table-demo.ts b/src/demo-app/table/table-demo.ts index efecfc9e6995..691190cb73dc 100644 --- a/src/demo-app/table/table-demo.ts +++ b/src/demo-app/table/table-demo.ts @@ -60,7 +60,8 @@ export class TableDemo { default: return ''; } }; - this.matTableDataSource.filterTermAccessor = (data: UserData) => data.name; + this.matTableDataSource.filterPredicate = + (data: UserData, filter: string) => data.name.indexOf(filter) != -1; this.filter.valueChanges.subscribe(filter => this.matTableDataSource!.filter = filter); } diff --git a/src/lib/table/table-data-source.ts b/src/lib/table/table-data-source.ts index 14852a5f570f..eb215d05fc80 100644 --- a/src/lib/table/table-data-source.ts +++ b/src/lib/table/table-data-source.ts @@ -44,7 +44,7 @@ export class MatTableDataSource implements DataSource { /** * Filter term that should be used to filter out objects from the data array. To override how - * the filter matches data objects, provide a custom function on filterTermAccessor. + * data objects match to this filter string, provide a custom function for filterPredicate. */ set filter(filter: string) { this._filter.next(filter); } get filter(): string { return this._filter.value; } @@ -91,14 +91,24 @@ export class MatTableDataSource implements DataSource { } /** - * Transforms data objects into a filter term that will be used to check against the filter if - * a filter is set. By default, the function will iterate over the values of the data object - * and convert them to a lowercase string. - * @param data Data object to convert to a string that checked for containing the filter term. + * Checks if a data object matches the data source's filter string. By default, each data object + * is converted to a string of its properties and returns true if the filter has + * at least one occurrence in that string. By default, the filter string has its whitespace + * trimmed and the match is case-insensitive. May be overriden for a custom implementation of + * filter matching. + * @param data Data object used to check against the filter. + * @param filter Filter string that has been set on the data source. + * @returns Whether the filter matches against the data */ - filterTermAccessor: ((data: T) => string) = (data: T): string => { + filterPredicate: ((data: T, filter: string) => boolean) = (data: T, filter: string): boolean => { + // Transform the data into a lowercase string of all property values. const accumulator = (currentTerm, key) => currentTerm + data[key]; - return Object.keys(data).reduce(accumulator, '').toLowerCase(); + const dataStr = Object.keys(data).reduce(accumulator, '').toLowerCase(); + + // Transform the filter by converting it to lowercase and removing whitespace. + const transformedFilter = filter.trim().toLowerCase(); + + return dataStr.indexOf(transformedFilter) != -1; } constructor(initialData: T[] = []) { @@ -141,9 +151,8 @@ export class MatTableDataSource implements DataSource { // If there is a filter string, filter out data that does not contain it. // Each data object is converted to a string using the function defined by filterTermAccessor. // May be overriden for customization. - const filteredData = !this.filter ? data : data.filter(obj => { - return this.filterTermAccessor(obj).indexOf(this.filter) != -1; - }); + const filteredData = + !this.filter ? data : data.filter(obj => this.filterPredicate(obj, this.filter)); if (this.paginator) { this._updatePaginator(filteredData.length); } diff --git a/src/lib/table/table.spec.ts b/src/lib/table/table.spec.ts index 39949cf92b19..eac0a880fff9 100644 --- a/src/lib/table/table.spec.ts +++ b/src/lib/table/table.spec.ts @@ -109,8 +109,8 @@ describe('MatTable', () => { flushMicrotasks(); // Resolve promise that updates paginator's length expect(dataSource.paginator!.length).toBe(1); - // Change filter to a_2, should match one row - dataSource.filter = 'a_2'; + // Change filter to ' A_2 ', should match one row (ignores case and whitespace) + dataSource.filter = ' A_2 '; fixture.detectChanges(); expectTableToMatchContent(tableElement, [ ['Column A', 'Column B', 'Column C'], @@ -127,14 +127,17 @@ describe('MatTable', () => { ['a_3', 'b_3', 'c_3'], ]); - // Change filter function and filter, should match to rows. - dataSource.filterTermAccessor = data => { + // Change filter function and filter, should match to rows with zebra. + dataSource.filterPredicate = (data, filter) => { + let dataStr; switch (data.a) { - case 'a_1': return 'elephant'; - case 'a_2': return 'zebra'; - case 'a_3': return 'monkey'; - default: return ''; + case 'a_1': dataStr = 'elephant'; break; + case 'a_2': dataStr = 'zebra'; break; + case 'a_3': dataStr = 'monkey'; break; + default: dataStr = ''; } + + return dataStr.indexOf(filter) != -1; }; dataSource.filter = 'zebra'; fixture.detectChanges();