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 {{i}}
  </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 {{item.content}}</button>
    <button mat-menu-item>Fixed value</button>
  </ng-template>
</mat-menu>