Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change absolute position of mat-menu in angular 4 material using x and y co-ordinates?

I have following menu in angular 4

<button mat-button [matMenuTriggerFor]="menu" style="display:none;">Menu</button>
    <mat-menu #menu="matMenu">
        <button mat-menu-item *ngFor="let item of items" (click)="select(item)">
            {{ item }}
        </button>
    </mat-menu>

I am opening the menu when user selects text on screen using matMenuTrigger.openMenu();

but I want to open menu wherever user selects text. I have X and Y coordinates of user selection but how can I change position of menu?

I have tried giving Id to mat-menu and changing it's position using

element.style.position = 'absolute'
element.style.left = screenX + 'px'
element.style.top = screenY + 'px'

but it's not changing position of menu.

EDIT: I have changed position of menu by

this.matMenuTrigger.openMenu();
var element = document.getElementsByClassName('cdk-overlay-pane');
menu.style.position = "absolute";
menu.style.left = evt.pageX + 5 + 'px';
menu.style.top = evt.pageY + 5 + 'px';

where evt is mouseup event which gives co-ordinates(X,Y) of user text selection.

But, when I scroll the page , opened menu again goes back to it's original position. How can I keep menu to it's changed position on scroll??

like image 255
AjinkyaBhagwat Avatar asked Nov 28 '17 09:11

AjinkyaBhagwat


1 Answers

I have implemented opening mat-menu where ever user selectes text.

I have added hidden button which on click opens menu. On user text selection, I have changed style="display:none;" of that button to style="display:'';" and after showing that button, I have changed position of that button to where user has selected the text by x and y co-ordinates and then opened menu programatically by this.menuTrigger.openMenu();

DEMO

menu-example.ts

export class MenuIconsExample {
@ViewChild(MatMenuTrigger)
    private menuTrigger: MatMenuTrigger;

  addTextToOpns: Array<String> = ["option 1", "option 2", "option 3"];
  selectedOption: string = "no Option selected";
  onTextSelection(event: any):void{
    if(window.getSelection && window.getSelection().toString()){
      var menu = document.getElementById('menuBtn');
      menu.style.display = '';
      menu.style.position = 'absolute';
      menu.style.left = event.pageX + 5 + 'px';
      menu.style.top = event.pageY + 5 + 'px';

      this.menuTrigger.openMenu();  
    }

  }

  onMenuClosed():void {
    var menu = document.getElementById('menuBtn');
        if (menu) {
            menu.style.display = 'none';            
        }
  }

  addTextTo(selectedOpn): void {
    this.selectedOption = selectedOpn + ' selected';
  }

}

menu-example.html

<div (mouseup)="onTextSelection($event)">
  <button mat-button [matMenuTriggerFor]="menu" id="menuBtn" style="display:none;">Menu</button>
    <mat-menu #menu="matMenu" (close)="onMenuClosed()">
        <button class="menuOpnBtn" mat-menu-item *ngFor="let opn of addTextToOpns" (click)="addTextTo(opn)">
            {{ opn }}
        </button>
    </mat-menu>
  <p>
    text for selection
  </p>
</div>
<br/>
<br/>


<div><span>selected option : </span> <span>{{selectedOption}}</span></div>
like image 116
AjinkyaBhagwat Avatar answered Oct 30 '22 12:10

AjinkyaBhagwat