3

I am using Mat Table in which I am having 2 filter criteria/options.

  • A toggle button for filtering based on 1 column.

  • And a normal input text box for filtering based on default behavior, string matching.

So when I am calling the toggle function, I am overriding the default filter using the filter predicate method. How do I reset the filter back to it's default state?

P.S. I am getting the table data from back end api call.

BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
SanDash
  • 733
  • 1
  • 6
  • 15
  • 1
    Do you have any code samples? Maybe handle the toggle change with a function inside your component and keep the state of your filters into an object so you could manage the state on button's toggle? – StPaulis Jul 13 '20 at 10:28
  • Yeah that sounds possible. so instead of having separate/distinct filters, I can have a filter object for handling multiple columns. and based on the state of the filter, apply the corresponding filter value from the object. – SanDash Jul 13 '20 at 10:34
  • Yes, I think that these approach would be cleaner. If you have a lot like these in your application, maybe you should think to use a state manager library like ngrx or akita. – StPaulis Jul 13 '20 at 10:38
  • Does this answer your question? [Reset this.dataSource.filterPredicate in Angular](https://stackoverflow.com/questions/63467149/reset-this-datasource-filterpredicate-in-angular) – BuZZ-dEE Dec 23 '21 at 21:26

1 Answers1

0

Update The way is simply create a CustomFunction.

In you has a variable "check" and a customFilter

  check=false;
  customFilter = (data: PeriodicElement, filter: string) => {
    if (this.check)
        return data['name`].toLowerCase().indexOf(filter)>=0

    const search=(data['name']+"|"+data['description']...).toLowerCase()
        return search.indexOf(filter)>=0
  };

You can has a input and a checkbox

<mat-form-field>
  <mat-label>Search</mat-label>
  <input #input matInput (input)="dataSource.filter=input.value.toLowerCase()" />
</mat-form-field>
<mat-checkbox [(ngModel)]="check" 
    (change)="dataSource.filter=input.value.toLowerCase()">
</mat-checkbox>

Update2 If we can, we can use a FormControl to change the dataSource.filter in the way

  control=new formControl()

  //After defined the dataSource
  this.control.valueChanges.pipe(
      throttleTime(200))
      .subscribe((res:string)=>{
        this.dataSource.filter=res.toLowerCase()
    })

And use

  <input matInput [formControl]="control" />
  <mat-checkbox [(ngModel)]="check" 
      (change)="dataSource.filter=control.value.toLowerCase()">
  </mat-checkbox>

A Custom function is in the way

customFilter = (data: any, filter: string) => {
  
}

The filter is the value of this.dataSource.filter, so we can make some similar to this SO. In the SO is used ReactiveForms, but you can also simple use the mat-input and mat-checkbox with his methods. So

<mat-form-field>
  <mat-label>Search</mat-label>
  <input #input matInput (input)="changeFilter({value:input.value.toLowerCase()})" />
</mat-form-field>
<mat-checkbox (change)="changeFilter({checked:$event.checked})"></mat-checkbox>

(*)Note I pass the value to lowercase

You can use

  changeFilter(obj:any){
    this.dataSource.filter=JSON.stringify(
          {...JSON.parse(this.dataSource.filter),...obj})
    }


  customFilter = (data: PeriodicElement, filter: string) => {
    const {value,checked}=JSON.parse(filter)
    //here you has in value the value of the input and 
    //             in checked if the checkbox is checked or not 
    ..create the condition and return true or false
    return true;
  };

The last is, when you create the data source

this.dataSource = new MatTableDataSource(ELEMENT_DATA);
this.dataSource.filterPredicate = this.customFilter;
this.dataSource.filter=JSON.stringify({value:'','checked':false})
Eliseo
  • 50,109
  • 4
  • 29
  • 67