Search code examples
htmlangular7

Want to add search box for each column which will search in respective column


enter image description hereI Want to add search box for each column which will search in respective column. For that I have written my code as below but its not working. home.component.html

<table class="table">
  <tr>
    <th>Commit Date</th>
    <th>Commit Id</th>
    <th >Environment</th>
    <th>Jira Id's</th>
    <th >Upgrade Date</th>
  </tr>
  <tr>
    <th><input [(ngModel)]="searchString1" placeholder="Search.." class="advancedSearchTextbox"></th>
    <th><input [(ngModel)]="searchString2" placeholder="Search.." class="advancedSearchTextbox"></th>
    <th><input [(ngModel)]="searchStrin3" placeholder="Search.." class="advancedSearchTextbox"></th>
    <th><input [(ngModel)]="searchStrin4" placeholder="Search.." class="advancedSearchTextbox"></th>
    <th><input [(ngModel)]="searchString5" placeholder="Search.." class="advancedSearchTextbox"></th>
  </tr>
  <tr *ngFor="let data of history | filter :{ commit_date : searchString1, commit_id: searchString2, env: searchString3, jira_ids: searchString4, upgrade_date: searchString5};">
    <td class="text-left">
      {{data.commit_date}}
    </td>
    <td>{{data.commit_id}}</td>
    <td>{{data.env}}</td>
    <td>{{data.jira_ids}}</td>
    <td>{{data.upgrade_date}}</td>
  </tr>
</table>

filter.pipe.ts

import { Pipe, PipeTransform, Injectable } from '@angular/core';
@Pipe({
  name: 'filter'
})
@Injectable()
export class FilterPipe implements PipeTransform {
  transform(items: any, filter: any, defaultFilter: boolean): any {
    if (!filter){
      return items;
    }
    if (!Array.isArray(items)){
      return items;
    }
    if (filter && Array.isArray(items)) {
      let filterKeys = Object.keys(filter);
      if (defaultFilter) {
        return items.filter(item =>
            filterKeys.reduce((x, keyName) =>
                (x && new RegExp(filter[keyName], 'gi').test(item[keyName])) || filter[keyName] == "", true));
      }
      else {
        return items.filter(item => {
          return filterKeys.some((keyName) => {
            return new RegExp(filter[keyName], 'gi').test(item[keyName]) || filter[keyName] == "";
          });
        });
      }
    }
  }
}



It works fine if I add a single search box at top and change HTML file like below:

Search Data Here: </b><input [(ngModel)]="searchString" placeholder="Search.." class="advancedSearchTextbox">
<table class="table">
  <tr>
    <th>Commit Date</th>
    <th>Commit Id</th>
    <th >Environment</th>
    <th>Jira Id's</th>
    <th >Upgrade Date</th>
  </tr>
  <tr *ngFor="let data of history | filter :{ commit_date : searchString, commit_id: searchString, env: searchString, jira_ids: searchString, upgrade_date: searchString};">
    <td class="text-left">
      {{data.commit_date}}
    </td>
    <td>{{data.commit_id}}</td>
    <td>{{data.env}}</td>
    <td>{{data.jira_ids}}</td>
    <td>{{data.upgrade_date}}</td>
  </tr>
</table>

What changes do I need to make the search box work for each individual column


Solution

  • Use one parameter for the search input and use function that get the key and the name of the column as below:

    HTML:

    <table class="table">
      <tr>
        <th>Commit Date</th>
        <th>Commit Id</th>
        <th >Environment</th>
        <th>Jira Id's</th>
        <th >Upgrade Date</th>
      </tr>
      <tr>
        <th><input  placeholder="Search.." class="advancedSearchTextbox" [ngModel]="searchString" (ngModelChange)="search($event,'commit_date')" ></th>
        <th><input placeholder="Search.." class="advancedSearchTextbox" [ngModel]="searchString" (ngModelChange)="search($event,'commit_id')"></th>
        <th><input placeholder="Search.." class="advancedSearchTextbox" [ngModel]="searchString" (ngModelChange)="search($event,'env')"></th>
        <th><input placeholder="Search.." class="advancedSearchTextbox" [ngModel]="searchString" (ngModelChange)="search($event,'jira_ids')"></th>
        <th><input placeholder="Search.." class="advancedSearchTextbox" [ngModel]="searchString" (ngModelChange)="search($event,'upgrade_date')"></th>
      </tr>
      <tr *ngFor="let data of filterData">
        <td class="text-left">
          {{data.commit_date}}
        </td>
        <td>{{data.commit_id}}</td>
        <td>{{data.env}}</td>
        <td>{{data.jira_ids}}</td>
        <td>{{data.upgrade_date}}</td>
      </tr>
    </table>
    

    TS:

      history = [
        {
          commit_date: "20/02/2019",
          commit_id: "52",
          env: "log",
          jira_ids: "jira",
          upgrade_date: "02/03/2019"
        },
        {
          commit_date: "03/03/2019",
          commit_id: "53",
          env: "log",
          jira_ids: "jira",
          upgrade_date: "03/04/2019"
        }
      ];
      searchString="";
      filterData:any=[];
    
      constructor(){
        this.filterData = this.history;
      }
    
      search(term,columnName){
           if(!term) {
          this.filterData = this.history;
        } else {
          this.filterData = this.history.filter(x => 
             x[columnName].trim().toLowerCase().includes(term.trim().toLowerCase())
          );
        }
      }