Mich
Mich

Reputation: 322

Material Angular add regular expressions (regex) to filter

I want to use regular expression on material table data filter. So far I've achieved using a filter for each column on my table, but no idea on how to approach the regex functionality. I've read about changing the customfilterpredicate, but can't seem to do it.

My filtering code is very long, but here's how my customfilterpredicate looks like. I want to transform it using regex expressions:

customFilterPredicate() {
    const myFilterPredicate = (data: IApiDataFile, filter: string): boolean => {
      const searchString = JSON.parse(filter);
      const unitFound = data.unit.toString().trim().toLowerCase().indexOf(searchString.unit.toLowerCase()) !== -1;
      const file_nameFound = data.file_name.toString().trim().toLowerCase().indexOf(searchString.file_name.toLowerCase()) !== -1;

      if (searchString.topFilter) {
        return unitFound || file_nameFound;
      } else {
        return unitFound && file_nameFound;
      }
    };
    return myFilterPredicate;
  }
  
 filterSubscribe() {
    this.unitFilter.valueChanges.subscribe(unitFilterValue => {
      this.filteredValues.unit = unitFilterValue;
      this.dataSource.filter = JSON.stringify(this.filteredValues);
      this.filteredValues.topFilter = false;
      console.log('in filterSubscribe()');

    });

    this.file_nameFilter.valueChanges.subscribe(file_nameFilterValue => {
      this.filteredValues.file_name = file_nameFilterValue;
      this.dataSource.filter = JSON.stringify(this.filteredValues);
      this.filteredValues.topFilter = false;
    });
    this.dataSource.filterPredicate = this.customFilterPredicate();
  }

then

 public ngOnInit() {
    interval(60 * 1000).pipe(
        flatMap(() => this.ApiDataFileService.getApiDataFiles())).subscribe(
        ApiDataFiles => {
            this.filteredApiDataFiles = ApiDataFiles;
            this.dataSource = new MatTableDataSource<IApiDataFile>(this.filteredApiDataFiles);
            this.filterSubscribe();
            this.dataSource.filter = JSON.stringify(this.filteredValues);
            this.filteredValues.topFilter = false;
        },
        error => this.errorMessage = error as any
      );
  }

Upvotes: 1

Views: 1609

Answers (1)

Eliseo
Eliseo

Reputation: 57971

Use the property filterPredicate of the data source. If your dataSource is the typical of the examples

  dataSource = new MatTableDataSource(ELEMENT_DATA);

You can define a regExpr variable that change in applyFilterFunction

  regExpr:any;  //<--define a variable

  applyFilter(filterValue: string) {
    this.regExpr = new RegExp(filterValue);
    this.dataSource.filter = filterValue;
  }

then you can make a function like

regExprFilter()
  { 
    return (data: any, filter: string) => {
        try {
          return this.regExpr.test(data.name)
        } catch (e) {
          return false
        }
      }
  }

And in ngOnInit change the filterPredicate

ngOnInit() {
    this.dataSource.filterPredicate =this.regExprFilter()
}

see stackblitz

NOTE:I edited my answer to make more confortable code

NOTE2: Be carefull using regExp if you want defined using a string variable in code. you need take acount "\" must be write as "\\", e.g.

  let myExpresion="^\w" //BAD, myExpresion get the value "^w"
  let myExpresion="^\\w" //GOOD, myExpresion get the value "^\w"

Upvotes: 3

Related Questions