Filtering specific column in Angular Material Table with filtering in angular?

前端 未结 4 886
温柔的废话
温柔的废话 2021-02-19 00:44

I am using mat-table. It has a filter which works fine.

Filter happened against this below data (All columns)

const ELEMENT_DATA: Element[] = [
  {posit         


        
相关标签:
4条回答
  • 2021-02-19 01:22

    In Angular Material Tables, we can create column based filters from data itself.

    Source Link

    Demo Link

    For that, we need to override the filterPredicate method with customFilter() method

            ...
            ngOnInit() {
                this.getRemoteData();
    
                // Overrride default filter behaviour of Material Datatable
                this.dataSource.filterPredicate = this.createFilter();
            }
            ...
    
            // Custom filter method fot Angular Material Datatable
            createFilter() {
                let filterFunction = function (data: any, filter: string): boolean {
                let searchTerms = JSON.parse(filter);
                let isFilterSet = false;
                for (const col in searchTerms) {
                    if (searchTerms[col].toString() !== '') {
                    isFilterSet = true;
                    } else {
                    delete searchTerms[col];
                    }
                }
    
                let nameSearch = () => {
                    let found = false;
                    if (isFilterSet) {
                    for (const col in searchTerms) {
                        searchTerms[col].trim().toLowerCase().split(' ').forEach(word => {
                        if (data[col].toString().toLowerCase().indexOf(word) != -1 && isFilterSet) {
                            found = true
                        }
                        });
                    }
                    return found
                    } else {
                    return true;
                    }
                }
                return nameSearch()
                }
                return filterFunction
            }
    

    Check complete working code here

    0 讨论(0)
  • 2021-02-19 01:26

    Adding to bugs' answer. Here's a more elaborate implementation,

    export class FilterTable implements AfterViewInit {
      //some datasource
      datasource //=
      displayedColumns //=insert column names on which you want to filter whether they are displayed or not, but present in the datasource
    
      // Apply filter to the datasource
      applyFilter(filterValue: string) {
        this.datasource.filter = filterValue;
      }
    
    
      ngAfterViewInit() {
        // Overwriting filterPredicate here, as it needs to be done after the datasource is loaded.
        this.datasource.filterPredicate = (data, filter) => {
          var tot = false;
          for (let column of this.displayedColumns) {
            //incase if there is a date type and is displayed differently using a pipe, then convert it intorequired format before filtering
            //check if all the columnson which you are filtering are actually present
            if ((column in data) && (new Date(data[column].toString()).toString() == "Invalid Date")) {
              //if not date column
              tot = (tot || data[column].toString().trim().toLowerCase().indexOf(filter.trim().toLowerCase()) !== -1);
            } else {
              //change this to the format in which date is displayed
              var date = new Date(data[column].toString());
              var m = date.toDateString().slice(4, 7) + " " + date.getDate() + " " + date.getFullYear();
              tot = (tot || m.toLowerCase().indexOf(filter.trim().toLowerCase()) !== -1);
            }
          }
          return tot;
        }
      }
    }
    

    Please feel free to suggest edits, if this could be improved

    0 讨论(0)
  • 2021-02-19 01:28

    Material has implemented its own search feature you can override it by updating the filterPredicate property on the date source. Call the generateTable function on ngOninit() life cycle.

    generateTable(tableData: any) {
        this.dataSource = new MatTableDataSource(tableData);
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
        this.dataSource.filterPredicate = (data: any, filter: string) => {
          console.log(data);
          console.log(filter);
          let matchFound = false;
          for (let column of this.displayedColumns) {
            if(column in data) {
              if(data[column]) {
                matchFound = (matchFound || data[column].toString().trim().toLowerCase().indexOf(filter.trim().toLowerCase()) !== -1)
              }
            }
          }
          return matchFound;
        }
      }
    

    Whenever you wish to apply the filter, update the filter property on dataSource to the string value to be searched.

    applyFilter(searchValue: any) {
        this.dataSource.filter = this.filterText.trim().toLowerCase();
        }
    
    0 讨论(0)
  • 2021-02-19 01:33

    You have to override the filterPredicate of your dataSource.

    Here's an example of how to do it: Working demo


    Essentially, you want to specify what properties in your data the filter is applied to:

    this.dataSource.filterPredicate = function(data, filter: string): boolean {
        return data.name.toLowerCase().includes(filter) || data.symbol.toLowerCase().includes(filter) || data.position.toString().includes(filter);
    };
    
    0 讨论(0)
提交回复
热议问题