Sivakumar Tadisetti
Sivakumar Tadisetti

Reputation: 5051

Focus is being removed from the element when we select any item from the angular material mat menu

I have a textbox and material menu. When we select any item from the material menu, I am setting focus on textbox. But when material menu is closed, that focus on textbox is also being removed. How to prevent that action?

I tried event.stopPropagation() on menu item click, but didn't work. Any suggestions?

I want that focus on textbox should present even after material menu is closed.

<input type="text" #someTextInput (focusout)="focusedOut()">

<button mat-icon-button [matMenuTriggerFor]="menu"> 
  <!-- pass local reference of mat-menu to be opened on this click -->
  <mat-icon>more_vert</mat-icon>
</button>

<mat-menu #menu="matMenu">
  <!-- give local reference and tell this is manu by assigning 'matMenu' -->
  <button mat-menu-item>
    <mat-icon>dialpad</mat-icon>
    <span>Redial</span>
  </button>
  <button mat-menu-item disabled>
    <mat-icon>voicemail</mat-icon>
    <span>Check voicemail</span>
  </button>
  <button mat-menu-item (click)="focusElement()">
    <mat-icon>notifications_off</mat-icon>
    <span>Disable alerts</span>
  </button>
</mat-menu>

ts file

@Component({
  selector: 'menu-icons-example',
  templateUrl: 'menu-icons-example.html',
  styleUrls: ['menu-icons-example.css'],
})
export class MenuIconsExample implements AfterViewInit {

  @ViewChild('someTextInput') textInput: ElementRef;

  public ngAfterViewInit() {
    this.textInput.nativeElement.focus();
  }

  focusElement() {
    this.textInput.nativeElement.focus();
    console.log('focused...');
  }

  focusedOut() {
    console.log('focused out called...');
  }
}

Please find the example Stackblitz

Upvotes: 0

Views: 4626

Answers (2)

ylmz
ylmz

Reputation: 46

I think when you click a menu item; angular calls first click method and later on, it calls close method of menu which causes to lose focus of input. Changing the focusElement method like this will do the trick:

focusElement() {
const nativeEl = this.textInput.nativeElement;

setTimeout(function () {
  nativeEl.focus();
  console.log('focused...');
}, 1);  

}

Upvotes: 0

Eldar
Eldar

Reputation: 10790

Well there is a bug (or unwanted behavior) with the version of angular-material you are using. After menu closed event something causes input to lost focus again. You can observe it with removing setTimeout part on the example. There is a work around with using setTimeout like below :

In your template add a closed event handler:

<mat-menu #menu="matMenu" (closed)="onMenuClosed()"> 

Then in your component class :

 onMenuClosed() {
    setTimeout(() => {
      this.focusElement();
    });
  }

Here is the Stackblitz example

Please note that later versions of angular-material menu has option named restoreFocus which is automatically restores the focus into previous target.

Upvotes: 2

Related Questions