1

I am using the jQuery UI Menu as a context menu, so when a user clicks on a cell in a table, it brings it up with relevant options. The problem is, it wasn't really designed to be used like this, so it doesn't hide when the user clicks outside of the menu.

I tried using the blur method:

$("#menu").menu({
    blur: function( event, ui ) {
        $("#menu").css('top', '-1000px');
        $("#menu").css('left', '-1000px');
    }
});

For some reason though, the menu hides even if you scroll onto one of the options in the menu.

Is there a simple solution for this?

Edit: To pull up the menu I use:

$("table.adminScheduleViewer tr td:nth-child(4), table.adminScheduleViewer tr td:nth-child(5), table.adminScheduleViewer tr td:nth-child(6), table.adminScheduleViewer tr td:nth-child(7), table.adminScheduleViewer tr td:nth-child(8), table.adminScheduleViewer tr td:nth-child(9), table.adminScheduleViewer tr td:nth-child(10)").click(function(event){
    $("#menu").css('top', event.pageY);
    $("#menu").css('left', event.pageX);
});

That always seems to get called first if I try to use a $('body').click() to hide it. Can you change the order jQuery handles clicks?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Leah Sapan
  • 3,621
  • 7
  • 33
  • 57

3 Answers3

3

how about something like:

           $('body').not($('#menu').find('*'))
             .bind('click',function(){
                $("#menu").css('top', '-1000px');
                $("#menu").css('left', '-1000px');
             });

Lets handle clicks on the body, and if the click happens NOT anywhere on the menu, do your hiding.

james emanon
  • 11,185
  • 11
  • 56
  • 97
  • correct. I am currently using an older version of jQuery so my mind is on that availability set.. so if you have the latest jQuery, use .on - thanks scott. – james emanon Feb 27 '13 at 20:28
  • As I said to @ScottSelby, I had come up with a similar solution to this but it doesn't work. Because I use $("td").click() to change the top and left positions to on screen, it seems that the td's click gets called first, and then the body one just hides it immediately. – Leah Sapan Feb 27 '13 at 21:47
3
 $('body:not(#menu)').click(function(){
     $("#menu").css({ 'top' : '-1000px', 'left' : '-1000px' });
 });

I think this way is a little sexier

Scott Selby
  • 9,420
  • 12
  • 57
  • 96
  • I had come up with a similar solution to this but it doesn't work. Because I use $("td").click() to change the top and left positions to on screen, it seems that the td's click gets called first, and then the body:not one just hides it immediately. – Leah Sapan Feb 27 '13 at 21:46
  • I don't know why I didn't think of using event.stopPropagation(). Nevermind, thanks! – Leah Sapan Feb 27 '13 at 21:57
  • Does this add an event listener to every child of BODY that is not the menu? I don't find that sexy, just promiscuous :p – Jure Špik May 05 '15 at 17:06
2

I'm using this to hide my jquery-ui menu when the user clicks outside of the menu.

$('body:not(#menu)')
.off('click')
.on( 'click', function() {
    $('body:not(#menu)')
    .off('click');
    $('#menu')
    .hide();
});

Similar to the above answer but hides the menu elements instead of moving them out of the viewport. Also disables the click handle after it is invoked once to leave other click functionality in place.

wolfstevent
  • 703
  • 8
  • 13