10

我一直试图让这个工作没有运气。我一直在参考这些资源寻求帮助: http ://swimlane.github.io/ngx-datatable/#filter
https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/filter。组件.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);
  }

在这里,我显然只是在处理我的 items 数组的 'name' 属性的过滤。这工作得很好,但就像我提到的那样,如果网格包含许多列,我想要一种方法来处理所有这些列。任何帮助或提示表示赞赏。

4

8 回答 8

13

使用示例 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;
}
于 2018-01-24T23:15:29.963 回答
4

这个答案改进了 Cole Paciano 的现有答案:

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

以下是步骤

template(html) 文件中添加一个带有keyup处理程序的输入

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

component添加以下内容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;
}
于 2019-10-24T02:10:56.803 回答
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;
  });
}

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

于 2018-01-23T15:04:38.347 回答
1

同时将数据存储在rows列表中同时也会初始化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;
    }
}
于 2020-04-21T07:49:38.897 回答
0

你可能会得到帮助

 <input
        type="text"
        style="padding:8px;margin:15px auto;width:30%;"
        placeholder="Type to filter the name column..."
        (keyup)="updateFilter($event)"
      />
      <ngx-datatable
        #table
        class="material"
        [columns]="columns"
        [columnMode]="ColumnMode.force"
        [headerHeight]="50"
        [footerHeight]="50"
        rowHeight="auto"
        [limit]="10"
        [rows]="rows"
      >
      </ngx-datatable>




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

    // filter our data
    const temp = this.temp.filter(function(d) {
      return d.name.toLowerCase().indexOf(val) !== -1 ||
        d.address.toLowerCase().indexOf(val) !== -1 ||
        d.gender.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;
  }

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

于 2020-04-01T06:24:38.757 回答
0

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

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

问题解决了……

  1. 如果通过输入推送数据,我们需要重置键,尤其是在没有数据开始的情况下。

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

我在这里发布我的全部使用情况..

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] });
  }

}
于 2020-05-18T09:26:43.683 回答
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;
  }
于 2019-08-27T12:10:56.070 回答
0
import { DatatableComponent } from '@swimlane/ngx-datatable';
ViewChild(DatatableComponent) table: DatatableComponent;

   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;
    });
 <input placeholder="Search Order" (keyup)='updateFilter($event)'>
于 2018-10-18T11:14:15.990 回答