如何使用 accents/diacritics 过滤 MatTable?
How can I filter a MatTable with accents/diacritics?
我想过滤 table 的名称,无论用户是否输入了任何重音符号。
例如:
如果用户输入 "hydrogen",结果应该是 "Hydrôgen",因为它在 table.
我使用 Angular 8.1.3 和 Angular Material 8.0.1
这是我的代码:
app.component.html:
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" (focus)="setupFilter('name')" placeholder="Filter">
</mat-form-field>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
...
我的界面:
export interface PeriodicElement {
name: string;
position: number;
weight: number;
symbol: string;
}
app.component.ts:
const ELEMENT_DATA: PeriodicElement[] = [
{position: 1, name: 'Hydrôgen', weight: 1.0079, symbol: 'H'},
{position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
{position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
{position: 4, name: 'Béryllium', weight: 9.0122, symbol: 'Be'},
{position: 5, name: 'Bóron', weight: 10.811, symbol: 'B'},
{position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
{position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
{position: 8, name: 'ÔLxygen', weight: 15.9994, symbol: 'O'},
{position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
{position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
];
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
dataSource = new MatTableDataSource(ELEMENT_DATA);
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
setupFilter(column: string) {
this.dataSource.filterPredicate = (d: any, filter: string) => {
const textToSearch = d[column] && d[column].toLowerCase() || '';
return textToSearch.indexOf(filter) !== -1;
};
}
public removeAccents(str: string): string {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
我希望当用户输入 "bo" 时显示在 table 2 行中,其中包含 "Carbon" 和 "Bóron".
这是 Angular material 在 mat-table
中使用过滤时使用的代码
filterPredicate: ((data: T, filter: string) => boolean) = (data: T, filter: string): boolean => {
// Transform the data into a lowercase string of all property values.
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();
return dataStr.indexOf(transformedFilter) != -1;
}
让我们继续修改这个 filterPredicate()
到你需要的。您已经展示了如何删除代码中的重音符号和变音符号。我们将在新的 filterPredicate
.
中使用它
this.dataSource.filterPredicate = (data: PeriodicElement, filter: string): boolean => {
const dataStr = Object.keys(data).reduce((currentTerm: string, key: string) => {
return (currentTerm + (data as { [key: string]: any })[key] + '◬');
}, '').normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
const transformedFilter = filter.trim().normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
return dataStr.indexOf(transformedFilter) != -1;
}
}
我们从 table 中的值以及过滤器值中删除 accents/diacritics,这样即使用户碰巧输入具有 accents/diacritics 的字符,过滤器也会继续正确过滤。
这是 StackBlitz 上的一个工作示例。
我想过滤 table 的名称,无论用户是否输入了任何重音符号。
例如:
如果用户输入 "hydrogen",结果应该是 "Hydrôgen",因为它在 table.
我使用 Angular 8.1.3 和 Angular Material 8.0.1
这是我的代码:
app.component.html:
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" (focus)="setupFilter('name')" placeholder="Filter">
</mat-form-field>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
...
我的界面:
export interface PeriodicElement {
name: string;
position: number;
weight: number;
symbol: string;
}
app.component.ts:
const ELEMENT_DATA: PeriodicElement[] = [
{position: 1, name: 'Hydrôgen', weight: 1.0079, symbol: 'H'},
{position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
{position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
{position: 4, name: 'Béryllium', weight: 9.0122, symbol: 'Be'},
{position: 5, name: 'Bóron', weight: 10.811, symbol: 'B'},
{position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
{position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
{position: 8, name: 'ÔLxygen', weight: 15.9994, symbol: 'O'},
{position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
{position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
];
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
dataSource = new MatTableDataSource(ELEMENT_DATA);
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
setupFilter(column: string) {
this.dataSource.filterPredicate = (d: any, filter: string) => {
const textToSearch = d[column] && d[column].toLowerCase() || '';
return textToSearch.indexOf(filter) !== -1;
};
}
public removeAccents(str: string): string {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
我希望当用户输入 "bo" 时显示在 table 2 行中,其中包含 "Carbon" 和 "Bóron".
这是 Angular material 在 mat-table
filterPredicate: ((data: T, filter: string) => boolean) = (data: T, filter: string): boolean => {
// Transform the data into a lowercase string of all property values.
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();
return dataStr.indexOf(transformedFilter) != -1;
}
让我们继续修改这个 filterPredicate()
到你需要的。您已经展示了如何删除代码中的重音符号和变音符号。我们将在新的 filterPredicate
.
this.dataSource.filterPredicate = (data: PeriodicElement, filter: string): boolean => {
const dataStr = Object.keys(data).reduce((currentTerm: string, key: string) => {
return (currentTerm + (data as { [key: string]: any })[key] + '◬');
}, '').normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
const transformedFilter = filter.trim().normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
return dataStr.indexOf(transformedFilter) != -1;
}
}
我们从 table 中的值以及过滤器值中删除 accents/diacritics,这样即使用户碰巧输入具有 accents/diacritics 的字符,过滤器也会继续正确过滤。
这是 StackBlitz 上的一个工作示例。