Right click context menu with Angular


Create a right click context menu inside a dynamic list or table

GitHub demo

We need to link each element of a list or table to a right-click context mat-menu.

The list elements and their menu are generated only at runtime. To generate dynamically the menu we create an hidden div with the coordinates of the mouse.

Component code

Here is important to notice that we define the position of the menu using the coordinates of the mouse.

// we create an object that contains coordinates 
  menuTopLeftPosition =  {x: '0', y: '0'} 
 
  // reference to the MatMenuTrigger in the DOM 
  @ViewChild(MatMenuTrigger, {static: true}) matMenuTrigger: MatMenuTrigger; 
 
  /** 
   * Method called when the user click with the right button 
   * @param event MouseEvent, it contains the coordinates 
   * @param item Our data contained in the row of the table 
   */ 
  onRightClick(event: MouseEvent, item) { 
      // preventDefault avoids to show the visualization of the right-click menu of the browser 
      event.preventDefault(); 
 
      // we record the mouse position in our object 
      this.menuTopLeftPosition.x = event.clientX + 'px'; 
      this.menuTopLeftPosition.y = event.clientY + 'px'; 
 
      // we open the menu 
      // we pass to the menu the information about our object 
      this.matMenuTrigger.menuData = {item: item} 
 
      // we open the menu 
      this.matMenuTrigger.openMenu(); 
 
  } 

html code

<!-- we generate a number of items dinamically--> 
<div *ngFor="let i of getExamples(20)"> 
  <!-- when the user clicks on the div the onRightClick event is called, we pass a simple object--> 
  <div (contextmenu)="onRightClick($event, {content: 'Item ' + i})" 
  style="padding-bottom: 20px;"> 
    Item {% raw %}{{i}}{% endraw %} 
  </div> 
</div> 
 
<!-- an hidden div is created to set the position of appearance of the menu--> 
<div style="visibility: hidden; position: fixed;" 
[style.left]="menuTopLeftPosition.x" 
[style.top]="menuTopLeftPosition.y" 
[matMenuTriggerFor]="rightMenu"></div> 
 
<!-- standard material menu --> 
<mat-menu #rightMenu="matMenu"> 
  <ng-template matMenuContent let-item="item"> 
    <button mat-menu-item>Clicked {% raw %}{{item.content}}{% endraw %}</button> 
    <button mat-menu-item>Fixed value</button> 
  </ng-template> 
</mat-menu> 

Here you can play the StackBlitz project



Super fast WebApp built by Marco using SpringBoot 3 and Java 17 hosted in Switzerland