web-dev-qa-db-fra.com

Filtrage de colonne spécifique dans la table des matériaux angulaires dans la forme angulaire 5

Dans le site officiel Angular Material, il est mentionné que filterPredicate: ((data: T, filter: string) => boolean) filtrera les données en fonction du champ spécifique. Mais ne pas savoir comment commencer. 

J'ai vu des exemples mais je n'ai pas: - https://stackblitz.com/edit/angular-material2-table?file=app%2Fapp.component.html

Par défaut, il filtre en fonction de l'objet entier, mais je souhaite effectuer une recherche uniquement en fonction d'une propriété unique de json.

7
Nidhi

J'ai réussi à faire comme ça:

this.dataSource.filterPredicate = (data, filter) =>
      (data.name.indexOf(filter) !== -1 ||
        data.id.indexOf(filter) !== -1 );
  }
10
alin0509

Déclarez simplement une fonction avec la déclaration suivante dans votre composant, puis affectez-la à DataSource.filterPredicate. Pour utiliser le filtre, assignez simplement une chaîne à la propriété DataSource.filter.

  customFilter(Data: T, Filter: string): boolean {
    return <true if Data matches filter>
  }
7
Eduardo Mauro

Filtres de travail sur chaque colonne, lien de démonstration Stackblitz .

Pour filtrer une colonne spécifique dans mat-table, ajoutez un champ de recherche pour la colonne comme ci-dessous;

<mat-form-field class="filter" floatLabel="never">
    <mat-label>Search</mat-label>
    <input matInput [formControl]="nameFilter">
  </mat-form-field>

Et nous connectons les entrées à FormControls à partir du ReactiveFormsModule.

filterValues = {
name: '',
id: '',
colour: '',
pet: ''

};

Et nous surveillerons la valeur des entrées de filtre et modifierons cet objet filtre et la propriété de filtre de la source de données lorsqu’ils changeront. Nous devons affecter la version sous forme de chaîne de l’objet filtre à la propriété de filtrage de la source de données.

ngOnInit() {
this.nameFilter.valueChanges
  .subscribe(
    name => {
      this.filterValues.name = name;
      this.dataSource.filter = JSON.stringify(this.filterValues);
    }
  )
this.idFilter.valueChanges
  .subscribe(
    id => {
      this.filterValues.id = id;
      this.dataSource.filter = JSON.stringify(this.filterValues);
    }
  )
this.colourFilter.valueChanges
  .subscribe(
    colour => {
      this.filterValues.colour = colour;
      this.dataSource.filter = JSON.stringify(this.filterValues);
    }
  )
this.petFilter.valueChanges
  .subscribe(
    pet => {
      this.filterValues.pet = pet;
      this.dataSource.filter = JSON.stringify(this.filterValues);
    }
  )

}

Nous devons modifier le filterPredicate de la source de données pour lui indiquer comment interpréter les informations de filtre.

constructor() {
this.dataSource.data = this.people;
this.dataSource.filterPredicate = this.tableFilter();
}

tableFilter(): (data: any, filter: string) => boolean {
let filterFunction = function(data, filter): boolean {
  let searchTerms = JSON.parse(filter);
  return data.name.toLowerCase().indexOf(searchTerms.name) !== -1
    && data.id.toString().toLowerCase().indexOf(searchTerms.id) !== -1
    && data.colour.toLowerCase().indexOf(searchTerms.colour) !== -1
    && data.pet.toLowerCase().indexOf(searchTerms.pet) !== -1;
}
return filterFunction;

}

0
Naresh Chennuri

Vous pouvez filtrer par une colonne dynamique, comme dans pas de nom de colonne codé en dur , en procédant comme suit:

// On input focus: setup filterPredicate to only filter by input column
setupFilter(column: string) {
  this.dataSource.filterPredicate = (d: TableDataSourceType, filter: string) => {
    const textToSearch = d[column] && d[column].toLowerCase() || '';
    return textToSearch.indexOf(filter) !== -1;
  };
}

applyFilter(filterValue: string) {
  this.dataSource.filter = filterValue.trim().toLowerCase();
}

Dans le modèle, vous pouvez avoir quelque chose comme ça:

<ng-container matColumnDef="item-filter">
  <th mat-header-cell *matHeaderCellDef>
    <input (keyup)="applyFilter($event.target.value)" (focus)="setupFilter('name')" />
  </th>
</ng-container>

Ou, pour un exemple plus complexe, créez dynamiquement une ligne d’en-tête avec filtrage par colonne:

<table mat-table [dataSource]="dataSource">
   <ng-container *ngFor="let filterCol of ['names', 'age', 'address']">
     <ng-container matColumnDef="filterCol">
       <th mat-header-cell *matHeaderCellDef>
         <input (keyup)="applyFilter($event.target.value)" (focus)="setupFilter(filterCol)"/>
       </th>
     </ng-container>
   </ng-container>

   <tr mat-header-row *matHeaderRowDef="['names', 'age', 'address']"></tr>
</table>

Sachez que vous ne pouvez pas avoir plusieurs lignes d’en-tête avec les mêmes clés, cela ne fonctionnera donc pas:

<tr mat-header-row *matHeaderRowDef="['names', 'age', 'address']"></tr>
<tr mat-header-row *matHeaderRowDef="['names', 'age', 'address']"></tr>
0
Rui Marques