J'ai essayé d'appliquer un filtrage multi-colonnes, c'est-à-dire qu'une entrée de texte dans les en-têtes de colonne ne filtrerait que le contenu de la colonne. Jusqu'à présent, j'ai pu le faire fonctionner en remplaçant filterPredicate
of MatTableDataSource
mais une fois que j'ai outrepassé le filtrage par défaut qui est à travers les colonnes ne fonctionne plus.
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;
}
}
Ce que je recherche, c'est qu'une fois le filtre de colonne appliqué, le filtre par défaut doit mettre à jour les critères de filtre existants et renvoyer les données filtrées supplémentaires.
Je pense que vous avez juste oublié d'appeler toLowerCase()
pour searchString.name
data.name.toString (). trim (). toLowerCase (). indexOf (searchString.name.toLowerCase ())! == -1;
EDIT: Une approche consiste à créer un champ de filtre global dans votre classe 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);
}
Essayez ensuite de filtrer à l'aide du filtre global avant les autres champs.
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;
}
Voici l'application de travail: https://stackblitz.com/edit/angular-hbakxo-5jeaic
Dans Angular Material Tables, vous pouvez ajouter un filtre multi-colonnes en utilisant la propriété filterPredicate sur les tables mat et en leur fournissant un méthode customFilter comme indiqué ci-dessous
Source Lien
Démo Lien
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
}