Keep right click context menu on the screen

1k Views Asked by At

I have created an typescript component for my Context Menu and everything is working great except when the Context menu is activated near the edge of the screen it will go past the edge of the screen and some items will be inaccessible.

This is the HTML structure of my Context Menu

<div id="contextMenu">
  <div
    class="menu-link"
    *ngFor="let menuItem of contextMenuItems; index as i"
    (click)="onContextMenuClick($event, menuItem.menuEvent)">
    <div *ngIf="menuItem.menuText !== 'divider'">{{ menuItem.menuText }}</div>
    <hr *ngIf="menuItem.menuText == 'divider'" />
  </div>
</div>

The menu items are dynamically added based on the "context"

right click activates this code

displayContextMenu(event) {
this.myContextMenuService.buildMenu();
this.rightClickMenuPositionX = event.clientX;
this.rightClickMenuPositionY = event.clientY;
}

I've tried several CSS things but nothing has kept the entire menu on the screen no matter where you activate it from.

3

There are 3 best solutions below

1
Funn_Bobby On

Taking too long to get an answer from the community. This is how I've decided to solve this problem...hopefully it will help someone else.

The below is triggered by a [ngStyle] call on the "contextMenu" [ngStyle]="getYourClickMenuStyle()"

const rightClickMenuPositionX = event.clientX;
const rightClickMenuPositionY = event.clientY;
const cMenu = <HTMLInputElement>document.getElementById('contextMenu');
const menuWidth = cMenu.offsetWidth + 30;
const menuHeight = cMenu.offsetHeight + 30;
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
let menuStyleLeft = '';
let menuStyleTop = '';

if((windowWidth - rightClickMenuPositionX)<menuWidth){
menuStyleLeft = (windowWidth - menuWidth).toString() + "px";
} else {
  menuStyleLeft = rightClickMenuPositionX.toString() + "px";
}
if ( (windowHeight - rightClickMenuPositionY) < menuHeight ) {
  menuStyleTop = (windowHeight - menuHeight).toString() + "px";
} else {
  menuStyleTop = rightClickMenuPositionY.toString() + "px";
}
if(menuStyleLeft !== ''){
  return {
    position: 'fixed',
    left: menuStyleLeft,
    top: menuStyleTop
  }
}
0
Moufeed Juboqji On
displayContextMenu(event) {
  this.myContextMenuService.buildMenu();
  // get your contextMenu width and height
  const contextMenu = document.getElementById('contextMenu');
  const contextMenuWidth = contextMenu.offsetWidth;
  const contextMenuHeight = contextMenu.offsetHeight;

  const xPos = event.clientX + contextMenuWidth > window.innerWidth ? window.innerWidth - contextMenuWidth : event.clientX;
  const yPos = event.clientY + contextMenuHeight > window.innerHeight ? window.innerHeight - contextMenuHeight : event.clientY;

  this.rightClickMenuPositionX = xPos;
  this.rightClickMenuPositionY = yPos;
}
0
Nathan On

Why make this more difficult than it already is? Use Angular's Cdk, it takes care of this out of the box. Non need to re-invent the wheel