1

I want to add search functionality in my mat multiple select dropdown. I have done this thing in Jquery but I want to do same thing in Angular material. Here is the design pic. Here is the image

3

4 Answers 4

9

Try this example in stackblitz

stackblitz example with angular 8

in your html file

 <h2>Multiple selection</h2>
  <p>
    <mat-form-field>
      <mat-select [formControl]="bankMultiCtrl" placeholder="Banks" [multiple]="true">
        <mat-select-search [formControl]="bankMultiFilterCtrl"></mat-select-search>
        <mat-option *ngFor="let bank of filteredBanksMulti | async" [value]="bank">
          {{bank.name}}
        </mat-option>
      </mat-select>
    </mat-form-field>
  </p>
  <p>
    Selected Banks: 
  </p>
  <ul *ngFor="let bank of bankMultiCtrl?.value">
    <li>{{bank.name}}</li>
  </ul>
Sign up to request clarification or add additional context in comments.

5 Comments

This is in Angular2 mate and I am making this in angular7
@RohitSoni here is angular 5. It will work in angular 7 also. Try it
@RohitSoni here the updated answer is in angular 8 version. No difference with angular 7 also. Please use necessary node packages and use @ViewChild('singleSelect', {static: false}) singleSelect: MatSelect; with angular 8.
@RohitSoni is your problem solved or do you wants the exact angular 7 project?
@dasunse It is possible to add the option to select all.
6

The problem is that the material select doesn't have the functionality for an input. Therefore you need to do a bit of css to make it look good.

<mat-select multiple>

  <mat-form-field>
    <input matInput placeholer="Search" (input)="filterOptione($event.target.value)" />
  </mat-form-field>

  <mat-option *ngFor="let option of options" [value]="option">
    {{option}}
  </mat-option>


</mat-select> 

The filter function:

public filterOptions(filter: string): void {
 this.options = this._unfilteredOptions.filter(x => x.toLowerCase().includes(filter.toLowerCase()));
}

2 Comments

The search functionality is missing
@RohitSoni try this. I think this will work also. When you clear if your search key is empty show all list.
0

Instead of using a mat-select, use a mat-autocomplete. https://material.angular.io/components/autocomplete/overview

You can make it work the same as a mat-select by populating it with all values when the input is blank, then filter the auto-complete options when the input value changes.

Again, the trick is to make it show all available options when the input is empty.

Hope this helps.

Edit:

I should add that I use a mat-chip-list (https://material.angular.io/components/chips/overview) for the multi-select part of the equation. When an option is selected, add it to the chip list, and you can add X icons to each chip to remove things from the list.

Granted, this is my personal flavor of a multi-select input, but I thought it might give you some ideas.

3 Comments

It won't work as I need to select multiple instead of one, for that, I need to select and store multiple values in an array
I was going to create an example of what I mean, but found that the Angular Material docs have it pretty close to what I was thinking - stackblitz.com/angular/… Found it in the Chips examples - Chips Autocomplete
Thank you, exactly what I was looking for! Sadly couldn't find a good example, right away, without using third party libraries.
0

My approach for this solution is as follow: I populated mat-option from an array of object with many parameters. Of course, I used only one or 2 parameters to show, but I want my user to search by any value of the object even the values of the parameters that are not shown in the mat-option, So, in the template I created an input field like the follow

  <mat-form-field>
    <mat-select multiple>

        <input matInput placeholer="Search" (input)="search($event)" />
      <mat-option *ngFor="let d of data" [value]="d">
        {{d}}
      </mat-option>
    
    
    </mat-select> 
 </mat-form-field>

And in the .ts file:

AllData:any[]; //of course the type will be the type of your data.

Search(event: any, PropertyToSearch: string)
  {
    this.data = this.AllData.filter(x =>
    {
      for (let v of String(event.target.value).trim().split(" "))
      {
        if (Object.values(x).join(" ").toLowerCase().includes(v.toLowerCase()))
          return true;
      }
      return false;
    });
  }

In this function, I creates an array of the words entered by the user, and joined all the values of the each object inside the data array and search each word inside that joined string. Why did I do that? Because there is a case when the user by mistake add 2 spaces between 2 words like this "word1 word2".

If I used simple solution like

this.AllData.filter(x => x.toLowerCase().includes(event.target.value.toLowerCase()));

and the user write the words with only one space between the words, the matched result will not shown. Also, my solution make the user use any value he remember to search with.

1 Comment

This does not work. because when you have any option selected and you search for other option and if the results of the search do not contain your previously selected option then the selected data will get overridden

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.