In my code, I am trying to filter elements from a list and I'm trying to filter that element when I write multiple words at once. Right now, I can filter the element if I write the words in their correct order. For example; I can filter 'red book love' element if I write 'red book' but I also want to filter it when I write 'red love'. Here is my code, what should I do to achieve what I want?
HTML:
<mat-form-field appearance="outline" fxFlex="100" >
<mat-label>Product</mat-label>
<input type="text" required matInput [(ngModel)]="product" name="product"
(input)="onProductSearchChange($event.target.value)" [matAutocomplete]="autoProductId">
<button mat-button matSuffix mat-icon-button aria-label="Clear" (click)="product = null" type="button">
<mat-icon>block</mat-icon>
</button>
<mat-autocomplete autoActiveFirstOption #autoProductId="matAutocomplete"
[displayWith]="displayProduct.bind(this)" (optionSelected)="filterProduct($event.option.value)">
<mat-option *ngFor="let prm of productList" [value]="prm">
{{prm?.StockIntegrationCode ' ' prm?.ProductName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
TS:
onProductSearchChange(search: string) {
let filterValue = (search as any).toLocaleLowerCase("tr");
if (
this._adminService.products &&
this._adminService.products.length > 0
) {
this.productList = this._adminService.products.filter(
(x) =>
x.StockIntegrationCode.indexOf(filterValue) >= 0 ||
(x.ProductName as any)
.toLocaleLowerCase("tr")
.indexOf(filterValue) >= 0
);
}
if (!search) {
this.product = null;
this.productList = this._adminService.products;
}
}
displayProduct(product: IProduct): string | undefined {
return product
? product.StockIntegrationCode " - " product.ProductName
: "";
}
CodePudding user response:
I can't tell if you want ALL of the words to match, or just ONE of the words to match, so here's both solutions. I also have no idea what a stock integration code is, so I'm assuming it counts if there's a match in either the code or the name.
Just one word matches
onProductSearchChange(search: string) {
if (!search) {
this.product = null;
this.productList = this._adminService.products;
return; //Return because the string is empty
}
let filterValue = search.toLocaleLowerCase('tr');
let values = filterValue.split(' ');
if (this._adminService.products && this._adminService.products.length > 0) {
this.productList = this._adminService.products.filter((x) => {
for (const value of values) {
if (
x.StockIntegrationCode.includes(value) ||
x.ProductName.toLocaleLowerCase('tr').includes(value)
)
return true;
}
return false;
});
}
}
All words match
onProductSearchChange(search: string) {
if (!search) {
this.product = null;
this.productList = this._adminService.products;
return; //Return because the string is empty
}
let filterValue = search.toLocaleLowerCase('tr');
let values = filterValue.split(' ');
if (this._adminService.products && this._adminService.products.length > 0) {
this.productList = this._adminService.products.filter((x) => {
for (const value of values) {
if (
!x.StockIntegrationCode.includes(value) &&
!x.ProductName.toLocaleLowerCase('tr').includes(value)
)
return false;
}
return true;
});
}
}
I just split the filterValue on whitespace, and searched word by word.
