Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 Filter Search Custom Pipe

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.

like image 701
T. Evans Avatar asked Nov 29 '22 22:11

T. Evans


2 Answers

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.

like image 99
Chintan Kotadiya Avatar answered Dec 04 '22 09:12

Chintan Kotadiya


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.

like image 43
Virendra Pandey Avatar answered Dec 04 '22 11:12

Virendra Pandey