How do you check if jquery modal dialog has lost focus?
I want to close the dialog when you click outside of the dialog, but I'm not sure how you are testing this in jquery / plain javascript.
Some have suggested using blur event, but that doesn't seem like jquery's dialog support.
EDIT I have this question too, but I can't seem to get my head around any of the answers currently provided as I can't make my dialogs modal.
I need this so that I can only register key handlers when the dialog is at its most, and unregister as soon as another dialog appears.
Does anyone have a solution - ideally this means the event fires every time some other dialogue comes to the top?
a source to share
Can you make your dialogue modal? If so, then you can (possibly) achieve what you need with events on the modal overlay ...
Completely hacked, untested idea, but it might just work ...
Modal dialogs create events named click.dialog-overlay etc. They are fired when the mouse is called outside of the dialog box, on a modal overlay. Attaching these events and closing the dialog might do what you are trying to do ...
a source to share
Pure jQueryUI no modal dialog.
Example:
http://jsfiddle.net/marcosfromero/x4GXy/
the code:
// Bind the click event to window
$(window).click(function(event) {
if (($(event.target).closest('.ui-dialog')).length>0) {
// if clicked on a dialog, do nothing
return false;
} else {
// if clicked outside the dialog, close it
// jQuery-UI dialog adds ui-dialog-content class to the dialog element.
// with the following selector, we are sure that any visible dialog is closed.
$('.ui-dialog-content:visible').dialog('close');
}
})
a source to share
The blur event isn't exactly what you're looking for. The blur event occurs on one element. What you are looking for is when the user clicks "outside" a specific group of elements - everything below a specific parent node. ** There is no event for this, so you have to simulate it with events that you have access to.
$('.dialogSelector').dialog({
open: function(e) { // on the open event
// find the dialog element
var dialogEl = $(this).parents('.ui-dialog')[0];
$(document).click(function (e) { // when anywhere in the doc is clicked
var clickedOutside = true; // start searching assuming we clicked outside
$(e.target).parents().andSelf().each(function () { // search parents and self
// if the original dialog selector is the click target or a parent of the target
// we have not clicked outside the box
if (this == dialogEl) {
clickedOutside = false; // found
return false; // stop searching
}
});
if (clickedOutside) {
$('a.ui-dialog-titlebar-close').click(); // close the dialog
// unbind this listener, we're done with it
$(document).unbind('click',arguments.callee);
}
});
}
});
** To be more precise, you are looking for an event when the user clicks outside of a certain visible group of items. An absolutely positioned div can appear "outside" of a group of elements to the user, whereas it is actually a child of one of those elements. It won't work for this, but it should work for your purposes.
Hope it helps. :)
a source to share
Have a look at the jquery tool overlay that can help you make modals. This has helped me in the past.
To check if the click is outside the modal window, you can do something like this:
echo '<div class="mybody">Body of the webpage';
echo '<div class="myoverlay">Body of overlay</div></div>';
JQuery
$(function() {
$('body').click(function(e) {
var inOverlay = false;
$(e.target).parents().each(function(idx,parent) {
if ('mybody' == parent.className) {
inOverlay=true;
}
});
if (!inOverlay) {
alert('outside');
}
});
});
Then you can add keyboard checks inside the modal:
$(".myoverlay").keydown(function(e) {
// your specific keyboard handler
});
a source to share
A solution like @marcosfromero (but more performant) should be used $.contains
to check if an element exists inside another. $.contains
uses a native method document.documentElement.compareDocumentPosition
if it exists, meaning you don't need to turn event.target
into a jQuery object, you don't need to query the DOM for .ui-dialog
, and the underlying logic doesn't even need to traverse the DOM (in modern browsers).
$(document).click(function(event) {
if( !$.contains( dialog.dialog('widget')[0], event.target ) ){
$(':ui-dialog').dialog('close');
}
});
If the target element does not exist with the dialog markup generated by the widgets (obtained by calling the dialog method widget
), the dialog is closed.
a source to share
Create a transparent overlay with CSS {position: fixed; height: 100%; width: 100%; background: transparent; z-index: 100} and use $('.overlay').click(function() {$('ui-dialog').remove();}
. Of course, you need to create <div class="overlay"></div>
at the same time as creating a dialog. And the dialog will need a higher z-index!
a source to share