views:

33

answers:

1

My GWT app uses a DockLayoutPanel for primary layout and the page itself does not scroll. I have a PopupPanel with a MenuBar and sometimes when a MenuItem is selected the sub menu bar goes off the bottom of the screen abruptly forcing a new scroll bar into the browser and messing up the layout.

How do I get the menu popup to behave nicely and reposition itself upward when the default positioning would put it out of the browser viewport (the way that PopupPanel.showRelativeTo(uiTarget) positioning works)?

In looking at the MenuBar source, it looks like all the layout is done in private methods, so I can't fix it in subclass, and I don't see any events I can listen to that would allow me to do the repositioning myself.

+2  A: 

Take a look at http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/6185225fec64c091/4954d91d1461c71f?lnk=gst&q=context+menu#4954d91d1461c71f.

We've been using this strategy quite successfully for a while now.

Update: There is a bit more to be done. Specifically:

  • Create a reposition() method, which:

    • Determines the max width of all the menu items
    • Checks the left edge of the menu + the max width; if greater than the Window's width, use "DOM.setStyleAttribute(elem, "left", left + "px");" to move the menu
    • Get the height of the menu; if top of the menu + height of the menu > Window's height, use "DOM.setStyleAttribute(elem, "top", top + "px");" to move it up.
  • In the onAttach() method, use a deferred command to invoke the reposition() method.

jgindin
The code posted in that thread is about right-click context menus in GWT 1.1. The only reference to menu positioning is this salient comment at the bottom of the code: "// TODO : if we're close to the bottom of the window, then offset the Y by the height of the to-be-drawn menu"
Mocky
Yes, sorry, I didn't look closely enough. Our code extends the ideas in that post. I've edited my answer above to show the approach we take.
jgindin
It does work to use reposition from a deferred command in the onAttach() method. However, the reposition takes place after the menu has been rendered and forced a relayout of the page around the new scrollbar. After the deferred command fixes it, another full page relayout occurs back to the way it was. I need a way to position the popup after it is attached but before it is set visible.
Mocky
I haven't found a way to get sizes until after it's attached. You might be able to have a style on the menu such that it is not visible at first, do the calculations, then change the visibility. (Never tried this, so YMMV.)
jgindin