Skip to content Skip to sidebar Skip to footer

How To Add A Search Filter To A Select Option In Angular

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 opt

Solution 1:

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 2:

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


Solution 3:

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 4:

I couldn't find any easy way to do this for the select, but the autocomplete component seems to do something very close to what is desired. The only issue with it is, that it does not require the value to be one of the options. That's why I created the following directive:

// mat-autocomplete-force-select.directive.ts
import { Directive, Input } from '@angular/core';
import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms';
import { MatAutocomplete } from '@angular/material/autocomplete';

@Directive({
  selector: '[matAutocomplete][appMatAutocompleteForceSelect]',
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: MatAutocompleteForceSelectDirective,
      multi: true,
    }
  ]
})
export class MatAutocompleteForceSelectDirective implements Validator {
  @Input('matAutocomplete')
  matAutocomplete!: MatAutocomplete;

  validate(control: AbstractControl): ValidationErrors | null {
    if (this.matAutocomplete.options && !this.isOptionOfAutocomplete(control.value)) {
      return { 'notAnAutocompleteValue' : true }
    }

    return null;
  }

  private isOptionOfAutocomplete(value: string) {
    return this.matAutocomplete.options.find(option => option.value === value) !== undefined;
  }
}

After that, you can add the directive to the input of the autocomplete, and it will have an error of notAnAutocompleteValue if it's not that.

<input matInput type="text" appMatAutocompleteForceSelect [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" >
  <!-- ... -->
</mat-autocomplete>

For anyone unfamiliar with the autocomplete component, https://material.angular.io/components/autocomplete/overview will be helpful.

Cheers :)


Post a Comment for "How To Add A Search Filter To A Select Option In Angular"