Home:ALL Converter>Angular 4 Filter Search Custom Pipe

Angular 4 Filter Search Custom Pipe

Ask Time:2017-10-17T08:39:02         Author:T. Evans

Json Formatter

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 them are based on previous builds and don't seem to work. So I was building the Pipe and using the console to give me the values. However, I cannot seem to get the input text to show up.

Here are the previous places I have looked to find working examples:

Angular 4 Pipe Filter

http://jilles.me/ng-filter-in-angular2-pipes/

https://mytechnetknowhows.wordpress.com/2017/02/18/angular-2-pipes-passing-multiple-filters-to-pipes/

https://plnkr.co/edit/vRvnNUULmBpkbLUYk4uw?p=preview

https://www.youtube.com/results?search_query=filter+search+angular+2

https://www.youtube.com/watch?v=UgMhQpkjCFg

Here is the code that I currently have:

component.html

<input type="text" class="form-control" placeholder="Search" ngModel="query" id="listSearch" #LockFilter>

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

pipe.ts

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

@Pipe({
  name: 'LockFilter'
})

export class LockFilterPipe implements PipeTransform {
  transform(locked: any, query: string): any {
    console.log(locked); //this shows in the console
    console.log(query); //this does not show anything in the console when typing
    if(!query) {
      return locked;
    }
    return locked.filter((lock) => {
      return lock.User.toLowerCase().match(query.toLowerCase());
    });
  }
}

I have imported the pipe into the module.

I am still a little newer to Angular 4 and am trying to figure out how to make this work. Anyways thanks for your help!

I guess I will need to be more specific. I already built out a filter search in JS that does not filter all of the options, which is what I am trying to do. Not just filter the User Name. I am filtering all 4 pieces of data. I chose a Pipe as this was what Angular suggests you do as they originally used them in AngularJS. I am just trying to essentially recreate the filter pipe we had in AngularJS that they removed for performance. All options I have found don't work, or are from previous builds of Angular.

If you need anything else from my code let me know.

Author:T. Evans,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/46780843/angular-4-filter-search-custom-pipe
Chintan Kotadiya :

I have to implement search functionality in my local and Here is Updated your code. please do this way.\n\nHere is the code that I have to update.\n\ndirectory Structure\n\napp/\n _pipe/\n search/\n search.pipe.ts\n search.pipe.spec.ts\napp/ \n app.component.css\n app.component.html\n app.component.ts\n app.module.ts\n app.component.spec.ts\n\n\ncommand run for creating pipe \n\nng g pipe search\n\n\ncomponent.html\n\n<input type=\"text\" class=\"form-control\" placeholder=\"Search\" [(ngModel)]=\"query\" id=\"listSearch\">\n <div class=\"panel panel-default col-xs-12 col-sm-11\" *ngFor=\"let lock of locked | LockFilter: query\">\n <input type=\"checkbox\" (change)=\"openModal($event, lock)\" class=\"check\" id=\"{{lock.ID}}\">\n <label [for]=\"lock.ID\" class=\"check-label\"></label>\n <h3 class=\"card-text name\">{{lock.User}}</h3>\n <h3 class=\"card-text auth\">{{lock.AuthID}}</h3>\n <h3 class=\"card-text form\">{{lock.FormName}}</h3>\n <h3 class=\"card-text win\">{{lock.WinHandle}}</h3>\n</div>\n\n\ncomponent.js\n\nNote: In this file, i have to use dummy records for implementation and testing purpose.\n\nimport { Component, OnInit } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.css']\n})\n export class AppComponent implements OnInit{\n public search:any = '';\n locked: any[] = [];\n\n constructor(){}\n\n ngOnInit(){\n this.locked = [\n {ID: 1, User: 'Agustin', AuthID: '68114', FormName: 'Fellman', WinHandle: 'Oak Way'},\n {ID: 2, User: 'Alden', AuthID: '98101', FormName: 'Raccoon Run', WinHandle: 'Newsome'},\n {ID: 3, User: 'Ramon', AuthID: '28586', FormName: 'Yorkshire Circle', WinHandle: 'Dennis'},\n {ID: 4, User: 'Elbert', AuthID: '91775', FormName: 'Lee', WinHandle: 'Middleville Road'},\n ]\n }\n}\n\n\nmodule.ts\n\nimport { BrowserModule } from '@angular/platform-browser';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { AppComponent } from './app.component';\nimport { SearchPipe } from './_pipe/search/search.pipe';\n\n\n@NgModule({\n declarations: [\n AppComponent,\n SearchPipe\n ],\n imports: [\n BrowserModule,\n FormsModule\n ],\n providers: [],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n\n\npipe.ts\n\nimport { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'LockFilter'\n})\n\nexport class SearchPipe implements PipeTransform {\n transform(value: any, args?: any): any {\n\n if(!value)return null;\n if(!args)return value;\n\n args = args.toLowerCase();\n\n return value.filter(function(item){\n return JSON.stringify(item).toLowerCase().includes(args);\n });\n }\n}\n\n\nI hope you are getting the pipe functionality and this will help you.",
2017-12-10T12:13:30
Virendra Pandey :

