DEV Community

Chetan
Chetan

Posted on

Angular: Build your own Context Menu

Quite an amazing topic and much needed in large scale application.
Every developer has somehow used html Tables to display records and might have used action buttons like Edit, View or download and list goes on and everyone must have felt that these buttons occupy so much space.
old way
So Here comes a solution Context Menu.
Instead of button you can have a context menu and can have as many as actions to perform without disturbing UI design.

New way
With Context Menu now we have more space to show other information in grid and for user also easy to get action item on right click.
Following are the steps to achieve above Context-Menu

  • context menu html a simple div with css to be visible where user will click right click div will be visible as popup. Here You can have all your action items. Here rightPanelStyle is dynamic style which will be added on right click event.
<div id="contextmenu" class="contextmenu" [ngStyle]="rightPanelStyle" 
    (clickOutside)="closeContextMenu()" (mouseleave)="closeContextMenu()">
    <ul class="menu">
        <li (click)="edit()"><a><i class="fa fa-eye"></i> View</a></li>
        <li class="activem"><a><i class="fa fa-pencil-square-o"></i> Edit</a></li>
        <li><a><i class="fa fa-download"></i> Download</a></li>
        <li (click)="delete()"><a><i class="fa fa-trash"></i> Delete</a></li>
    </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

some css to make it look like context menu.

.menu {
    display: flex;
    flex-direction: column;
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 10px 20px rgb(64 64 64 / 5%);
    padding: 10px 0;
  }
  .menu > li > a {
    cursor: pointer;
    font: inherit;
    border: 0;
    padding: 10px 30px 10px 15px;
    width: 100%;
    display: flex;
    align-items: center;
    position: relative;
    text-decoration: unset;
    color: #000;
    font-weight: 500;
    transition: 0.5s linear;
    -webkit-transition: 0.5s linear;
    -moz-transition: 0.5s linear;
    -ms-transition: 0.5s linear;
    -o-transition: 0.5s linear;
  }
  .menu > li > a:hover {
    background:#b1b3b6;
    color: #4b00ff;
  }
  .menu > li > a > i {
    padding-right: 10px;
  }
  .menu > li.trash > a:hover { 
    background:#b1b3b6;
  }
Enter fullscreen mode Exit fullscreen mode

code you need in .ts file

rightPanelStyle: any = {};
detectRightMouseClick($event,user) { 
    if ($event.which === 3) { 
      this.rightPanelStyle = { 'display': 'block', 'position': 'absolute', 'left.px': $event.clientX, 'top.px': $event.clientY };
      this.currentRecord = user;
      return false;
    } 
    return true;
  }
  closeContextMenu() { 
     this.rightPanelStyle = { 'display': 'none' }; 
  }
Enter fullscreen mode Exit fullscreen mode

then finally on td of your table you need to invoke detectRightMouseClick function like below.

<td (mouseup)="detectRightMouseClick($event,item)">{{item.name}}</td>
Enter fullscreen mode Exit fullscreen mode

here item is ngFor instance to pass it on to function and with $event you get JavaScript event that will get you mouse click position form top and left.

One more thing you might want to disable browser right click.
otherwise there will be two context menu. you can add this to parent div of table.

<div oncontextmenu="return false;">
Enter fullscreen mode Exit fullscreen mode

and you need to call closeContextMenu in ngOnInit to close context menu on load.

Hope you might have learned few new things.
in case you need to see while code from scratch and thought process Please watch youtube video
youTube Link

and do drop comments to here from me with such amazing life saving post....

Top comments (1)

Collapse
 
avinash1994 profile image
avinash

I hope this message finds you well. My name is Aviansh, and I recently came across your YouTube videos, which I found incredibly informative and helpful. I'm particularly interested in [looking for trainner].

I'm reaching out because I'd like to learn more and possibly engage with your content further. However, I couldn't find any contact information to reach you directly. Could you please provide guidance on how I can get in touch with you?