在所有列上实施NGX Datatable过滤

时间:2017-07-14 15:06:29

标签: angular typescript ngx-datatable

我一直试图让这个工作没有运气。我一直在引用这些资源寻求帮助: http://swimlane.github.io/ngx-datatable/#filter
https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/filter.component.ts

基本上我只想让我的过滤器应用于多个列,而不需要实现代码来处理每一列。 (有些数据表有​​20多列!)

示例代码:

//HTML
  <input type='text' placeholder='Filter' (keyup)='updateFilter($event.target.value)' />

  <ngx-datatable
    class="material"
    columnMode="force"
    [columns]="gridProperties.FilteredColumns"
    [footerHeight]="50"
    [loadingIndicator]="gridLoadingIndicator"
    [rows]="filteredList"
    [scrollbarH]="false"
    [scrollbarV]="true"
    [selected]="selectedItem"
    [selectionType]="'single'"
    style="min-height:400px;">
  </ngx-datatable>

//TYPESCRIPT
  public items: Item[];

  updateFilter(filterValue) {
    const lowerValue = filterValue.toLowerCase();

    this.filteredList = this.items.filter(item => item.name.toLowerCase().indexOf(lowerValue) !== -1 || !lowerValue);
  }

在这里,我显然只是处理“&#39; name&#39;我的items数组的属性。这很好用,但就像我提到的那样,如果网格包含很多列,我想要一种方法来处理所有这些列。任何帮助或提示都表示赞赏。

8 个答案:

答案 0 :(得分:7)

使用示例TS文件进行过滤 (https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/filter.component.ts) 作为基础,我能够成功地使其动态过滤所有列(它将过滤所有列而无需指定它们)。我已经包含了我认为可以使用的所有必要部分,但也尽可能地减少了代码,以便更容易理解。

HTML

<ngx-datatable
 #table
 class="material striped scroll-vertical"
 [rows]="data"
 [columns]="cols"
 [columnMode]="'force'"
 [headerHeight]="35"
 [footerHeight]="35"
 [rowHeight]="'auto'"
 [limit]="pageSize"
 [selectionType]="'single'">

<input type="text" (keyup)='filterDatatable($event)'>

打字稿

cols = [{name:'First Name'},{name:'Last Name'},{name:'Address'}];
data = [];
filteredData = [];

// dummy data for datatable rows
dummyData = [
  {firstName:'Daenarys',lastName:'Targaryen',address:'Dragonstone'},
  {firstName:'Sansa',lastName:'Stark',address:'Winterfell'},
  {firstName:'Cersei',lastName:'Lannister',address:'Kings Landing'},
  {firstName:'Brienne',lastName:'Tarth',address:'Sapphire Island'},
  {firstName:'Lyanna',lastName:'Mormont',address:'Bear Island'},
  {firstName:'Margaery',lastName:'Tyrell',address:'Highgarden'}
]

ngOnInit(){
  // populate datatable rows
  this.data = this.dummyData;
  // copy over dataset to empty object
  this.filteredData = this.dummyData;
}

// filters results
filterDatatable(event){
  // get the value of the key pressed and make it lowercase
  let val = event.target.value.toLowerCase();
  // get the amount of columns in the table
  let colsAmt = this.cols.length;
  // get the key names of each column in the dataset
  let keys = Object.keys(this.dummyData[0]);
  // assign filtered matches to the active datatable
  this.data = this.filteredData.filter(function(item){
    // iterate through each row's column data
    for (let i=0; i<colsAmt; i++){
      // check for a match
      if (item[keys[i]].toString().toLowerCase().indexOf(val) !== -1 || !val){
        // found match, return true to add to result set
        return true;
      }
    }
  });
  // whenever the filter changes, always go back to the first page
  this.table.offset = 0;
}

答案 1 :(得分:1)

以下是使用多列过滤的代码示例:

updateFilter(filter: string): void {

  const val = filter.trim().toLowerCase();

  this.filteredList = this.items.slice().filter((item: any) => {
    let searchStr = '';
    for (let i = 0; i < this.gridProperties.FilteredColumns.length; i++) {
      searchStr += (item[this.gridProperties.FilteredColumns[i]]).toString().toLowerCase();
    }
    return searchStr.indexOf(val) !== -1 || !val;
  });
}

如果我没有犯任何错误,它应该可以正常工作。

答案 2 :(得分:0)

**100 % working for anyone**
    **Before doing import the** 

import { DatatableComponent } from '@swimlane/ngx-datatable';
ViewChild(DatatableComponent) table: DatatableComponent;

