J'ai fait une simple application CRUD, maintenant je dois ajouter une barre de recherche qui filtre ma table et me montre les lignes avec les mêmes lettres que je chiffre.

Je ne sais pas quoi faire dans mon composant, j'ai vu différentes choses avec les tuyaux et le filtre mais je n'ai pas pu les adapter à mon projet.

J'aimerais savoir s'il existe une méthode que je peux implémenter dans mon component.ts sans en créer une nouvelle.

COMPOSANT.HTML

<div class="container">
  <ul class="table-wrapper">
    <div class="table-title">
      <div class="row">
        <div class="col-sm-4">
          <button *ngIf="metadata && metadata.addMD" (click)="addFunc(metadata)">{{metadata.addMD.label}}</button>
          <div class="show-entries">
            <span>Show</span>
            <label>
              <select [(ngModel)]="pageSize">
                <option *ngFor="let maxPerPage of rowsOnPageSet"
                        (click)="maxElements(maxPerPage)">{{maxPerPage}}</option>
              </select>
            </label>
            <span>users</span>
          </div>
        </div>

        <div class="col-sm-4">
          <h2 class="text-center">Users <b>Details</b></h2>
        </div>

        <div class="col-sm-4">
          <div class="search-box">
            <div class="input-group">
              <span class="input-group-addon"><i class="material-icons">&#xE8B6;</i></span>
--> //HERE I HAVE TO ADD THE FUNCTION OR SOMETHING ELSE
             <input type="text" class="form-control" [(ngModel)]="searchVal"
                 (ngModelChange)='checkSearchVal()'  placeholder="Search&hellip;">
            </div>
          </div>
        </div>
      </div>
    </div>

    <table class="table table-bordered">
      <thead>
      <tr>
        <th *ngFor="let col of columns" (click)="sortTable(col)">{{col}}
          <i *ngIf="col === columnSorted && !direction" class="material-icons">keyboard_arrow_up</i>
          <i *ngIf="col === columnSorted && direction" class="material-icons">keyboard_arrow_down</i>
        </th>
        <th>Actions</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let user of users | paginate: {itemsPerPage: pageSize,
                                               currentPage: page,
                                               totalItems: users.length}">
        <td *ngFor="let col of columns">{{user[col]}}</td>
        <td>
          <button [ngClass]="getClassCondition(act.actionType)" *ngFor="let act of actions"
                  (click)="actionFunc(act, user)">{{act.label}}</button>

        </td>

      </tr>
      </tbody>
    </table>

    <div align="center">
      <!--<div class="hint-text">Showing <b>{{totUsersPerPage}}</b> out of <b>{{users.length}}</b> entries</div>-->
      <ul align="center">
        <pagination-controls (pageChange)="pageChanged($event)"></pagination-controls>
      </ul>
    </div>

  </ul>
</div>

COMPONENT.TS, ici, je dois créer la bonne méthode qui fonctionne pour mon application.

    export class DynamicTableComponent implements OnInit {

  constructor(private userService: UserService,
              private resourcesService: ResourcesService,
              private router: Router) {
  }

  @Input()
  users = [];
  @Input()
  columns: string[];
  @Input()
  actions = [];
  @Input()
  metadata: any;
  @Input()
  class;

  direction = false;
  columnSorted = '';
  public rowsOnPageSet = ['5', '10', '15', '20', '25'];
  page = 1;
  private pageSize = 5;
  searchVal = '';

  /*totalPages = Math.trunc(this.users.length / this.pageSize);
  totUsersPerPage = this.pageSize;*/

  ngOnInit() {
  }

  actionFunc(action, element: any) {
    if (action.actionType === 'DELETE') {
        /*...*/
      }
    }
    if (action.actionType === 'GO_TO') {
        /*...*/
    }
  }

  addFunc(metadata) {
    if (metadata.addMD.actionType === 'ADD_TO') {
       /*...*/
    }
  }

  maxElements(maxPerPage) {
    this.rowsOnPageSet = maxPerPage;
  }

  sortTable(param) {
    /*...*/
  }

  getClassCondition(act) {
    return act === 'DELETE' ? this.class = 'btn btn-danger' : 'btn btn-primary';
  }

  pageChanged($event: number) {
     /*...*/
  }

checkSearchVal() {
    this.users.slice();
    const filteredUsers: User[] = [];
    if (this.searchVal && this.searchVal !== '') {
      for (const selectedUser of this.users) {
        if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) !== -1 ||
          selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) !== -1) {
          filteredUsers.push(selectedUser);
        }
      }
      this.users = filteredUsers.slice();
    }
  }

}

