I want to build a filter for a list. The Array of Objects for that looks like this:
myList: [
{
"id": 1,
"title":"title",
"city":"city name",
"types":[
{
"id":1,
"name":"type 1 name"
},
{
"id":2,
"name":"type 2 name"
}
],
"properties": [
{
"id": 1,
"name": "prop 1 name"
},
{
"id": 2,
"name": "prop 2 name"
}
]
},
{
"id": 2,
"title":"title2",
"city":"city name",
"types":[
{
"id":1,
"name":"type 1 name"
}
],
"properties": [
{
"id": 2,
"name": "prop 2 name"
},
{
"id": 3,
"name": "prop 3 name"
}
]
},
]
I have select fields with multiple selects on city, type and property.
<form *ngIf="filterForm" [formGroup]="filterForm">
<div >
<div >
<mat-form-field appearance="outline">
<mat-label>filter by city</mat-label>
<mat-select formControlName="filterCity" multiple="true">
<mat-option *ngFor="let city of cities" [value]="city.name">{{city.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div >
<mat-form-field appearance="outline">
<mat-label>filter by type</mat-label>
<mat-select formControlName="filterAdType" multiple="true">
<mat-option *ngFor="let type of Types" [value]="type.name">{{type.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div >
<mat-form-field appearance="outline">
<mat-label>filter by property</mat-label>
<mat-select formControlName="filterProperty" multiple="true">
<mat-option *ngFor="let prop of Properties" [value]="prop.name">{{prop.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div >
<div >
<button mat-button color="primary" (click)='filterSet()'>set filters</button>
</div>
<div >
<button mat-button color="primary" (click)='clearFilters()'>clear filters</button>
</div>
</div>
</form>
and displaying the list in a table
<table *ngIf="myList.length > 0">
<thead>
<tr>
<!-- <th scope="col">#</th> -->
<th scope="col">title</th>
<th scope="col">type</th>
<th scope="col">property</th>
<th scope="col">city</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of myList; let i = index">
<td>
<div>
<strong>{{item.title}}</strong>
</div>
</td>
<td>
<div *ngFor="let type of item.types">
{{type.name}}
</div>
</td>
<td>
<div *ngFor="let prop of item.property">
{{prop.name}}
</div>
</td>
<td>{{item.city}}</td>
</tr>
</tbody>
</table>
So i am struggling with the filter for the multiple selects, the properties and type array. I want to filter the myList. The filterSet() function is empty at the moment.
CodePudding user response:
First take a backup ( using lodash cloneDeep) of the original values, without any filters, then when the filters are applied, filter the backup array apply it to the array displayed on the HTML.
filterSet() {
this.pageList = [];
this.pageList = this.data.filter((x: any) => {
const { filterCity, filterAdType, filterProperty } =
this.filterForm.value;
return (
(filterCity && filterCity.length
? filterCity.includes(x.city)
: true) &&
(filterAdType && filterAdType.length
? filterAdType.includes(x.types.name)
: true) &&
(filterProperty && filterProperty.length
? x.properties.find((item) => filterProperty.includes(item.name))
: true)
);
});
}
Thanks for providing stackblitz, PFB working example. Issue was that dropdown data names, should match the data in the grid!