fix(table): delimit words when filtering (#13487)

This commit is contained in:
Kristiyan Kostadinov
2018-10-19 17:08:00 +02:00
committed by Joey Perrott
parent a54530ac85
commit 2a3599e331
2 changed files with 21 additions and 3 deletions
+9 -3
View File
@@ -173,9 +173,15 @@ export class MatTableDataSource<T> extends DataSource<T> {
*/
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: string, key: string) => currentTerm + (data as {[key: string]: any})[key];
const dataStr = Object.keys(data).reduce(accumulator, '').toLowerCase();
const dataStr = Object.keys(data).reduce((currentTerm: string, key: string) => {
// Use an obscure Unicode character to delimit the words in the concatenated string.
// This avoids matches where the values of two columns combined will match the user's query
// (e.g. `Flute` and `Stop` will match `Test`). The character is intended to be something
// that has a very low chance of being typed in by somebody in a text field. This one in
// particular is "White up-pointing triangle with dot" from
// https://en.wikipedia.org/wiki/List_of_Unicode_characters
return currentTerm + (data as {[key: string]: any})[key] + '◬';
}, '').toLowerCase();
// Transform the filter by converting it to lowercase and removing whitespace.
const transformedFilter = filter.trim().toLowerCase();
+12
View File
@@ -259,6 +259,18 @@ describe('MatTable', () => {
]);
}));
it('should not match concatenated words', fakeAsync(() => {
// Set the value to the last character of the first
// column plus the first character of the second column.
dataSource.filter = '1b';
fixture.detectChanges();
expect(dataSource.filteredData.length).toBe(0);
expectTableToMatchContent(tableElement, [
['Column A', 'Column B', 'Column C'],
['Footer A', 'Footer B', 'Footer C'],
]);
}));
it('should be able to sort the table contents', () => {
// Activate column A sort
component.sort.sort(component.sortHeader);