STRUCTURE DES DONNÉES : in.memory-data.service.ts

import { InMemoryDbService } from 'angular-in-memory-web-api';
import { User } from './user';
import { Injectable } from '@angular/core';

export const COLUMNS = ['id', 'firstName', 'lastName', 'age'];

@Injectable({
  providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
  createDb() {
    const USERS = [
      {id: 1, firstName: 'NAME_1', lastName: 'SURNAME_1', age: 23},
      {id: 2, firstName: 'NAME_2', lastName: 'SURNAME_2', age: 23},
      {id: 3, firstName: 'NAME_3', lastName: 'SURNAME_3', age: 23},
      {id: 4, firstName: 'NAME_4', lastName: 'SURNAME_4', age: 24},
      {id: 5, firstName: 'NAME_5', lastName: 'SURNAME_5', age: 42},
      {id: 6, firstName: 'NAME_6', lastName: 'SURNAME_6', age: 41},
      {id: 7, firstName: 'NAME_7', lastName: 'SURNAME_7', age: 24},
      {id: 8, firstName: 'NAME_8', lastName: 'SURNAME_8', age: 25},
      {id: 9, firstName: 'NAME_9', lastName: 'SURNAME_9', age: 25},
      {id: 10, firstName: 'NAME_10', lastName: 'SURNAME_10', age: 25},
      {id: 11, firstName: 'NAME_11', lastName: 'SURNAME_11', age: 22},
      {id: 12, firstName: 'NAME_12', lastName: 'SURNAME_12', age: 22},
      {id: 13, firstName: 'NAME_13', lastName: 'SURNAME_13', age: 24},
    ];
    return {USERS};
  }
}

User.ts

export class User {
  id: number;
  firstName: string;
  lastName: string;
  age: number;
}
3
S.A.R.A. 8 mars 2019 à 12:46

2 réponses

Meilleure réponse

J'ai vu que vous avez eu votre réponse... voici est une autre approche pour ce qu'elle vaut. .. comme discuté dans les commentaires...

checkSearchVal() {
    this.USERS = masterUSERS.slice();
    let filteredUsers: User[] = [];
    if (this.searchVal && this.searchVal != '') {

    /* NORMAL FOR
      for(var i=0; i<this.USERS.length; i++ ){
        if(this.USERS[i].firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 || this.USERS[i].lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ){
          filteredUsers.push(this.USERS[i])
        }
      }
    */
    /* FOR EACH
      this.USERS.forEach((selectedUser) => {
        if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ||
          selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1) {
          filteredUsers.push(selectedUser);
        }
      })
    */

    /*  FOR OF */
    for (let selectedUser of this.USERS) {
        if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ||
          selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1) {
          filteredUsers.push(selectedUser);
        }
    }

      this.USERS = filteredUsers.slice();
    }
  }

mise à jour : a déplacé le this.USERS = filteredUsers.slice(); à l'intérieur du SI

mise à jour :2 : même code avec forEach et For-Of (pour se débarrasser de l'erreur TSLint)

1
Akber Iqbal 8 mars 2019 à 11:14

Créez simplement un fichier PIPE.ts pour filtrer la table :

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ 
    name: 'filterAll'
})
export class FilterPipe implements PipeTransform {
  transform(value: any, searchText: any): any {
    if(!searchText) {
      return value;
    }
    return value.filter((data) => this.matchValue(data,searchText)); 
  }

  matchValue(data, value) {
    return Object.keys(data).map((key) => {
       return new RegExp(value, 'gi').test(data[key]);
    }).some(result => result);
  }
 }

Ajoutez le FilterPipe à app.module.ts dans les déclarations et ajoutez ceci à votre component.html :

  <form id="searchForm">
    <div class="form-group">
        <div class="input-group" id="filterAll">
          <div class="input-group-addon"><i class="glyphicon glyphicon-search"></i></div>
          <input type="text" class="form-control" name="searchString" placeholder="Search..." [(ngModel)]="searchString">
        </div>
    </div>
</form>

Puis vous ajoutez un tube au TR de votre table comme ceci :

 <tr *ngFor="let user of users | paginate: {itemsPerPage: pageSize,
                                           currentPage: page,
                                           totalItems: users.length} | filterAll: searchString">

J'ai oublié le fichier component.ts désolé : vous devez mettre la variable searchString comme :

public searchString: string;
5
Jon Fernandez 8 mars 2019 à 11:48