Filter on Multiple Columns Using One Pipe Angular 2

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.

Filter on multiple columns in a table using one pipe in Angular

Created multiple arguments pipe in angular 4

The code lets you search through multiple columns in your table.

Passed 2 arguments in the transform function


  1. value: Which involves all the data inside the table, all columns
  2. searchString: What you want to search inside the columns (inside the table).

Hence, you can define which columns to be searched inside the transform function.

In this case, the columns to be searched are builderId, groupName and companyPersonName

Pipe file

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: "arrayFilter"
})

export class BuilderFilterPipe implements PipeTransform {

transform(value:any[],searchString:string ){

if(!searchString){
console.log('no search')
return value
}

return value.filter(it=>{
const builderId = it.builderId.toString().includes(searchString)
const groupName = it.groupName.toLowerCase().includes(searchString.toLowerCase())
const companyPersonName = it.companyPersonName.toLowerCase().includes(searchString.toLowerCase())
console.log( builderId + groupName + companyPersonName);
return (builderId + groupName + companyPersonName );
})
}
}

What does the transform function do?


  1. builderId, groupName and companyPersonName are the three fields I searched

  2. builderId converted to string because our searchString is in string format.

  3. toLowerCase() is used to make search accurate irrespective of user search in lowercase or uppercase

Html:

  <tr *ngFor = "let builder of newBuilderDetailsArray | arrayFilter:search" >
<td>{{builder.builderId}}</td>
<td>{{builder.groupName}}</td>
<td>{{builder.companyPersonName}}</td>
</tr>

Sample Image

Sample Image

Make sure your filter.ts file added to module.ts file

Use existing filter to filter on multiple columns in angular

You can also pass an object to your pipe. Something like this:

<div *ngFor="let x of issues | FilterPipe: {ticketNumber, someKey: someValue}">
{{x | json}}
</div>

input in your pipe will contain that values and you can use them all.

A side note: I would recommend naming variables based on context. eg. issue of issues instead of x of issues and TicketFilterPipe instead of FilterPipe, etc...

angular filter pipe on multiple values of table columns

Your code logic bug is that you are returning true if any of the filters match when you want to only return true if all the filters match.

stackblitz

transform(vList: any[], vfilter?: any): any {
if (!vList || !Object.keys(vfilter).length) {
return vList;
}
return vList.filter(item => {
return Object.keys(vfilter)
.filter(_ => vfilter.hasOwnProperty(_))
.every(key => {
if(!item[key]) return true; // matches undefined value
const arrayValues = vfilter[key] as any[];
return arrayValues.some(_ => _ === item[key]);
});
});
}

How to set or condition in filtering multiple columns using Angular pipe

<tr *ngFor="let bot of bots | filter : searchString;">

just remove this : 'id' and it will work on all the fields!

EDIT1:

Please update your filter as per this

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'filter',
pure: false
})
export class FilterPipe implements PipeTransform {
transform(items: any[], term): any {
console.log('term', term);

return term
? items.filter(item => item.title.indexOf(term) !== -1)
: items;
}
}

just to update this line cause problem for you

if (!field || !value) {
return items;
}

Using multiple fields on Filter Pipe | Angular 4

You can pass an object instead of multiple fields:

<li *ngFor="let member of members | filter: filters">

In your component's class:

filters: any = { name: "ex", country: "a country" };

UPDATE:

<input type="text" [(ngModel)] = "fields.name" (ngModelChange)="updateFilters()"/>
<input type="text" [(ngModel)] = "fields.country" (ngModelChange)="updateFilters()"/>

In your component:

fields: any  = { name: "", country: "" };
filters: any = { name: "", country: "" };

updateFilters(): void {
this.filters = Object.assign({}, this.fields);
}

Filter on columns using one pipe with array of values angular 2

I tested this in your stackblitz it's not in edit mode :(.

Here is the code I added and extra variable on the component scope this.filteredData:any[] = [];

this.filterData.model=["Swift", "zen"];

for(let i = 0; i < this.filterData.model.length; i++){
let products = this.products.filter((product: any) =>
product.model.toLowerCase().indexOf(this.filterData.model[i].toLowerCase()) === 0);
for(let j = 0; j < products.length; j++){
this.filteredData.push(products[j]);
}
}
console.log(this.filteredData);


Related Topics



Leave a reply



Submit