25

Does any one know how to programmatically open or close mat-select? As pert the api there are methods for open and close but don't know how to call those methods from component and there isn't any example showing that on site.

Thanks

Bhavesh
  • 819
  • 1
  • 17
  • 31

4 Answers4

44

In order to access these properties you need to identify the DOM element and access it with a ViewChild:

component.html

  <mat-select #mySelect placeholder="Favorite food">
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{ food.viewValue }}
    </mat-option>
  </mat-select>

component.ts

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

@Component({
  selector: 'select-overview-example',
  templateUrl: 'select-overview-example.html',
  styleUrls: ['select-overview-example.css'],
})
export class SelectOverviewExample {
  @ViewChild('mySelect') mySelect;
  foods = [
    {value: 'steak-0', viewValue: 'Steak'},
    {value: 'pizza-1', viewValue: 'Pizza'},
    {value: 'tacos-2', viewValue: 'Tacos'}
  ];

  click() {
    this.mySelect.open();
  }
}

View a working stackblitz here.

Stefan Falk
  • 23,898
  • 50
  • 191
  • 378
Z. Bagley
  • 8,942
  • 1
  • 40
  • 52
  • I am getting error: Cannot read property 'open' of undefined – Solomon Raja Dec 30 '20 at 14:49
  • @SolomonRaja This will often happen if the `mat-select` isn't available in DOM. Make sure that any `.open()` calls are made after the view is initialized (won't be available in constructor, OnInit, etc.). Make sure there are no `*ngIf` or similar causing it to not be rendered in the DOM as well. – Z. Bagley Dec 30 '20 at 16:00
  • Thanks for your reply. I am even getting this error in the mentioned stackblitz example. Please help me if I am making any mistakes – Solomon Raja Dec 31 '20 at 16:23
  • @SolomonRaja Sorry, but I'm not seeing any issues across multiple browsers when running the default stackblitz. All I can think is trying to define `mySelect` as a MatSelect: `@ViewChild('mySelect') mySelect: MatSelect;` – Z. Bagley Dec 31 '20 at 16:30
12

Another approach, so as not to so tightly couple the material component to your typescript code would be to handle this all on the HTML side.

<mat-form-field>
  <mat-select #mySelect placeholder="Favorite food">
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{ food.viewValue }}
    </mat-option>
  </mat-select>
</mat-form-field>
<br/>
<button (click)="mySelect.toggle()">click</button>

I used toggle() on the "selected" answer to both open or close the panel, although you can substitute open() or close() calls depending on your needs.

The key piece seems to be that template variable (#mySelect) that I learned thanks to the answer that @zbagley provided. I just kept tinkering to make it work without the tight binding of a @ViewChild.

Cheers, Dan

Al Dass
  • 831
  • 15
  • 23
djmarquette
  • 712
  • 8
  • 17
0

In the .html file you need to add the anchor to the mat-select element:

<mat-select #dropdownAnchor></mat-select>

And in the .ts file add this:

@ViewChild('dropdownAnchor', {static: false}) dropdownAnchor: MatSelect;

openDropdown(): void {
  this.dropdownAnchor.open();
}
Liraz Shaka Amir
  • 587
  • 9
  • 26
-1

Using Angular 13 and Angular Material 13, I had to click the "trigger" element for the select.

this.mySelect.trigger.nativeElement.click();

(Same configuration below as other answers)

In component:

@ViewChild("mySelect") mySelect;

In template:

<mat-select #mySelect ...
Sam Berry
  • 7,394
  • 6
  • 40
  • 58
  • It will work, however, this is not the angular way of doing things. I've added an answer on how to properly achieve this functionality. – Liraz Shaka Amir Dec 06 '22 at 10:56