简体   繁体   中英

Dynamic Search Filter in Angular 7

I want to write a generic filter in angular 7 to perform search filter operation on any field in any number of screens. I have found some links suggesting writing custom pipe filters but they always filter based on particular static field.

To explain more, I have around 20 screens in my project. Each screen is making an API call , fetching data and displaying on the UI ,like one is device screen showing data for fields:

deviceId, deviceHardwareNumber, deviceSoftwareNumber, deviceVendor, devicePurchaseDate

Another screen for deviceServiceDetails

deviceId, deviceServiceProvider, deviceServiceDate, nextServiceDueDate

Now either I can write 20 filters for 20 screens for filtering on different field names or is there any way possible for writing only one filter for all the screens and filtering on any field.

Is there a way to make it dynamic by writing one filter irrespective of the number of screens, ie any list or searchText passed from any screen should be filtered and returned?

It 's hard to create a filter to handle every case scenario but I did something to handle string value and with option to enter the property name in that case I manage to use this filter in many screens , but you can see if you want to handle another type you may need to create a new filter in that case

In case of filter a string property with support different method like include , equal and not equal

string filter pipe

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

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {

  transform(arr: any[], prop: string, value: string , method:Method): any {
    if (arr) {
      if (!value) {
        return arr
      } else {
        return arr.filter(obj => this.filter(obj[prop],value, method))
      }
    } else {
      return []
    }
  }

  filter(source :string, target :string, method:Method) : boolean {

    switch(method) {
      case "includes" : return source.includes(target)
      case "equal"  : return source === target
      case "not-equal" : return source !== target
    }
  }
}

type Method ="includes" | "equal" | "not-equal"

template

<p>
Include <br>
 <input type="text" placeholder="search..." [(ngModel)]="searchValue">
</p>

<div *ngFor="let skill of skills | filter :'name' : searchValue: 'includes' ">
  {{skill.name}}
</div> 


<p>
Equal <br>
 <input type="text" placeholder="search..." [(ngModel)]="searchValue02">
</p>

<div *ngFor="let skill of skills | filter :'name' : searchValue02 : 'equal'">
  {{skill.name}}
</div> 

Demo 🚀🚀

You can also use Regex instead of includes() to get case in-sensitive filter results.

case "includes" : return source.includes(target); Case Sensitive

case "includes" : return new RegExp(target, "i").test(source); Case Insensitive

Hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM