2

enter image description here

<button mat-button id="categories-button" [mat-menu-trigger-for]="categoryList">
  <span>categories</span>
  <mat-icon id="drop-arrow">arrow_drop_down</mat-icon>
</button>
<mat-menu #categoryList>
  <mat-form-field appearance="standard" id="category-search-wrapper">
    <input (click)="$event.stopPropagation()" matInput id="category-search">
  </mat-form-field>

  <button mat-menu-item>Settings</button>
  <button mat-menu-item>Help</button>
</mat-menu>

I want category-search input to be focused, when Menu is opened, the problem is it doesn't seem to be ready yet, when menuOpened event is emitted. How can I focus input element when Menu is opened?

Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Gieted
  • 835
  • 6
  • 21
  • Since autofocus doesnt work, try out this answer: https://stackoverflow.com/questions/51510936/how-to-set-autofocus-on-a-matinput-element-on-click-event-in-angular-6 – Mario Petrovic May 15 '20 at 12:07
  • The problem is ngOnInit will be called only once on page load and not on each menu open – Gieted May 15 '20 at 12:17
  • But isn't the `mat-menu` not in DOM when its closed? If so, it should fire cause that directive will be initiated every time input is inserted into DOM, that is if. – Mario Petrovic May 15 '20 at 12:30
  • I'm not familiar enough with Angular to provide an example, but all frontend frameworks have the concept of `tick()` / `nextTick(` that runs your code next time the DOM updates. It's a solve for this exact problem. – Chris Hayes Jun 12 '22 at 15:59

2 Answers2

3

you can use ViewChild as follow

<button mat-button
  (menuOpened)="menuOpened()"
  [matMenuTriggerFor]="menu">Menu
</button>

<mat-menu #menu="matMenu">
  <mat-form-field appearance="standard" id="category-search-wrapper">

    <input
      #search
      (click)="$event.stopPropagation()" matInput>

  </mat-form-field>

  <button mat-menu-item>Item 1</button>
  <button mat-menu-item>Item 2</button>
</mat-menu>


export class AppComponent  {

  @ViewChild('search', {static: false})
  inputElement: ElementRef;

  menuOpened() {
    setTimeout(() => {
      this.inputElement.nativeElement.focus();
    }, 0);
  }
}

example

Radik
  • 2,715
  • 1
  • 19
  • 24
  • Works great! also if the input is outside of the menu. – bfredo123 Oct 03 '20 at 09:46
  • This works great for me too. However there is one small issue, if I type a letter in text box and if there is any mat-menu item (we have used button) starts with that letter, then the focus changes. In above StackBliz example if I type "i" then focus changes as mat-menu contains Item1, Item2. Any solution for this issue? – Avi May 27 '21 at 15:00
2
<button
  id="categories-button"
  [mat-menu-trigger-for]="categoryList"
  (menuOpened)="categorySearch.focus()"
>
  <span>categories</span>
  <mat-icon id="drop-arrow">arrow_drop_down</mat-icon>
</button>
<mat-menu #categoryList>
  <mat-form-field #categorySearch appearance="standard" id="category-search-wrapper">
    <input matInput (click)="$event.stopPropagation()" />
  </mat-form-field>

  <button mat-menu-item>Settings</button>
  <button mat-menu-item>Help</button>
</mat-menu>
  1. Add (menuOpened)="this.categoryListOpened()" to the button, that opens the Menu
  2. Declare categoryListOpened method in your component's class like above
Raphaël Balet
  • 6,334
  • 6
  • 41
  • 78
Gieted
  • 835
  • 6
  • 21