Filter on multiple columns using one pipe angular 2
Here is a solution using the object passed as multiple columns filter. I found it more convenient then passing a 2D array:
@Pipe({ name: 'filter' }) export class FilterPipe implements PipeTransform { transform(items: Array<any>, filter: {[key: string]: any }): Array<any> { return items.filter(item => { const notMatchingField = Object.keys(filter) .find(key => item[key] !== filter[key]); return !notMatchingField; // true if matches all fields }); } }
Having an array of objects with multiple columns:
this.people = [ {name: 'John', age: 27, sex: 'male'}, {name: 'Lara', age: 21, sex: 'female'}, {name: 'Rick', age: 29, sex: 'male'}, {name: 'Eva', age: 27, sex: 'female'}, {name: 'Mike', age: 27, sex: 'male'}];
And a filter:
this.peopleFilter = {age: 27, sex: 'male'};
Use it like:
<div *ngFor="let person of people | filter: peopleFilter;"></div>
As a result, two people are matching our criteria: John and Mike.
Here is the working plunker: Multiple columns filter pipe demo.
Here is what I did with Angular 8:
Goal: Search on multiple properties say "Property1" and "Property2" from a list of items for a given keyword:
app.module.ts:
......import { MyFilterPipe } from './shared/pipes/my-filter.pipe';@NgModule({ declarations: [ ... MyFilterPipe ], imports: [ ... ], providers: [], bootstrap: [AppComponent]})export class AppModule { }
Pipe: content-filter.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';@Pipe({ name: 'myFilter'})export class MyFilterPipe implements PipeTransform { transform(items: any[], keyword: any, properties: string[]): any[] { if (!items) return []; if (!keyword) return items; debugger; return items.filter(item => { var itemFound: Boolean; for (let i = 0; i < properties.length; i++) { if (item[properties[i]].toLowerCase().indexOf(keyword.toLowerCase()) !== -1) { itemFound = true; break; } } return itemFound; }); }}
component:
<input type="search" class="form-control filter-list-input" placeholder="Filter" aria-label="Filter" name="search" [(ngModel)]="searchText" > <div *ngFor="let itemof myItems | myFilter:searchText:['Property1', 'Property2']; let i = index">...</div>
component.ts:
export class MyListComponent implements OnInit { ... searchText: string;
Replace Your code as below,
export class DataFilterPipe implements PipeTransform { transform(value: Item[], field: string, args: string): Item[]{ let filter: string = args ? args.toLocaleLowerCase() : null; return filter ? value.filter((item : Item) => Item[field].toLocaleLowerCase().indexOf(filter) != -1) : value; }}
In Html page,
<tbody *ngFor="let item of items | dataFilter : columnName : value ">