Primeng: Popup menu positioning

Created on 11 Oct 2016  路  16Comments  路  Source: primefaces/primeng

I'm trying to add a popup menu in one of my projects, but the positioning of the menu is way off. I took a look at what was going on in the code, and it seemed like something strange was happening in the call to domHandler.absolutePosition() from menu.show(). It was calculating the correct offsets from the parent element, but, rather than applying the 'top' and 'left' properties relative to the browser window, it applied them relative to the parent element, so my menu was offscreen way to the right of my toggle button, instead of directly beneath it as desired.

When I changed the position attribute from absolute to fixed for .ui-menu-dynamic selector, it positioned the menu correctly, but never set the display attribute back to 'block' after hiding the menu in domHandler.getHiddenElementDimensions(). I'm currently setting the visibility back to block in my own code as a workaround, but it would be nice not to have to resort to that.

Didn't have anything too different from the demo page in terms of my template (below), so not sure why it would be behaving differently, but it certainly is.

<span>
    <p-menu #menu popup="popup" [model]="menuItems"></p-menu>
    <i class="fa fa-bars action-list-icon" (click)="menu.toggle($event)"></i>
</span>

Most helpful comment

Find solution here .
Just add appendTo="body" to p-menu and it will work.

All 16 comments

I think this is a valid point. I tried wrapping the parent div to position: relative to force the absolute position to be relative to parent but didn't work

I had to extend TieredMenu and TieredMenuSub with my own classes and switch to using domHandler.relativePosition() instead of domHandler.absolutePosition(), along with some custom CSS margins for .ui-tieredmenu, to get this to work. Right now, tiered menu positioning is totally broken whenever the component is nested within something like a Dialog. As already pointed out, this seems to be because the positioning is done relative to the parent component instead of the body.

I'm also experiencing this issue. In my case when I attach a menu through a template to the data table component it shows up far away from the expected position.

I have the same problem, my menu was offscreen way to the right of my toggle button.

Find solution here .
Just add appendTo="body" to p-menu and it will work.

If appendTo="body" works, this needs to be added to the docs and the TSD.

It did not work for me

I can't replicate with 2.0.5, feel free to create a new issue ticket with plunkr.

I was experiencing this problem when the menu was within a positioned element. The menu is positioned with position: absolute so if it is within a positioned element (not static) such as a position: relative element, it will be positioned relative to that element instead of the body. Adding appendTo="body" to the p-menu element did work for me.

Thanks @ajshapiro that fixed it for me too

I am having this problem in react the menu is showin up way to the right and too low. i cannot use the appendTo="body" with react... any ideas how to fix this with react.

You probably want to post this to the primereact issue tracker. This is the primeng issue tracker, so it's highly unlikely you'll find the answer here.

I am having this problem in react the menu is showin up way to the right and too low. i cannot use the appendTo="body" with react... any ideas how to fix this with react.

@lucas-wade primereact's Menu has an appendTo prop that accepts a DOMElement. You can pass document.body, for example. FWIW, I'm experiencing a similar issue with primereact and that did not resolve my issue (the issue also seems to be with the absolutePosition() function).

the solution is appendTo = "body" as they indicate in angular 9 for example my dashboard have different div and library css and function

example

<body>
  <div class="wrapper">
   <!--Handle of Dashboard-->
    <div class="content-wrapper">
        <div class="container-fluid">
            <div>
              <router-outlet></router-outlet>----> it  handled different pages
            </div>
        </div>
    </div>
   <!--Handle of Dashboard-->
  </div>
</body>

The idea of using appendTo="body" works visually until you try to scroll. Now, the menu is not 'attached' to a particular element and the content scrolls 'under' the menu resulting in undesired effects. It would be better to stop scrolling from happening when appendTo body is used. I would simply use this option all the time on that basis.

The idea of using appendTo="body" works visually until you try to scroll. Now, the menu is not 'attached' to a particular element and the content scrolls 'under' the menu resulting in undesired effects. It would be better to stop scrolling from happening when appendTo body is used. I would simply use this option all the time on that basis.

Can you please suggest a solution where in my case i want to scroll when appendTo='body' is used

Was this page helpful?
0 / 5 - 0 ratings

Related issues

miresk picture miresk  路  3Comments

Faigjaz picture Faigjaz  路  3Comments

jisqaqov picture jisqaqov  路  3Comments

mitosandov picture mitosandov  路  3Comments

papiroca-tm picture papiroca-tm  路  3Comments