Search code examples
angularangular-material

Open Mat-Select Drop down in Angular when focus comes on Mat-Select


I want to open Mat-Select Drop down when I press Tab key if coming from previous field or Shift + Tab if coming from the next field after Drop Down. How to achieve this ?

This is my Account Page

Now, as in the image - Account Type is my Mat-Select Drop Down. So if I press tab key from Account Name focus will shift to Account Type but I want to open the Drop Down. Like Wise if I Press Shift + Tab key combination from Company I want to open Drop - Down of Account Type.

I went through all the Angular Material Select API's but not able to achieve my goal.

This is my Account Type Drop Down Code -

<div class="row">
    <div class="col-lg-4 col-md-4 col-sm-12 col-label-line-height">
        <mat-label>Account Type </mat-label>
    </div>
    <div class="col-lg-8 col-md-8 col-sm-12">
        <mat-form-field>
            <mat-select formControlName="AccountTypeCode" [disabled]="this.DataService.LeaseCount" [(ngModel)]="AccountModel.AccountTypeCode">
                <mat-option *ngFor="let AccountType of this.AccountTypeList" [value]="AccountType.Code">
                {{ AccountType.Name }}
                </mat-option>
            </mat-select>
            <mat-error *ngIf="hasError('AccountTypeCode', 'required')">Account Type is required</mat-error>
            <mat-error *ngIf="hasError('CompanyCode', 'min')">Account Type is required</mat-error>
        </mat-form-field>
    </div>
</div>

So far, I have tried -

<div class="row">
    <div class="col-lg-4 col-md-4 col-sm-12 col-label-line-height">
        <mat-label>Account Type </mat-label>
    </div>
    <div class="col-lg-8 col-md-8 col-sm-12">
        <mat-form-field>
            <mat-select (open)="matSelectOpen($event)" formControlName="AccountTypeCode" [disabled]="this.DataService.LeaseCount" [(ngModel)]="AccountModel.AccountTypeCode">
                <mat-option *ngFor="let AccountType of this.AccountTypeList" [value]="AccountType.Code">
                {{ AccountType.Name }}
                </mat-option>
            </mat-select>
            <mat-error *ngIf="hasError('AccountTypeCode', 'required')">Account Type is required</mat-error>
            <mat-error *ngIf="hasError('CompanyCode', 'min')">Account Type is required</mat-error>
        </mat-form-field>
    </div>
</div>

In .ts File -

matSelectOpen(e) {
    Console.log(e); //just to check whether function is called or not
}

I have also tried with event as follows : -

(trigger)="matSelectOpen($event)"

(panelOpen)="matSelectOpen($event)"

Any help would be appreciated.


Solution

  • try this

     <mat-select #accType (focus)="accType.open()">
    

    Which means give your select a template ref. Then on focus open it.

    Edit :

    It's been a while since I answer this and didn't notice the comment that @KrunalShah made.

    If you want a general solution that can be applied to multiple selects, you are right it's not feasible to give templateRef to each select element. Here you can do is to create an angular directive to serve this purpose:

    @Directive({
      selector: "mat-select[appOpenOnFocus]"
    })
    export class OpenOnFocusDirective {
      constructor(select: MatSelect) {
        const nativeEl = select._elementRef.nativeElement;
        nativeEl.addEventListener("focus", () => {
          select.open();
        });
      }
    }
    

    Then use it on the mat-select like this : <mat-select appOpenOnFocus>

    StackBlitz