views:

117

answers:

1

I'm trying to take advantage of jQuery-UI Position's ability to handle collisions when I popup a little menu if a user clicks a button. Essentially, if they've scrolled somewhere on the screen, and the menu will fit above the button but not below, it automatically "flips" the menu up.

This seems to be really easy and super elegant:

$('#bmenu').click(function(){
  $('#button_submenu').position({
   'my':'left top',
   'at':'center bottom',
   'of':$('#bmenu'),
   'collision':'fit flip'
 }).toggle();
});

$('#bmenu').button({ //prettify the button
  icons: {
      primary: 'ui-icon-triangle-1-s'
  },
  text: false
});

They click the menu, it positions the submenu, possibly flipping or whatever, then toggles it into view.

What I've found is one key issue: If you scroll down on the page, then click the menu, the menu appears offset in some way. And the weird thing is, if you don't use toggle (or show/hide), position() works perfectly.

Here's some markup:

<style type="text/css" media="screen">
/*making the button less space-hungry*/
.ui-button-icon-only { font-size:46%; }

/*menu*/
#button_submenu {
    display:block;
    position:absolute;
    list-style: none;
    margin:0;
    z-index:9999;
}
/*menu items have a border*/
#button_submenu li {
    border-top: 1px solid #CCC;}
#button_submenu li:hover { background-color:white; }
/*except the first one*/
#button_submenu li:first-child { border-top: none;}
/*style the actual items*/
#button_submenu li a {
    white-space:nowrap;
    text-align:left;
    padding: 4px;
}
</style>
<div style="height:100px"></div>
<button id="bmenu">Menu</button>
<ul class="ui-state-default ui-corner-all" id="button_submenu">
    <li><a href="#">Show Site Navigation</a></li>
    <li><a href="#">Add Boxes:</a></li>
    <li><a href="#">Add Boxes:</a></li>
    <li><a href="#">Add Boxes:</a></li>
    <li><a href="#">Add Boxes:</a></li>
    <li><a href="#">Add Boxes:</a></li>
    <li><a href="#">Add Boxes:</a></li>    
</ul>
<div style="height:800px"></div>

And here is a jsfiddle demonstrating the issue. What I've noticed is that if you make the #button_submenu display:block and get rid of the toggle(), this all works correctly. Note also that my demo doesn't have collision stuff turned on because I suspect that's just a red-herring - the basic positioning isn't working anyways, maybe fix one, fix the other?


EDIT for tldr version: click here, scroll down, click button, why crazy menu position?

+1  A: 

The position utility is intended to be called once, not refreshed every click, so it should look like this:

$('#button_submenu').position({
  'my':'left top', 
  'at':'center bottom', 
  'of': '#bmenu',
  'collision':'none'
});
$('#bmenu').click(function(){
  $('#button_submenu').toggle();
});

Here's the updated/random-offset-free version :)

Nick Craver
fair enough, that will solve my problem - I am curious still what the interaction between toggle and position is that causes things to go oddly, but OK!
Ryley
I guess position utility just isn't going to do what I want - generally, the "point" of it for me would be using the collision stuff in the case where they've scrolled around a bit, to make sure the popup is visible in the viewport.
Ryley