简体   繁体   中英

How do i filter angular mat-table using multiple keywords and/or partial match

I am trying to filter my mat table by matching exact strings for a column for example these are two rows in one column:

  1. Jack wants a puppy
  2. Jack wants a puppy dog

If i search for Jack dog it should only show the second row containing the string. So I should be able to applyFilter using multiple keywords to display results. I have tried customizing filter predicate but the filter fails when I type in Jack dog . it passes if i type in Jack wants a puppy dog exactly. Is it possible to customize search to match just the letters irregardless of space and characters? ie, jack do should only display one result. Here is my approach

this.dataSource.filterPredicate =
      (data: UserData, filters: string) => {
        const matchFilter = [];
        const filterArray = filters.split(/[\s,]+/);
        const columns = (<any>Object).values(data);
        // OR be more specific [data.name, data.race, data.color];

        // Main
        filterArray.forEach(filter => {
          const customFilter = [];
          columns.forEach(column => customFilter.push(column.toLowerCase().includes(filter)));
          matchFilter.push(customFilter.some(Boolean)); // OR
        });
        return matchFilter.every(Boolean); // AND
      }
  applyFilterSimple(filterValue: string) {
    const filtersSimple = filterValue.trim().toLowerCase();
    this.dataSourceSimple.filter = filtersSimple;
  }

I have this custom pipe, maybe you can drop it into your ts file and use it there. It takes 3 parameters the array of objects, the property to filter by (can be used by multiple objects), and the string the user entered. it return the array just filtered.

  transform(items: object[], propToFilterBy: string, searchText: string): object[] {
    if (!items) {
      return [];
    }
    if (!searchText) {
      return items;
    }
    searchText = searchText.toLowerCase();
    var searchArray = searchText.split(' ');

    return items.filter(elem => elem[propToFilterBy] && this.checkArray(elem[propToFilterBy].toLowerCase(), searchArray) );
  }

  checkArray(str: string, searchArray: string[]) {
    for (let i = 0; i < searchArray.length; i++) {
      if ( !str.includes(searchArray[i]) ) {
        return false;
      }
    }
    return true;
  }
}

The truth is, i added some code for your use case, and i didnt heavily test this code, so it might still need some tweaking.

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