5

I have two components called list and details, On clicking to particular list-item in list component. It will emit selected/clicked list-item to details component as in below image.

enter image description here

Now i have placed another component called search above the list component like this:

enter image description here

How can i apply filter for the list-items present in the list component? So that i can search the list-items easily.

Stackblitz Link

Empty_Soul
  • 799
  • 2
  • 13
  • 31
  • Output the searched string from `app-search`, save it in `list-component` and do something like `*ngIf="contact.includes(searchQuery)"` for each `mat-list-option`. Or build a filter pipe for `*ngFor` like this: https://stackoverflow.com/questions/44769748/angular-4-pipe-filter – Roberto Zvjerković Jan 23 '19 at 10:13

2 Answers2

17

You can create a pipe for this.

Here is a working solution

I created a pipe and called it ListFilterPipe

@Pipe({
  name: 'listFilter'
})
export class ListFilterPipe implements PipeTransform {

  transform(list: any[], filterText: string): any {
    return list ? list.filter(item => item.name.search(new RegExp(filterText, 'i')) > -1) : [];
  }

}

And simply use it within *ngFor as follows

<h4>List</h4>
<div class="main-div">
<app-search [(searchModel)]="searchModel"></app-search>
  <div class="list">
    <mat-selection-list  #contact>
      <mat-list-option  *ngFor="let contact of contacts | listFilter: searchModel">
        <a mat-list-item (click)="onSelect(contact)"><span>{{ contact?.name }}</span></a>
      </mat-list-option>
    </mat-selection-list>
  </div>

Also, added and input and output to search.component so that we can update our searchModel

search.component.ts

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {

  @Input() searchModel;

  @Output() searchModelChange: EventEmitter<any> = new EventEmitter();

  constructor() { }

  ngOnInit() {
  }

  updateSearchModel(value) {
    this.searchModel = value;
    this.searchModelChange.emit(this.searchModel);
  }

}

search.component.html

<mat-form-field floatLabel="never">
  <input matInput class="searching-customer" type="text"  placeholder="Search" 
         [ngModel]="searchModel" 
         (ngModelChange)="updateSearchModel($event)">
</mat-form-field>
Bunyamin Coskuner
  • 8,719
  • 1
  • 28
  • 48
3

You can pass the List of contacts to Search Comonent For that change in List.component.html

<h4>List</h4>
<div class="main-div">
<app-search [list]="contacts" ></app-search>
  <div class="list">
    <mat-selection-list  #contact>
        <mat-list-option  *ngFor="let contact of contacts">
            <a mat-list-item (click)="onSelect(contact)"><span>{{ contact?.name }}</span></a>
        </mat-list-option>
      </mat-selection-list>
  </div>
</div>  

Inside your search component - get value of input box - filter the list by that input value

Search.component.html

<mat-form-field floatLabel=never >
  <input matInput class="searching-customer" type="text"  placeholder="Search" (input)="search($event.target.value)"  >
</mat-form-field>

search.component.ts

import { Component, OnInit , Input} from '@angular/core';
import { IContact } from '../models';

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {

@Input()
public list:  IContact[] ;
searchedList : any;

  constructor() { }

  ngOnInit() {
  }

  // This function will be called on every key press for input text box
  search(value)
  {
    this.searchedList = this.list.filter(
      (val)=> val['name'].includes(value))
    //Searched Data
    console.log(this.searchedList)
  }
}
Vishal Hasnani
  • 720
  • 7
  • 21