web-dev-qa-db-fra.com

Implémentation du filtrage NGX Datatable sur toutes les colonnes

J'ai essayé de faire fonctionner ça sans succès. J'ai référencé ces ressources pour obtenir de l'aide: http://swimlane.github.io/ngx-datatable/#filter
https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/filter.component.ts

Fondamentalement, je veux simplement permettre à mon filtre de s'appliquer à plus d'une seule colonne, sans implémenter de code pour gérer chaque colonne. (Certaines tables de données ont plus de 20 colonnes!)

Exemple de code:

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

Ici, je suis évidemment en train de gérer le filtrage de la propriété "nom" de mon tableau d'éléments. Cela fonctionne très bien tel quel, mais comme je l'avais mentionné, si la grille contient de nombreuses colonnes, j'aimerais qu'une méthode les gère toutes. Toute aide ou conseil est apprécié.

8
Blankdud

En utilisant l'exemple de fichier TS pour le filtrage ( https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/filter.component.ts ) comme fondation, j'ai pu pour réussir à filtrer dynamiquement toutes les colonnes (il filtrera toutes les colonnes sans avoir besoin de les spécifier). J'ai inclus ce que je pense être toutes les pièces nécessaires pour que cela fonctionne, mais j'ai également réduit le code autant que possible pour le rendre plus facile à comprendre.

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

Manuscrit

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

voici un exemple de votre code avec filtrage sur plusieurs colonnes:

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

Si je n'ai commis aucune erreur, cela devrait fonctionner correctement.

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
Sachin from Pune

Cette réponse améliore une réponse existante de Cole Paciano:

  • Les noms de colonnes à rechercher ne sont créés qu'une seule fois et non chaque fois qu'une touche est enfoncée
  • Les cellules avec des valeurs null sont correctement gérées (aucune erreur de console)
  • Les lignes complètes sont affichées (car le filtre s'applique au tableau de lignes)
  • Les noms de colonnes à rechercher peuvent également être spécifiés à la main pour n'en inclure que certains (exclure les guides, les identifiants, etc.)

Dans le fichier modèle (html), ajoutez une entrée avec un gestionnaire keyup

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

Dans le composant, ajoutez les filteredData et columnsWithSearch suivants

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

Ceci est un exemple de code pour filtrer toutes les colonnes avec une recherche de saisie de texte unique DÉMO

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