I have an Angular table with three columns. In the table header, all these three columns have three input fields.
Three inputs: Stock Number, Case, Availability.
User can search with Single Input(Stock Number OR Case OR Availability), two inputs(AND condition of any 2 inputs) or all three inputs(AND of all 3 inputs).
I have written code for 3 inputs scenario with AND operator. How to change this logic to all input usecases?
I am looking for a solution, where if the user enters three inputs {stockNumber: 'XYZ5000', caseNum: '1991', availability: 'AVAILABLE'}. It has to be compared with stockDetailsList(in stock response object) and collect the filtered result in another stock object(Just print filtered stock bject in console.log).
AppComponent
file:
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { MatTableDataSource } from '@angular/material/table';
const stock:any[] = [
{
stockId: 'XYZ5000', stockDetailsList: [
{stockNumber: 'XYZ5000', caseNum: '1991', availability: 'AVAILABLE'},
{stockNumber: 'XYZ5000', caseNum: '2001', availability: 'AVAILABLE'},
{stockNumber: 'XYZ5000', caseNum: '2023', availability: 'AVAILABLE'},
{stockNumber: 'XYZ5000', caseNum: '2000', availability: 'NOTAVAILABLE'},
{stockNumber: 'XYZ5000', caseNum: '1997', availability: 'AVAILABLE'},
{stockNumber: 'XYZ5000', caseNum: '2015', availability: 'AVAILABLE'}
],
},
{
stockId: 'XYZ1000', stockDetailsList: [{stockNumber: 'XYZ1000', caseNum: '2015', availability: 'AVAILABLE'}
],
},
{
stockId: 'XYZ4000, NEW.', stockDetailsList: [{stockNumber: 'XYZ4000', caseNum: '2012', availability: 'AVAILABLE'}
],
}
];
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
title = 'MultiInputFilters';
stockForm!: FormGroup;
pageList:any[] = [];
public displayedColumns: string[] = ['stockId', 'caseNum', 'availability'];
public dataSource = new MatTableDataSource<any>([]);
constructor() {
this.stockForm = new FormGroup({
stockNumber: new FormControl(),
caseNum: new FormControl(),
availability: new FormControl(),
});
}
ngOnInit(): void {
const objectArray: any[] = [];
this.generateTableRows(stock, objectArray);
this.dataSource = new MatTableDataSource(objectArray);
}
public generateTableRows(stock: any[], objectArray: any[]): void {
stock.forEach(s => {
objectArray.push({ stockId: s.stockId });
if (s.stockDetailsList?.length) {
s.stockDetailsList.forEach((x: any) => objectArray.push({
stockNumber: x.stockNumber,
caseNum: x.caseNum,
availability: x.availability,
}))
}
});
console.log('generateTableRows objectArray: '+ objectArray);
}
applyFilter() {
this.pageList = [];
const objectArray: any[] = [];
const { stockNumber, caseNum , availability } = this.stockForm.value;
this.pageList = stock.filter(s => {
s.stockDetailsList.filter((x: any) => {
if (((stockNumber && stockNumber.includes(x.stockNumber))) && (caseNum && caseNum.includes(x.caseNum)) && (availability && availability.includes(x.availability))) {
objectArray.push({ stockId: s.stockId });
objectArray.push({
stockNumber: x.stockNumber,
caseNum: x.caseNum,
availability: x.availability,
})
}
});
});
console.log("applyFilter objectArray: "+ objectArray);
this.dataSource = new MatTableDataSource(objectArray);
//this.dataSource.filter = JSON.stringify(objectArray); => this.dataSource.filter is preferable than MatTableDataSource
}
}
Stackblitz of complete project: https://stackblitz.com/edit/angular-ivy-38zpmg?file=src%2Fapp%2Fapp.component.ts, https://angular-ivy-38zpmg.stackblitz.io
Technologies used:
customFilter = (data: PeriodicElement, filter: string) => {
const filterData = JSON.parse(filter);
//filterData will be like: {stockNumber:..,caseNum:..,availability:...,name:...}
bool find=!filterData.stockNumber || filterData.stockNumber.includes(data.stockNumber);
find=find && (!filterData.caseNum || filterData.caseNum.includes(data.caseNum)
find=find && (!filterData.availability|| filterData.availability.includes(data.availability)
find=find && (!filterData.name|| data.name.indexOf(filterData.name)>=0)
return find
};