custom filter in mat-table

后端 未结 4 796
深忆病人
深忆病人 2020-11-29 01:54

I\'m using mat-table. It has a filter which works fine with doc example:

From https://material.angular.io/components/table/overview, the original code is:



        
相关标签:
4条回答
  • 2020-11-29 02:43

    I found the solution here.

    It's necessary to rewrite filterPredicate, and just use it as usual, filterPredicate needs to return true when filter passes and false when it doesn't

    export interface Element {
     name: string;
     position: number;
     weight: number;
     symbol: string;
    }
    
    
    dataSource = new MatTableDataSource(ELEMENT_DATA);
    /* configure filter */
    this.dataSource.filterPredicate = 
      (data: Element, filter: string) => data.name.indexOf(filter) != -1;
    
    
    applyFilter(filterValue: string) {
       filterValue = filterValue.trim(); // Remove whitespace
       filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
       this.dataSource.filter = filterValue;
     }
    
    0 讨论(0)
  • 2020-11-29 02:43

    when using parent-child componenet (or service with say observable) you must always in the component containing the MatTableDataSource set an "applyFilter" function (name not matters)

    in the table component i added @Input's for the filter string value as a FormControl, and sent a filter function (filterfn)

      @Input() data: any[];
      @Input() filterControl: FormControl;
      @Input() filterfn: (data: any, filter: string) => boolean;
    

    in the init

     ngOnInit(): void {
        this.dataSource.filterPredicate = this.filterfn
        this.dataSource.data = this.data;
        this.initExpandedDefaultValues();
        //my "applyFilter"
        this.filterControl.valueChanges.subscribe(searchValue => this.dataSource.filter = searchValue)
      }
    

    in parent html

    <div *ngIf="users">
        <expended-table [data]="users"
            [filterfn]="filterFunction"
            [filterControl]="search">
        </expended-table>
    </div>
    

    in parent component

    public users:User[]
      search:FormControl = new FormControl()
      public usersFiltered:User[]
    
      filterFunction(u: User, searchValue: string) : boolean{
        if (searchValue) {
          let v = searchValue.trim().toLowerCase()
          if (
            u.firstName.toLowerCase().includes(v) || 
            u.lastName.toLowerCase().includes(v) || 
            //bla bla bla more tests
            u.permission.toLowerCase().includes(v)  
          )
          { return true } 
          else { return false}
        } //end if searchValue
        else 
        {
          return true
        }
      }
    
    0 讨论(0)
  • 2020-11-29 02:47

    Don't forget to apply .trim().toLowerCase() on your data or you may encounter unexpected results. See my example below:

    this.dataSource.filterPredicate = (data:
      {name: string}, filterValue: string) =>
      data.name.trim().toLowerCase().indexOf(filterValue) !== -1;
    
    applyFilter(filterValue: string) {
        this.dataSource.filter = filterValue.trim().toLowerCase();
    }
    
    0 讨论(0)
  • 2020-11-29 02:51

    Be aware that all fields of the class displayed in table rows, are subject to filtering, even if you do not display that field as a column.

    export class City {
      id: number;//is not displayed in mat table
      code: string;
      name: string;
      country:Country;
    }
    

    Any filter for the dataSource of city table, also applies to id column, which generally we do not display to the end user.

    //this filter will also apply to id column
    this.cityDataSource.filter = filterValue;
    
    0 讨论(0)
提交回复
热议问题