Simple filterPipe for Angular 2+\n\nimport { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'filter'\n})\nexport class filterPipe implements PipeTransform {\n\n transform(items: any[], field:string, value: string): any[] {\n\n if(!items) return [];\n if(!value) return items;\n\n\n return items.filter( str => {\n return str[field].toLowerCase().includes(value.toLowerCase());\n });\n }\n}\n\n\nHere is the HTML\n\n<input type=\"text\" class=\"form-control\" placeholder=\"Search\" id=\"listSearch\" #search>\n <div class=\"panel panel-default col-xs-12 col-sm-11\" *ngFor=\"let lock of locked | filter:'propName': search.value>\n <input type=\"checkbox\" (change)=\"openModal($event, lock)\" class=\"check\" id=\"{{lock.ID}}\">\n <label [for]=\"lock.ID\" class=\"check-label\"></label>\n <h3 class=\"card-text name\">{{lock.User}}</h3>\n <h3 class=\"card-text auth\">{{lock.AuthID}}</h3>\n <h3 class=\"card-text form\">{{lock.FormName}}</h3>\n <h3 class=\"card-text win\">{{lock.WinHandle}}</h3>\n</div>\n\n\nin HTML PropName is dummy text. In place of PropName use your any object property key.",
2018-08-29T13:05:37
Madhavi Gandu :

Follow this code to filter specific column instead of all columns in table using custom filters\n\nfilename.component.html\n\n\n \n\n\n<table class=\"table table-striped\">\n <thead>\n <tr>\n <th scope=\"col\">product name </th>\n <th scope=\"col\">product price</th>\n </tr>\n </thead>\n\n <tbody>\n <tr *ngFor=\"let respObj of data | filter:searchText\">\n <td>{{respObj.product_name}}</td>\n <td>{{respObj.product_price}}</td>\n </tr>\n </tbody>\n</table>\n\n\nfilename.component.ts\n\nimport { Component, OnInit } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\n\n\n@Component({\n selector: 'app-productlist',\n templateUrl: './productlist.component.html',\n styleUrls: ['./productlist.component.css']\n})\n\nexport class ProductlistComponent implements OnInit {\n\n searchText: string;\n\n constructor(private http: HttpClient) { }\n data: any;\n ngOnInit() {\n this.http.get(url)\n .subscribe(\n resp => {\n this.data = resp;\n\n }\n )\n }\n}\n\n\nfilename.pipe.ts\nCreate a class and implement it with PipeTransform, in that way we can write custom filter with transform method.\n\nimport { Pipe, PipeTransform } from '@angular/core';\n@Pipe({\n name: 'filter'\n})\nexport class PipeList implements PipeTransform {\n transform(value: any, args?: any): any {\n if(!args)\n return value;\n return value.filter(\n item => item.product_name.toLowerCase().indexOf(args.toLowerCase()) > -1\n );\n }\n}\n",
2019-12-18T08:35:04
Prashant M Bhavsar :

Here is simple explanation to create custom pipe..as available pipes does not support it.\nI found this solution here..Nicely explained it\n\nCreate pipe file advanced-filter.pipe\n\nimport {Pipe, PipeTransform} from '@angular/core';\n\n@Pipe({\n name: 'advancedFilters'\n})\n\nexport class AdvancedFilterPipe implements PipeTransform {\n\n transform(array: any[], ...args): any {\n if (array == null) {\n return null;\n }\n\n return array.filter(function(obj) {\n if (args[1]) {\n return obj.status === args[0];\n }\n return array;\n });\n\n }\n\n}\n\n\nHere, array – will be data array passed to your custom pipe\nobj – will be the object of data by using that object you can add condition to filter data\n\nWe have added condition obj.status === args[0] so that data will get filter on status which is passed in .html file\n\nNow, import and declare custom pipe in module.ts file of component:\n\nimport {AdvancedFilterPipe} from './basic-filter.pipe';\n\n//Declare pipe\n\n@NgModule({\n\n imports: [DataTableModule, HttpModule, CommonModule, FormsModule, ChartModule, RouterModule],\n\n declarations: [ DashboardComponent, AdvancedFilterPipe],\n\n exports: [ DashboardComponent ],\n\n providers: [{provide: HighchartsStatic}]\n\n})\n\n\nUse of created custom angular pipe in .html file\n\n<table class=\"table table-bordered\" [mfData]=\"data | advancedFilters: status\" #mf=\"mfDataTable\" [mfRowsOnPage]=\"rowsOnPage\" [(mfSortBy)]=\"sortBy\" [(mfSortOrder)]=\"sortOrder\">\n\n <thead>\n <tr>\n <th class=\"sortable-column\" width=\"12%\">\n <mfDefaultSorter by=\"inquiry_originator\">Origin</mfDefaultSorter>\n </th>\n </tr>\n </thead>\n\n <tbody class=\"dashboard-grid\">\n\n <ng-container *ngFor=\"let item of mf.data; let counter = index;\">\n\n <tr class=\"data-row {{ item.status }} grid-panel-class-{{ counter }}\"> \n\n <td class=\"align-center\">{{ item.trn_date }}</td>\n\n <td>{{ item.trn_ref }}</td>\n\n </tr>\n\n </tbody>\n\n</table>\n\n\n//If you are using *ngFor and want to use custom angular pipe then below is code\n\n<li *ngFor=\"let num of (numbers | advancedFilters: status\">\n {{ num | ordinal }}\n</li>\n",
2018-12-17T13:53:59
Sen :

A simple Java-like logic that I could think of which might not look very compact in terms of typescript, is as below:\n\n\r\n\r\ntransform(value:IBook[], keyword:string) { \r\n if(!keyword)\r\n return value;\r\n let filteredValues:any=[]; \r\n for(let i=0;i<value.length;i++){\r\n if(value[i].name.toLowerCase().includes(keyword.toLowerCase())){\r\n filteredValues.push(value[i]);\r\n }\r\n }\r\n return filteredValues;\r\n }\r\n<h2>Available Books</h2>\r\n<input type=\"text\" [(ngModel)]=\"bookName\"/>\r\n<ul class=\"books\">\r\n <li *ngFor=\"let book of books | search:bookName\"\r\n [class.selected]=\"book === selectedBook\"\r\n (click)=\"onSelect(book)\">\r\n <span class=\"badge\">{{book.name}}</span>\r\n </li>\r\n</ul>",
2019-03-20T20:02:18
yy