Individual column searching text input angular

1.6k Views Asked by At

I am looking for an individual column search on the data table and I have already been used a common search bar using pipe now I have to implement proper functionality for search by each column i.e. search by ID, search by name, Search by age, and so on. It would be very helpful if anyone can help me with this.

app.html

<router-outlet></router-outlet>
        <div>
            <h1>Nested Array Table</h1>
            <div class="md-form">
                <input type="text" [(ngModel)]="searchText" class="form-control" id="search" placeholder="Search" />
            </div>
        
            <table class="table table-bordered">
                <thead>
                    
                    <tr>
                        <th>#ID</th>
                        <th>Name</th>
                        <th>Age</th>
                        <th>Weight</th>
                        <th>Height</th>
                        <th>Mobile</th>
                    </tr>
                </thead>
                <tfoot>
                    <tr>
                        <th><input type="text" id="search id" placeholder="Search by ID" /></th>
                        <th><input type="text" id="search name" placeholder="Search by Name" /></th>
                        <th><input type="text" id="search age" placeholder="Search by Age" /></th>
                        <th><input type="text" id="search weight" placeholder="Search by Weight" /></th>
                        <th><input type="text" id="search height" placeholder="Search by Height" /></th>
                        <th><input type="text" id="search mobile" placeholder="Search by Mobile" /></th>
                    </tr>
                </tfoot>
                <tbody>
                    <tr
                        *ngFor="let item of ItemsArray| FilterPipe: 
                        {name: searchText, age:searchText, weight: searchText, height:searchText, mobile: searchText}; let i=index;">
                        <td>{{ i+1 }}</td>
                        <td>{{ item.name }}</td>
                        <th>{{ item.data.age }}</th>
                        <td>{{ item.data.weight }}</td>
                        <td>{{ item.data.height}}</td>
                        <td>{{ item.data.mobile }}</td>
                    </tr>
                </tbody>
            </table>
        </div>

app.ts

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

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'testJobNestedArray';
    searchableList: any;
    public searchText : string;
    public ItemsArray : any;

    constructor() { }

    ngOnInit() {

        this.ItemsArray = [
            {
                name: 'manpreet',
                data:{
                        age: 25,
                        weight: 65,
                        height: 5.6,
                        mobile: [9780698969, 6895741258]
                    }   
            },
            {
                name: 'abdul',
                data: {
                        age: 26,
                        weight: 80,
                        height: 6.0,
                        mobile: [3698541258]
                    }
            },
            {
                name: 'onkar',
                data: {
                        age: 28,
                        weight: 70,
                        height: 5.8,
                        mobile: [8569741236, 6528965478]
                    }
            }
        ]
        // this.searchableList = ['name', 'age', 'weight', 'height', 'mobile']
        console.log('this.ItemsArray', this.ItemsArray)
    }
}

pipe.ts

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

@Pipe({
    name: 'FilterPipe',
})
export class FilterPipe implements PipeTransform {


    transform(items: any, filter: any, defaultFilter: boolean): any {
        if (!filter || !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) => {
                        console.log(filter[keyName])
                        return new RegExp(filter[keyName], 'gi').test(item[keyName]) || 
                        new RegExp(filter[keyName], 'gi').test(item.data[keyName]) ||
                        filter[keyName] == "";
                    });
                });
            }
        }
    }
}
2

There are 2 best solutions below

3
On

The best practice is using an object to make the filters, you can pass the object to the pipe call and make your filters there.

In your app.ts:

export class AppComponent {
    filterObject: {fullSearch: string, id: number, name: string, age: number, weight: number, height: number, mobile: string} = {
        fullSearch: null,
        id: null,
        name: null,
        age: null,
        weight: null,
        height: null,
        mobile: null
    }

in your app.html:

  <div class="md-form">
      <input type="text" [(ngModel)]="filterObject.fullSearch" class="form-control" placeholder="Search" />
  </div>
<tfoot>
    <tr>
        <th><input type="text" [(ngModel)]="filterObject.id"  placeholder="Search by ID" /></th>
        <th><input type="text" [(ngModel)]="filterObject.name" placeholder="Search by Name" /></th>
        <th><input type="text" [(ngModel)]="filterObject.age" placeholder="Search by Age" /></th>
        <th><input type="text" [(ngModel)]="filterObject.weight" placeholder="Search by Weight" /></th>
        <th><input type="text" [(ngModel)]="filterObject.height" placeholder="Search by Height" /></th>
        <th><input type="text" [(ngModel)]="filterObject.mobile" placeholder="Search by Mobile" /></th>
    </tr>
</tfoot>
<tbody>
<tr
    *ngFor="let item of ItemsArray| FilterPipe: filterObject; let i=index;">
    <td>{{ i+1 }}</td>
    <td>{{ item.name }}</td>
    <th>{{ item.data.age }}</th>
    <td>{{ item.data.weight }}</td>
    <td>{{ item.data.height}}</td>
    <td>{{ item.data.mobile }}</td>
</tr>
0
On

I think it worth trying Ag grid, It is powered with many features like column filter and good performance you can customize it as well .Ag Grid