Search code examples
angularangular-materialangular-filtersangular-material-table

Angular Material - Custom Column filter and Default filter not working together


Column filter is working absolutely fine but default filter (input field search) is not working at all. I tried several things but nothing worked out. I want my Input field to have default behavior of search for two cols i.e. allAssociates and dept column along with the individual column filters. It does not throw any error as well. Custom column filter reference is from so I have not included here: https://www.freakyjolly.com/angular-material-table-custom-filter-using-select-box/#Adding_Filters_on_Table

filterTable method is not working as expected I would appreciate any suggestions..

Full code: https://stackblitz.com/edit/angular-material-b6qdyt?file=app%2Fapp.component.html

Shared the snippet below:

HTML

<div>
  <mat-form-field 
    *ngFor="let filter of filterSelectObj" 
    style="margin-left: 15px;">
    <mat-label> Filter {{filter.name}} </mat-label>
    <select 
      matNativeControl 
      name="{{filter.columnProp}}" 
      [(ngModel)]="filter.modelValue" 
      (change)="filterChange(filter,$event)">
      <option value=""> All </option>
      <option 
        [value]="item" 
        *ngFor="let item of filter.options">
        {{item}}
      </option>
    </select>
  </mat-form-field>
  <mat-icon>search</mat-icon>
  <input 
    type="text" 
    placeholder="All Associates/Dept" 
    #input 
    (keyUp)="filterTable($event.target.value)"> &nbsp;
  <button 
    mat-stroked-button
    color="warn" 
    (click)="resetFilters(input)">
    Reset
  </button>
</div>

TS file:

ngOnInit() {
  //fetch data from Service
  const deptData = this.deptService.getData();
  this.dataSource = new MatTableDataSource(deptData);
  this.dataSource.filterPredicate = this.createFilter();
  this.filterSelectObj.filter((o) => {
    o.options = this.getFilterObject(deptData, o.columnProp);
  });
}

filterTable(input: string) {
  this.dataSource.filterPredicate =
    (data: DepartmentData, f: string) => !f || (data.allAssociates || data.dept) == f;
  input = input.trim(); // Remove whitespace
  input = input.toLowerCase(); // MatTableDataSource defaults to lowercase matches
  this.dataSource.filter = input;
}

Solution

  • Okay. So two issues that I found with your implementation.

    1. In the template you're binding to (keyUp) when the actual event name to bind to is (keyup).

    2. There's an issue with your predicate function. It should have been this:

      this.dataSource.filterPredicate = (data: DepartmentData, f: string) => !f || data.allAssociates.toLowerCase().includes(f) || data.dept.toLowerCase().includes(f.toLowerCase());

    Fixing these two issues should make it start working for you.

    Here's a Working Sample StackBlitz for your ref.