web-dev-qa-db-ja.com

すべての列で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);
  }

ここでは、明らかに、items配列の「name」プロパティのフィルタリングを処理しています。これはそのままで問題なく機能しますが、前述したように、グリッドに多くの列が含まれている場合は、すべての列を処理する1つのメソッドが必要です。ヘルプやヒントをいただければ幸いです。

8
Blankdud

フィルタリング用のサンプル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)'>

TypeScript

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;
}
8
Cole Paciano

複数列のフィルタリングを使用したコードの例を次に示します。

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

エラーが発生しなかった場合、正常に動作するはずです。

1
Josu
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)'>
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>

コンポーネントに次のfilteredDataおよびcolumnsWithSearchを追加します

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

これは、単一のテキスト入力検索ですべての列をフィルタリングするためのコード例です [〜#〜] demo [〜#〜]

0
Haifahrul
 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;
  }
0
Abhijit Hole