How to add a search filter to a select option in angular

36,809

Solution 1

If you want to filter your array menaces by typing on the first letter, then it is possible to filter your array like this:

HTML:

<select class="form-control" 
     (change)="mnVuln?.menaceActif?.menace.id = $event.target.value; 
               updateMenaceProcessus();
               filterMenaces($event)">
    <option></option>
    <option *ngFor="let menace of menaces" 
        [value]="menace.id" 
        [selected]="menace.id === mnVuln?.menaceActif?.menace.id">
        {{menace.nom}}</option>
</select>

TypeScript:

origMenaces = [];

methodAPIToGetMenaces() {
   this.yourService()
       .subscribe(s=> {
           this.menaces = s;
           this.origMenaces = s;
       });
}

filterMenaces(str: string) {
    if (typeof str === 'string') {
        this.menaces = this.origMenaces.filter(a => a.toLowerCase()
                                             .startsWith(str.toLowerCase())); 
    }
}

UPDATE 1:

If you want to filter by input value:

HTML:

<input type="text"         
    (ngModelChange)="filterItem($event)" 
    [(ngModel)]="filterText">
    <br>
<select 
     #selectList
     [(ngModel)]="myDropDown" 
    (ngModelChange)="onChangeofOptions($event)">
    <option value="empty"></option>
    <option *ngFor="let item of items">         
        {{item}}
    </option>    
</select>
<p>items {{ items | json }}</p>

TypeScript:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 4';
  myDropDown : string;
  items = ['one', 'two', 'three'];
  origItems = ['one', 'two', 'three'];
  @ViewChild('selectList', { static: false }) selectList: ElementRef;

  onChangeofOptions(newGov) {
     console.log(newGov);
  }

  filterItem(event){
      if(!event){
          this.items = this.origItems;
      } // when nothing has typed*/   
      if (typeof event === 'string') {
          console.log(event);
          this.items = this.origItems.filter(a => a.toLowerCase()
                                             .startsWith(event.toLowerCase())); 
      }
      console.log(this.items.length);
      this.selectList.nativeElement.size = this.items.length + 1 ;       
   }      
}

Please, see work example at stackblitz

Solution 2

If you want to filter in select option, you can use datalist control of HTML. If you use it, there is no need to do extra coding for filtering. It has built-in functionality for filtering.

HTML :

<input list="menace" name="menace">

<datalist id="menace">
     <option *ngFor="let menace of menaces">{{menace.nom}} </option>
</datalist>

Solution 3

I think you can use ng-select: https://www.npmjs.com/package/@ng-select/ng-select for Yor Requirement

Share:
36,809
PowerGirl
Author by

PowerGirl

Updated on July 17, 2022

Comments

  • PowerGirl
    PowerGirl almost 2 years

    I'm trying to add to add a search filter in my select option list because there are many options and I think that without a search, it will not be easy for the user to find the option that he wants to select.

    I hope you will understand me because I'm not good at English.

    Here's my code (it's just a part of my table)

    <ng-container *ngFor="let menaceProcessus of menaceProcessusTab">
        <tr>
             <td colspan="4" bgcolor="#f1f1f1"><b>{{menaceProcessus?.processus?.nom}}</b></td>
        </tr>
        <ng-container *ngFor="let actif of menaceProcessus?.actifs">
            <tr>
                <td [rowSpan]="actif?.menaces?.length+1">{{actif?.actif?.nom}}</td>
            </tr>
         <ng-container *ngFor="let mnVuln of actif?.menaces">
            <tr>
                 <td>{{mnVuln?.vulnerabilite?.nom}}</td>
                 <td>
                     <select class="form-control" 
                      (change)="mnVuln?.menaceActif?.menace.id = $event.target.value; 
                                updateMenaceProcessus()">
                          <option></option>
                          <option *ngFor="let menace of menaces" 
                              [value]="menace.id" 
                              [selected]="menace.id === mnVuln?.menaceActif?.menace.id">
                            {{menace.nom}}</option>
                      </select>
                  </td>
                  <td>
                     <input class="form-control" 
                        type="text" [value]="mnVuln?.menaceActif?.probabilite"> 
                  </td>
              </tr>
          </ng-container>
        </ng-container>
     </ng-container>
    
  • PowerGirl
    PowerGirl over 4 years
    what about the input value ?
  • Parth Dhankecha
    Parth Dhankecha over 4 years
    Selected option will be displayed in input field. Yo can bind input with your selected value.
  • PowerGirl
    PowerGirl over 4 years
    <input list="menace" name="menace"> <datalist id="menace" (change)="mnVuln?.menaceActif?.menace.id = $event.target.value; updateMenaceProcessus()"> <option *ngFor="let menace of menaces" [selected]="menace.id === mnVuln?.menaceActif?.menace.id">{{menace.nom}} </option> </datalist> this is what i tried to do but it doesn't work
  • PowerGirl
    PowerGirl over 4 years
    Thank you ! i'll take a look
  • StepUp
    StepUp over 4 years
    @PowerGirl Could you say exactly what doesn't work? I've tested and it works
  • PowerGirl
    PowerGirl over 4 years
    the problem is here : @ViewChild('selectList') selectList: ElementRef; ! @ViewChild must have 2 parameters
  • StepUp
    StepUp over 4 years
    @PowerGirl I've updated my answer. Please, see my updated answer. In addition, I've created an example stackblitz.com/edit/angular-qjf89w
  • Parth Dhankecha
    Parth Dhankecha over 4 years
    To bind datalist follow this link of stackoverflow bind datalist and get object
  • StepUp
    StepUp over 4 years
    @PowerGirl I am glad to help you!)
  • umunBeing
    umunBeing over 2 years
    Perfect! thanks a ton