I am trying to filter Array
data based on multiple columns using only one Pipe
. Right now, It filters first column value. Please check my below code and help me to sort this out.
My Code:
@Pipe({ name: "dataFilter", pure: false })
export class DataFilterPipe implements PipeTransform {
transform(value: Array<any>, filter: any[]) {
if (!filter) {
return value;
} else if (value) {
return value.filter(item => {
for (var i = 0; i < filter.length; i++) {
if (filter[i][1] == undefined) {
return true;
} else if ((typeof item[filter[i][0]] === 'string' || item[filter[i][0]] instanceof String) &&
(item[filter[i][0]].toLowerCase().indexOf(filter[i][1]) !== -1)) {
return true;
}
return false;
}
});
}
}
}
I am passing data like dataFilter : [['column1',value1],['column2',value2],['column3',value3]]
.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With