// Typescript  
   updateFilter(event) {
    const val = event.target.value.toLowerCase();
    var returnData: any;
    // filter our data
    const temp = this.temp.filter(function (d) {

      if (d.yourFirstColumnName.toLowerCase().indexOf(val) !== -1 || !val) {
        returnData = d.user_name.toLowerCase().indexOf(val) !== -1 || !val;
      } else if (d.yourSecondColumnName.toLowerCase().indexOf(val) !== -1 || !val) {
        returnData = d.notes_title.toLowerCase().indexOf(val) !== -1 || !val;

      }
      return returnData;
    });

// HTML

 <input placeholder="Search Order" (keyup)='updateFilter($event)'>

答案 3 :(得分:0)

 updateFilter(event) {
    const val = event.target.value.toLowerCase();
    const temp = this.temp.filter(index => {
      return (index.name.toLowerCase().indexOf(val) !== -1 ||
        index.company.toLowerCase().indexOf(val) !== -1 ||
        index.gender.toLowerCase().indexOf(val) !== -1 ||
        !val);
    });
    this.company = temp;
    this.table.offset = 0;
  }

答案 4 :(得分:0)

此答案改进了Cole Paciano的现有答案:

  • 要搜索的列名仅创建一次,而不是在每次按键时创建。
  • 具有null值的单元格得到了正确处理(没有控制台错误)
  • 显示了完整的行(因为过滤器应用于行数组)
  • 还可以手动指定要搜索的列名,使其仅包括其中的一些(不包括guid,id等)

在模板(html)文件中,添加带有keyup处理程序的输入

Search:
<input type="text" (keyup)='filterDatatable($event)'>
<ngx-datatable
    class="material"
    [rows]="rows"
    [columns]="columns"
    headerHeight="35"
    rowHeight ="35">
</ngx-datatable>

在组件中添加以下filteredDatacolumnsWithSearch

export class ListParkingsComponent implements OnInit {
  columns = [];
  rows = [];
  filteredData = [];
  columnsWithSearch : string[] = [];

ngOnInit() {
    this.rows = getData() ; //recover data from API/database/datasource
    this.filteredData = this.rows;
    // for specific columns to be search instead of all you can list them by name
    this.columnsWithSearch = Object.keys(this.rows[0]);
}

getData() {
   //your current logic to fill the rows of the table
}

// filters results
filterDatatable(event){
    // get the value of the key pressed and make it lowercase
    let filter = event.target.value.toLowerCase();

    // assign filtered matches to the active datatable
    this.rows = this.filteredData.filter(item => {
      // iterate through each row's column data
      for (let i = 0; i < this.columnsWithSearch.length; i++){
        var colValue = item[this.columnsWithSearch[i]] ;

        // if no filter OR colvalue is NOT null AND contains the given filter
        if (!filter || (!!colValue && colValue.toString().toLowerCase().indexOf(filter) !== -1)) {
          // found match, return true to add to result set
          return true;
        }
      }
    });
    // TODO - whenever the filter changes, always go back to the first page
    //this.table.offset = 0;
}

答案 5 :(得分:0)

您可能会得到帮助

{
k1:v1,
k2:v2,
k3:v3,
k4:{
     k5:v5,
     k6:{
          k7:v7,
          value:"value1"
        }
   }
k8:v8,
value:"value2"
}

https://github.com/swimlane/ngx-datatable/blob/master/src/app/basic/dark-theme.component.ts

答案 6 :(得分:0)

当时在行列表中存储数据的同时也会初始化perttemp列表,以便我们可以在过滤器之后获取

updateFilter(event) {

    const val = event.target.value.toLowerCase();
    if(val) {
        this.temp = this.rows;
        // filter our data
        const temp = this.temp.filter(function (d) {
          return ( d.name.toLowerCase().indexOf(val) !== -1 || d.email.toLowerCase().indexOf(val) !== -1 || !val);
        });
        this.rows = temp;
    }
    else
    {
        this.rows = this.perttemp;
    }
}

答案 7 :(得分:0)

在使用上述某些答案来添加自己的答案时出现了一些问题...

首先,最好将密钥存储在全局变量中,因为每次迭代都会覆盖所有内容。

问题解决了...

  1. 如果通过输入推送数据,则需要特别重置键 如果没有开始的数据。

  2. 将所有内容存储在temp变量中,以始终保留原始数据。**

我将全部使用情况发布在这里。

import {
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnChanges,
  OnInit,
  Output,
  SimpleChanges,
  ViewChild,
} from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'verasci-data-table',
  templateUrl: './data-table.component.html',
  styleUrls: ['./data-table.component.scss'],
})
export class DataTableComponent implements OnInit, OnChanges {
  @ViewChild('table') table;
  @Input() rows;
  @Input() columns;
  @Input() searchBar;
  keys;
  temp: Array<any>;
  @Output() selectEvent$ = new EventEmitter();
  selected = [];
  readonly pageLimit = 10;
  readonly headerHeight = 50;
  readonly rowHeight = 50;

  constructor(private readonly el: ElementRef, private readonly router: Router) { }

  async ngOnInit() {
    this.temp = this.rows;
    this.keys = this.rows[0] ? Object.keys(this.rows[0]) : null;
    setTimeout(() => { this.dataLoaded = true; }, 200);
  }

  // we need to reset keys and temp data if data is pushed to the table.
  ngOnChanges(changes: SimpleChanges) {
    this.keys = this.rows[0] ? Object.keys(this.rows[0]) : null;
    this.temp = this.rows;
  }       

  filterSingle(event) {
    const val = event.target.value.toLowerCase();

    // filter our data
    const temp = this.temp.filter((d) => {
      return d.sponsor.toLowerCase().indexOf(val) !== -1 || !val;
    });

    // update the rows
    this.rows = temp;
    // Whenever the filter changes, always go back to the first page
    this.table.offset = 0;
  }

  filterMulti(event) {
    // get the value of the key pressed and make it lowercase
    const val = event.target.value.toLowerCase();
    // get the amount of columns in the table
    const colsAmt = this.columns.length;
    // get the key names of each column in the dataset
    const keys = this.keys; // just need to keys from the first set of rw
    // filter our data
    const temp = this.temp.filter(item => {
    // iterate through each row's column data
    for (let i = 0; i < colsAmt; i++) {
    // check for a match on properties that are not null
      if (item[keys[i]] != null && (item[keys[i]].toString().toLowerCase().indexOf(val) !== -1 || !val)) {
        // found match, return true to add to result set
        return true;
      }
     }
   });
    // update the rows
    this.rows = temp;
    // Whenever the filter changes, always go back to the first page
    this.table.offset = 0;
  }

  onSelect({ selected }) {
    this.selectEvent$.emit({ selected: selected[0] });
  }

}
相关问题