Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement a search filter for the <mat-select> component of angular material

Trying to implement a simple application in angular 2 using angular material.
I implemented a simple table with pagination .

I also used mat-select component, but for this i want implement a search filter to type and search the required option from the list.

Below shown is my .html file

<table>
 <tr><td> Department</td>
<td>
  <mat-form-field>
  <mat-select placeholder=" ">
    <mat-option> </mat-option>
    <mat-option *ngFor="let dep of dept" [value]="dep">{{dep}}</mat-option>
  </mat-select>
</mat-form-field><br/>
</td>
</tr>


</table>

<br><br>

<button >Search</button>

<button >Reset</button>

<button >Close</button>


<mat-card>
<div class="example-container mat-elevation-z8">
  <mat-table #table [dataSource]="dataSource">

    <!-- Account No. Column -->
    <ng-container matColumnDef="accno">
      <mat-header-cell *matHeaderCellDef> Account No. </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.accno}} </mat-cell>
    </ng-container>

    <!-- Account Description Column -->
    <ng-container matColumnDef="accdesc">
      <mat-header-cell *matHeaderCellDef> Account Description </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.accdesc}} </mat-cell>
    </ng-container>

    <!-- Investigator Column -->
    <ng-container matColumnDef="investigator">
      <mat-header-cell *matHeaderCellDef> Investigator </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.investigator}} </mat-cell>
    </ng-container>

    <!-- Account CPC Column -->
    <ng-container matColumnDef="accCPC">
      <mat-header-cell *matHeaderCellDef> Account CPC </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.accCPC}} </mat-cell>
    </ng-container>

     <!-- Location Column -->
    <ng-container matColumnDef="location">
      <mat-header-cell *matHeaderCellDef> Location </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.location}} </mat-cell>
       </ng-container>


 <!-- Client Dept ID Column -->
    <ng-container matColumnDef="cdeptid">
      <mat-header-cell *matHeaderCellDef> ClientDeptID </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.cdeptid}} </mat-cell>
       </ng-container>


        <!-- Dept Description Column -->
    <ng-container matColumnDef="depdesc">
      <mat-header-cell *matHeaderCellDef> Dept Description  </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.depdesc}} </mat-cell>
       </ng-container>


    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>

  <mat-paginator #paginator
                 [pageSize]="10"
                 [pageSizeOptions]="[5, 10, 20]">
  </mat-paginator>
</div>
</mat-card>

Below shown is my .ts file

import {Component, ViewChild} from '@angular/core';
import {MatPaginator, MatTableDataSource} from '@angular/material';

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html',
  styleUrls: ['./account.component.scss']
})

export class AccountComponent {



  dept = [
    'Administrative Computer',
    'Agosta Laboratory',
    'Allis Laboratory',
    'Bargaman Laboratory',
    'Bio-Imaging Resource Center',
    'Capital Projects',
    'Casanova Laboratory',
    'Darst Laboratory',
    'Darnell James Laboratory',
    'Deans Office',
    'Energy Consultant',
    'Electronic Shop',
    'Facilities Management',
    'Field Laboratory'
  ];


  displayedColumns = ['accno', 'accdesc', 'investigator', 'accCPC','location','cdeptid','depdesc'];
  dataSource = new MatTableDataSource<Element>(ELEMENT_DATA);

  @ViewChild(MatPaginator) paginator: MatPaginator;

   ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
  }
}

export interface Element {
  accno: number;
  accdesc: string;
  investigator: string;
  accCPC: string;
  location:string;
  cdeptid: number;
  depdesc: string;
}

const ELEMENT_DATA: Element[] = [
  {accno: 5400343, accdesc: 'ASTRALIS LTD', investigator:'Kruger, James G.', accCPC: 'OR',location:'ON',cdeptid: 110350,depdesc: 'Kruger Laboratory'}

  ];

can anybody please help me to implement search filter with mat-select component in my application?

like image 742
Heena Avatar asked Jan 25 '18 12:01

Heena


4 Answers

HTML

<h4>mat-select</h4> <mat-form-field>   <mat-label>State</mat-label>   <mat-select>      <input (keyup)="onKey($event.target.value)"> // **Send user input to TS**     <mat-option>None</mat-option>     <mat-option *ngFor="let state of selectedStates" [value]="state">{{state}}</mat-option>   </mat-select> </mat-form-field> 

TS

states: string[] = [     'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware',     'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky',     'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi',     'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico',     'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania',     'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',     'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'   ];  **// Initially fill the selectedStates so it can be used in the for loop**  selectedStates = this.states;   **// Receive user input and send to search method** onKey(value) {  this.selectedStates = this.search(value); }  **// Filter the states list and send back to populate the selectedStates** search(value: string) {    let filter = value.toLowerCase();   return this.states.filter(option => option.toLowerCase().startsWith(filter)); } 

The solution is rather easy. Should work like a charm :)

like image 107
GoranSu Avatar answered Sep 25 '22 15:09

GoranSu


  • At the moment you can use 3rd party component on top of mat-select: https://www.npmjs.com/package/ngx-mat-select-search

  • Demo (https://stackblitz.com/github/bithost-gmbh/ngx-mat-select-search-example)

Btw. This might be supported in some of upcoming the Angular Material releases. Discussion is already open: https://github.com/angular/components/issues/5697

like image 41
Artem Avatar answered Sep 23 '22 15:09

Artem


I found the solution for searching the dropdown values

Here is the html code

<mat-select class="yourClass" [(ngModel)]="searchObj">
            <input class="yourClass" placeholder ="search " (keyup)="onKey($event.target.value)"> 
            <mat-option *ngIf="someCondition" [value]='Select'>Select</mat-option>
            <mat-option *ngFor="let data of dataArray" [value]="data">{{data}}</mat-option>
          </mat-select>

Here is the typescript code key function getting the entered value

    onKey(value) { 
            this.dataArray= []; 
            this.selectSearch(value);       
        }

performing the searching given value inside the provided values in dropdown

selectSearch(value:string){
            let filter = value.toLowerCase();
            for ( let i = 0 ; i < this.meta.data.length; i ++ ) {
                let option = this.meta.data[i];
                if (  option.name.toLowerCase().indexOf(filter) >= 0) {
                    this.dataArray.push( option );
                }
            }
        }

this function is goes where your main search function calling api and getting the data

this.meta.data

        searchDpDropdown(){
            for ( let i = 0 ; i < this.meta.data.length; i ++ ) {
                this.dataArray.push( this.meta.data[i] );
            }
        }
like image 37
Irrfan23 Avatar answered Sep 21 '22 15:09

Irrfan23


I've found out that primefaces for angular does have a multiselect list that allows you to search for listitems. It also includes a builtin select-all button! You can find it here https://www.primefaces.org/primeng/#/multiselect You can install primefaces with npm install primeng --save

like image 30
Maurice Avatar answered Sep 21 '22 15:09

Maurice