angularangular2-pipe

Angular 2 Table Search Pipe Filter not working


I am creating a table component in Angular 2, in which I am creating a common table search filter pipe, it is working correctly but not displaying the values in their appropriate columns. When I start typing the search keys in the text box the filtered values are displayed correctly but not under their appropriate columns. Sorry if this question is a duplicated one, I have spent enough time in searching the web but I was unable to get a solution for it.

Below is the code for your reference

component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  public tableData: any = [
     {"Name":"Gaurav","Address":"Chennai","Contact":"9632587410"},
     {"Name":"Rakesh","Address":"Goa","Contact":"852397410"}
  ];
}

Pipe.ts

@Pipe({
  name: 'searchPipe'
})
export class searchPipe implements PipeTransform {
   transform(value: any, args: string[]): any {
      let filter = args[0];

      if (filter && Array.isArray(value)) {
         let filterKeys = Object.keys(filter);
         return value.filter(item =>
            filterKeys.reduce((key, keyName) =>
               key && item[keyName].toUpperCase() === filter[keyName].toUpperCase(), true));
      } else {
         return value;
      }
   }
}

component.html

<input type="text" #searchFilter (keyup)="0"/>
<table>
  <tr>
    <th *ngFor="let colValues of tableData | columnPipe">{{colValues}}</th>
  </tr>
  <tr *ngFor="let row of tableData">
    <td *ngFor="let rowValues of row | rowPipe |searchPipe:searchFilter.value">{{rowValues}}</td>
  </tr>
</table>

Full working Plunker, help me in resolving the issues


Solution

  • I guess you want it like this: https://plnkr.co/edit/olkIEiOc67Ld28NuASef?p=preview

    You dont want to "hide" the whole td, instead you just want to "hide" the value..

    @Pipe({
      name: 'searchPipe'
    })
    export class searchPipe implements PipeTransform {
      transform(value: any, args: string[]): any {
        let filter = args[0];
    
        if (filter && Array.isArray(value)) {
          let filterKeys = Object.keys(filter);
          return value.filter(item => filterKeys.reduce((key, keyName) => key && item[keyName].toUpperCase() === filter[keyName].toUpperCase(), true));
        }
        // new case !
        else if (filter && typeof value === 'string') {
          return value.toUpperCase().indexOf(filter.toUpperCase()) >= 0 ? value : '';
        }
        else {
          return value;
        }
      }
    }
    
    <td *ngFor="let rowValues of row | rowPipe">{{ rowValues | searchPipe : searchFilter.value }}</td>
    

    UPDATE

    To show the whole row, you have to filter your tableData.

    Change your pipe like this:

    @Pipe({
      name: 'searchPipe'
    })
    export class searchPipe implements PipeTransform {
      transform(values: any[], filter: string): any {
        if (!values || !values.length) return [];
        if (!filter) return values;
    
        filter = filter.toUpperCase();
    
        if (filter && Array.isArray(values)) {
          const keys = Object.keys(values[0]);
          return values.filter(v => v && keys.some(k => v[k] && v[k].toString().toUpperCase().indexOf(filter) >= 0));
        }
      }
    }
    
    <tr *ngFor="let row of tableData | searchPipe : searchFilter.value">
      <td *ngFor="let rowValues of row | rowPipe">{{ rowValues }}</td>
    </tr>
    

    live demo: https://plnkr.co/edit/jXfqfCuJpKdw9HtL569T?p=preview