Angular 4 Filter Search Custom Pipe

后端 未结 6 1854
清歌不尽
清歌不尽 2020-11-28 15:14

So I am trying to build a custom pipe to do a search filter of multiple values in a ngFor loop. I have looked for a number of hours for a good working example, and most of t

相关标签:
6条回答
  • 2020-11-28 15:16

    Follow this code to filter specific column instead of all columns in table using custom filters

    filename.component.html

    <table class="table table-striped">
      <thead>
        <tr>
          <th scope="col">product name </th>
          <th scope="col">product price</th>
       </tr>
      </thead>
    
      <tbody>
        <tr *ngFor="let respObj of data | filter:searchText">
          <td>{{respObj.product_name}}</td>
          <td>{{respObj.product_price}}</td>
        </tr>
     </tbody>
    </table>
    

    filename.component.ts

    import { Component, OnInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    
    @Component({
      selector: 'app-productlist',
      templateUrl: './productlist.component.html',
      styleUrls: ['./productlist.component.css']
    })
    
    export class ProductlistComponent implements OnInit  {
    
      searchText: string;
    
      constructor(private http: HttpClient) { }
      data: any;
      ngOnInit() {
        this.http.get(url)
          .subscribe(
            resp => {
             this.data = resp;
    
            }
          )
      }
    }
    

    filename.pipe.ts
    Create a class and implement it with PipeTransform, in that way we can write custom filter with transform method.

    import { Pipe, PipeTransform } from '@angular/core';
    @Pipe({
      name: 'filter'
    })
    export class PipeList implements PipeTransform {
      transform(value: any, args?: any): any {
        if(!args)
         return value;
        return value.filter(
          item => item.product_name.toLowerCase().indexOf(args.toLowerCase()) > -1
       );
      }
    }
    
    0 讨论(0)
  • 2020-11-28 15:24

    Here is simple explanation to create custom pipe..as available pipes does not support it. I found this solution here..Nicely explained it

    Create pipe file advanced-filter.pipe

    import {Pipe, PipeTransform} from '@angular/core';
    
    @Pipe({
      name: 'advancedFilters'
    })
    
    export class AdvancedFilterPipe implements PipeTransform {
    
      transform(array: any[], ...args): any {
        if (array == null) {
          return null;
        }
    
        return array.filter(function(obj) {
          if (args[1]) {
            return obj.status === args[0];
          }
          return array;
        });
    
      }
    
    }
    

    Here, array – will be data array passed to your custom pipe obj – will be the object of data by using that object you can add condition to filter data

    We have added condition obj.status === args[0] so that data will get filter on status which is passed in .html file

    Now, import and declare custom pipe in module.ts file of component:

    import {AdvancedFilterPipe} from './basic-filter.pipe';
    
    //Declare pipe
    
    @NgModule({
    
        imports: [DataTableModule, HttpModule, CommonModule, FormsModule, ChartModule, RouterModule],
    
        declarations: [ DashboardComponent, AdvancedFilterPipe],
    
        exports: [ DashboardComponent ],
    
        providers: [{provide: HighchartsStatic}]
    
    })
    

    Use of created custom angular pipe in .html file

    <table class="table table-bordered" [mfData]="data | advancedFilters: status" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
    
                    <thead>
                           <tr>
                                 <th class="sortable-column" width="12%">
                                     <mfDefaultSorter by="inquiry_originator">Origin</mfDefaultSorter>
                                 </th>
                            </tr>
                    </thead>
    
                    <tbody class="dashboard-grid">
    
                                    <ng-container *ngFor="let item of mf.data; let counter = index;">
    
                                                    <tr class="data-row {{ item.status }} grid-panel-class-{{ counter }}">                                      
    
                                                                    <td class="align-center">{{ item.trn_date }}</td>
    
                                                                    <td>{{ item.trn_ref }}</td>
    
                                                    </tr>
    
                    </tbody>
    
    </table>
    
    
    //If you are using *ngFor and want to use custom angular pipe then below is code
    
    <li *ngFor="let num of (numbers | advancedFilters: status">
      {{ num | ordinal }}
    </li>
    
    0 讨论(0)
  • 2020-11-28 15:29

    I have to implement search functionality in my local and Here is Updated your code. please do this way.

    Here is the code that I have to update.

    directory Structure

    app/
       _pipe/
            search/
              search.pipe.ts
              search.pipe.spec.ts
    app/ 
       app.component.css
       app.component.html
       app.component.ts
       app.module.ts
       app.component.spec.ts
    

    command run for creating pipe

    ng g pipe search
    

    component.html

    <input type="text" class="form-control" placeholder="Search" [(ngModel)]="query" id="listSearch">
        <div class="panel panel-default col-xs-12 col-sm-11" *ngFor="let lock of locked | LockFilter: query">
        <input type="checkbox" (change)="openModal($event, lock)" class="check" id="{{lock.ID}}">
        <label [for]="lock.ID" class="check-label"></label>
        <h3 class="card-text name">{{lock.User}}</h3>
        <h3 class="card-text auth">{{lock.AuthID}}</h3>
        <h3 class="card-text form">{{lock.FormName}}</h3>
        <h3 class="card-text win">{{lock.WinHandle}}</h3>
    </div>
    

    component.js

    Note: In this file, i have to use dummy records for implementation and testing purpose.

    import { Component, OnInit } from '@angular/core';
    import { FormsModule }   from '@angular/forms';
    
    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
        export class AppComponent implements OnInit{
        public search:any = '';
        locked: any[] = [];
    
        constructor(){}
    
        ngOnInit(){
            this.locked = [
                {ID: 1, User: 'Agustin', AuthID: '68114', FormName: 'Fellman', WinHandle: 'Oak Way'},
                {ID: 2, User: 'Alden', AuthID: '98101', FormName: 'Raccoon Run', WinHandle: 'Newsome'},
                {ID: 3, User: 'Ramon', AuthID: '28586', FormName: 'Yorkshire Circle', WinHandle: 'Dennis'},
                {ID: 4, User: 'Elbert', AuthID: '91775', FormName: 'Lee', WinHandle: 'Middleville Road'},
            ]
        }
    }
    

    module.ts

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule }   from '@angular/forms';
    import { AppComponent } from './app.component';
    import { SearchPipe } from './_pipe/search/search.pipe';
    
    
    @NgModule({
      declarations: [
        AppComponent,
        SearchPipe
      ],
      imports: [
        BrowserModule,
        FormsModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    pipe.ts

    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
        name: 'LockFilter'
    })
    
    export class SearchPipe implements PipeTransform {
        transform(value: any, args?: any): any {
    
            if(!value)return null;
            if(!args)return value;
    
            args = args.toLowerCase();
    
            return value.filter(function(item){
                return JSON.stringify(item).toLowerCase().includes(args);
            });
        }
    }
    

    I hope you are getting the pipe functionality and this will help you.

    0 讨论(0)
  • 2020-11-28 15:30

    Simple filterPipe for Angular 2+

    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
      name: 'filter'
    })
    export class filterPipe implements PipeTransform {
    
      transform(items: any[], field:string, value: string): any[] {
    
        if(!items) return [];
        if(!value) return items;
    
    
        return items.filter( str => {
              return str[field].toLowerCase().includes(value.toLowerCase());
            });
       }
    }
    

    Here is the HTML

    <input type="text" class="form-control" placeholder="Search" id="listSearch" #search>
        <div class="panel panel-default col-xs-12 col-sm-11" *ngFor="let lock of locked | filter:'propName': search.value>
        <input type="checkbox" (change)="openModal($event, lock)" class="check" id="{{lock.ID}}">
        <label [for]="lock.ID" class="check-label"></label>
        <h3 class="card-text name">{{lock.User}}</h3>
        <h3 class="card-text auth">{{lock.AuthID}}</h3>
        <h3 class="card-text form">{{lock.FormName}}</h3>
        <h3 class="card-text win">{{lock.WinHandle}}</h3>
    </div>
    

    in HTML PropName is dummy text. In place of PropName use your any object property key.

    0 讨论(0)
  • 2020-11-28 15:32

    A simple Java-like logic that I could think of which might not look very compact in terms of typescript, is as below:

    transform(value:IBook[], keyword:string) {       
            if(!keyword)
            return value;
            let filteredValues:any=[];      
            for(let i=0;i<value.length;i++){
                if(value[i].name.toLowerCase().includes(keyword.toLowerCase())){
                    filteredValues.push(value[i]);
                }
            }
            return filteredValues;
        }
    <h2>Available Books</h2>
    <input type="text" [(ngModel)]="bookName"/>
    <ul class="books">
      <li *ngFor="let book of books | search:bookName"
        [class.selected]="book === selectedBook"
        (click)="onSelect(book)">
        <span class="badge">{{book.name}}</span>
      </li>
    </ul>

    0 讨论(0)
  • 2020-11-28 15:34

    You can use the given function instead on the (input) event of your input box

    filterNames(event)
    {
     this.names_list = this.names_list.filter(function(tag) {
     return tag.name.toLowerCase().indexOf(event.target.value.toLowerCase()) >= 0;
     });
    }
    

    Hope it helps..

    0 讨论(0)
提交回复
热议问题