Angular: Build your own Context Menu
Tags: angular, contextmenu, table, beginners
Published: 2022-05-17 16:39:04

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b93m5aev5p9mmipi4noj.PNG)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnfrbriw9qgxuuixg8qh.PNG)
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>
```
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;
  }
```

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' }; 
  }
```
then finally on td of your table you need to invoke detectRightMouseClick function like below.

```
<td (mouseup)="detectRightMouseClick($event,item)">{{item.name}}</td>
```
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;">
```
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](https://youtu.be/ZIFCZHT-uo8)

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