typescript MatTable 上的多个过滤器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52007176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple Filters on MatTable
提问by kal93
I've been trying to apply multi column filtering i.e a text input in column headers will filter only on the contents of the column.So far I've been able to make it work by overriding filterPredicate
of MatTableDataSource
but once I override the default filtering which is across columns no longer works.
我一直在尝试应用多列过滤,即列标题中的文本输入将仅过滤列的内容。到目前为止,我已经能够通过覆盖来使其工作filterPredicate
,MatTableDataSource
但是一旦我覆盖了默认过滤跨列不再有效。
export class TableFilteringExample implements OnInit
{
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
dataSource = new MatTableDataSource(ELEMENT_DATA);
positionFilter = new FormControl();
nameFilter = new FormControl();
filteredValues =
{
position: '',
name: '',
weight: '',
symbol: ''
};
ngOnInit()
{
this.positionFilter.valueChanges.subscribe((positionFilterValue) =>
{
this.filteredValues['position'] = positionFilterValue;
this.dataSource.filter = JSON.stringify(this.filteredValues);
});
this.nameFilter.valueChanges.subscribe((nameFilterValue) =>
{
this.filteredValues['name'] = nameFilterValue;
this.dataSource.filter = JSON.stringify(this.filteredValues);
});
this.dataSource.filterPredicate = this.customFilterPredicate();
}
applyFilter(filterValue: string)
{
this.dataSource.filter = filterValue.trim().toLowerCase();
this.dataSource.filter = filterValue;
}
customFilterPredicate()
{
const myFilterPredicate = function(data: PeriodicElement, filter: string): boolean
{
let searchString = JSON.parse(filter);
return data.position.toString().trim().indexOf(searchString.position) !== -1 && data.name.toString().trim().toLowerCase().indexOf(searchString.name)!== -1;
}
return myFilterPredicate;
}
}
What I'm looking for is once column filter is applied the default filter should update the existing filter criteria and return the further filtered data.
我正在寻找的是一旦应用了列过滤器,默认过滤器应该更新现有的过滤条件并返回进一步过滤的数据。
回答by Randal Cunanan
I think you just forgot to call toLowerCase()
for searchString.name
我想,你只是忘了打电话toLowerCase()
的searchString.name
data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase())!== -1;
data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase())!== -1;
EDIT: One approach is to create a global filter field in your Component class.
编辑:一种方法是在您的 Component 类中创建一个全局过滤器字段。
globalFilter = '';
<mat-form-field>
<input matInput [ngModel]="globalFilter" (ngModelChange)="applyFilter($event)" placeholder="Filter">
</mat-form-field>
applyFilter(filter) {
this.globalFilter = filter;
this.dataSource.filter = JSON.stringify(this.filteredValues);
}
Then try to filter using global filter first before the other fields.
然后尝试在其他字段之前首先使用全局过滤器进行过滤。
customFilterPredicate() {
const myFilterPredicate = (data: PeriodicElement, filter: string): boolean => {
var globalMatch = !this.globalFilter;
if (this.globalFilter) {
// search all text fields
globalMatch = data.name.toString().trim().toLowerCase().indexOf(this.globalFilter.toLowerCase()) !== -1;
}
if (!globalMatch) {
return;
}
let searchString = JSON.parse(filter);
return data.position.toString().trim().indexOf(searchString.position) !== -1 &&
data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase()) !== -1;
}
return myFilterPredicate;
}
Here's the working app: https://stackblitz.com/edit/angular-hbakxo-5jeaic
回答by Code Spy
In Angular Material Tables, you can add multi colum filter using filterPredicateproperty on mat-tables and providing them a customFiltermethod as shown below
在 Angular Material Tables 中,您可以使用mat-tables 上的filterPredicate属性添加多列过滤器,并为它们提供customFilter方法,如下所示
Source Link
来源链接
Demo Link
演示链接
ngOnInit() {
// Overrride default filter behaviour of Material Datatable
this.dataSource.filterPredicate = this.createFilter();
}
...
...
// Custom filter method fot Angular Material Datatable
createFilter() {
let filterFunction = function (data: any, filter: string): boolean {
let searchTerms = JSON.parse(filter);
let isFilterSet = false;
for (const col in searchTerms) {
if (searchTerms[col].toString() !== '') {
isFilterSet = true;
} else {
delete searchTerms[col];
}
}
let nameSearch = () => {
let found = false;
if (isFilterSet) {
for (const col in searchTerms) {
searchTerms[col].trim().toLowerCase().split(' ').forEach(word => {
if (data[col].toString().toLowerCase().indexOf(word) != -1 && isFilterSet) {
found = true
}
});
}
return found
} else {
return true;
}
}
return nameSearch()
}
return filterFunction
}