jQuery UI - Close Dialog When Clicked Outside

JavascriptJqueryJquery UiJquery Ui-Dialog

Javascript Problem Overview


I have a jQuery UI Dialog that gets displayed when specific elements are clicked. I would like to close the dialog if a click occurs anywhere other than on those triggering elements or the dialog itself.

Here's the code for opening the dialog:

$(document).ready(function() {
	var $field_hint = $('<div></div>')
		.dialog({
			autoOpen: false,
			minHeight: 50,
			resizable: false,
			width: 375
		});

	$('.hint').click(function() {
		var $hint = $(this);
		$field_hint.html($hint.html());
		$field_hint.dialog('option', 'position', [162, $hint.offset().top + 25]);
		$field_hint.dialog('option', 'title', $hint.siblings('label').html());
		$field_hint.dialog('open');
	});
	/*$(document).click(function() {
		$field_hint.dialog('close');
	});*/
});

If I uncomment the last part, the dialog never opens. I assume it's because the same click that opens the dialog is closing it again.


Final Working Code
Note: This is using the [jQuery outside events][1] plugin

$(document).ready(function() {
	// dialog element to .hint
	var $field_hint = $('<div></div>')
			.dialog({
				autoOpen: false,
				minHeight: 0,
				resizable: false,
				width: 376
			})
			.bind('clickoutside', function(e) {
				$target = $(e.target);
				if (!$target.filter('.hint').length
						&& !$target.filter('.hintclickicon').length) {
					$field_hint.dialog('close');
				}
			});

	// attach dialog element to .hint elements
	$('.hint').click(function() {
		var $hint = $(this);
		$field_hint.html('<div style="max-height: 300px;">' + $hint.html() + '</div>');
		$field_hint.dialog('option', 'position', [$hint.offset().left - 384, $hint.offset().top + 24 - $(document).scrollTop()]);
		$field_hint.dialog('option', 'title', $hint.siblings('label').html());
		$field_hint.dialog('open');
	});

	// trigger .hint dialog with an anchor tag referencing the form element
	$('.hintclickicon').click(function(e) {
		e.preventDefault();
		$($(this).get(0).hash + ' .hint').trigger('click');
	});
});

[1]: http://benalman.com/projects/jquery-outside-events-plugin/ "jQuery outside events"

Javascript Solutions


Solution 1 - Javascript

Sorry to drag this up after so long but I used the below. Any disadvantages? See the open function...

$("#popup").dialog(
{
    height: 670,
    width: 680,
    modal: true,
    autoOpen: false,
    close: function(event, ui) { $('#wrap').show(); },
    open: function(event, ui) 
    { 
        $('.ui-widget-overlay').bind('click', function()
        { 
            $("#popup").dialog('close'); 
        }); 
    }
});

Solution 2 - Javascript

Forget using another plugin:

Here are 3 methods to close a jquery UI dialog when clicking outside popin:

If the dialog is modal/has background overlay: http://jsfiddle.net/jasonday/6FGqN/

jQuery(document).ready(function() {
    jQuery("#dialog").dialog({
        bgiframe: true,
        autoOpen: false,
        height: 100,
        modal: true,
        open: function(){
            jQuery('.ui-widget-overlay').bind('click',function(){
                jQuery('#dialog').dialog('close');
            })
        }
    });
}); 

If dialog is non-modal Method 1: method 1: http://jsfiddle.net/jasonday/xpkFf/

 // Close Pop-in If the user clicks anywhere else on the page
                     jQuery('body')
                      .bind(
                       'click',
                       function(e){
                        if(
                         jQuery('#dialog').dialog('isOpen')
                         && !jQuery(e.target).is('.ui-dialog, a')
                         && !jQuery(e.target).closest('.ui-dialog').length
                        ){
                         jQuery('#dialog').dialog('close');
                        }
                       }
                      );

Non-Modal dialog Method 2: http://jsfiddle.net/jasonday/eccKr/

  $(function() {
            $( "#dialog" ).dialog({
                autoOpen: false, 
                minHeight: 100,
                width: 342,
                draggable: true,
                resizable: false,
                modal: false,
                closeText: 'Close',
                  open: function() {
                      closedialog = 1;
                      $(document).bind('click', overlayclickclose);
                  },
                  focus: function() {
                      closedialog = 0;
                  },
                  close: function() {
                      $(document).unbind('click');
                  }



        });

         $('#linkID').click(function() {
            $('#dialog').dialog('open');
            closedialog = 0;
        });

         var closedialog;

          function overlayclickclose() {
              if (closedialog) {
                  $('#dialog').dialog('close');
              }

              //set to one because click on dialog box sets to zero
              closedialog = 1;
          }


  });

Solution 3 - Javascript

Check out the jQuery Outside Events plugin

Lets you do:

$field_hint.bind('clickoutside',function(){
    $field_hint.dialog('close');
});

Solution 4 - Javascript

Just add this global script, which closes all the modal dialogs just clicking outsite them.

$(document).ready(function()
{
    $(document.body).on("click", ".ui-widget-overlay", function()
    {
        $.each($(".ui-dialog"), function()
        {
            var $dialog;
            $dialog = $(this).children(".ui-dialog-content");
            if($dialog.dialog("option", "modal"))
            {
                $dialog.dialog("close");
            }
        });
    });;
});

Solution 5 - Javascript

$(".ui-widget-overlay").click (function () {
    $("#dialog-id").dialog( "close" );
});

Fiddle showing the above code in action.

Solution 6 - Javascript

I had to do two parts. First the outside click-handler:

$(document).on('click', function(e){
    if ($(".ui-dialog").length) {
        if (!$(e.target).parents().filter('.ui-dialog').length) {
            $('.ui-dialog-content').dialog('close');
        }
    }
}); 

This calls dialog('close') on the generic ui-dialog-content class, and so will close all dialogs if the click didn't originate in one. It will work with modal dialogs too, since the overlay is not part of the .ui-dialog box.

The problem is:

  1. Most dialogs are created because of clicks outside of a dialog
  2. This handler runs after those clicks have created a dialog and bubbled up to the document, so it immediately closes them.

To fix this, I had to add stopPropagation to those click handlers:

moreLink.on('click', function (e) {
    listBox.dialog();
    e.stopPropagation(); //Don't trigger the outside click handler
});

Solution 7 - Javascript

This question is a bit old, but in case someone wants to close a dialog that is NOT modal when user clicks somewhere, you can use this that I took from the JQuery UI Multiselect plugin. The main advantage is that the click is not "lost" (if user wants to click on a link or a button, the action is done).

$myselector.dialog({
            title: "Dialog that closes when user clicks outside",
            modal:false,
            close: function(){
                        $(document).off('mousedown.mydialog');
                    },
            open: function(event, ui) { 
                    var $dialog = $(this).dialog('widget');
                    $(document).on('mousedown.mydialog', function(e) {
                        // Close when user clicks elsewhere
                        if($dialog.dialog('isOpen') && !$.contains($myselector.dialog('widget')[0], e.target)){
                            $myselector.dialog('close');
                        }            
                    });
                }                    
            });

Solution 8 - Javascript

You can do this without using any additional plug-in

var $dialog= $(document.createElement("div")).appendTo(document.body);
    var dialogOverlay;
    
    $dialog.dialog({
        title: "Your title",
        modal: true,
        resizable: true,
        draggable: false,
        autoOpen: false,
        width: "auto",
        show: "fade",
        hide: "fade",
        open:function(){
            $dialog.dialog('widget').animate({
                width: "+=300", 
                left: "-=150"
            });
            
//get the last overlay in the dom
            $dialogOverlay = $(".ui-widget-overlay").last();
//remove any event handler bound to it.
            $dialogOverlay.unbind();
            $dialogOverlay.click(function(){
//close the dialog whenever the overlay is clicked.
                $dialog.dialog("close");
            });
        }
    });

Here $dialog is the dialog. What we are basically doing is to get the last overlay widget whenever this dialog is opened and binding a click handler to that overlay to close $dialog as anytime the overlay is clicked.

Solution 9 - Javascript

no need for the outside events plugin...

just add an event handler to the .ui-widget-overlay div:

jQuery(document).on('click', 'body > .ui-widget-overlay', function(){
     jQuery("#ui-dialog-selector-goes-here").dialog("close");
     return false;
});

just make sure that whatever selector you used for the jQuery ui dialog, is also called to close it.. i.e. #ui-dialog-selector-goes-here

Solution 10 - Javascript

This doesn't use jQuery UI, but does use jQuery, and may be useful for those who aren't using jQuery UI for whatever reason. Do it like so:

function showDialog(){
  $('#dialog').show();
  $('*').on('click',function(e){
    $('#zoomer').hide();
  });
}

$(document).ready(function(){

  showDialog();    
    
});

So, once I've shown a dialog, I add a click handler that only looks for the first click on anything.

Now, it would be nicer if I could get it to ignore clicks on anything on #dialog and its contents, but when I tried switching $('*') with $(':not("#dialog,#dialog *")'), it still detected #dialog clicks.

Anyway, I was using this purely for a photo lightbox, so it worked okay for that purpose.

Solution 11 - Javascript

The given example(s) use one dialog with id '#dialog', i needed a solution that close any dialog:

$.extend($.ui.dialog.prototype.options, {
    modal: true,
    open: function(object) {
        jQuery('.ui-widget-overlay').bind('click', function() {              
            var id = jQuery(object.target).attr('id');
            jQuery('#'+id).dialog('close');
        })
    }
});

Thanks to my colleague Youri Arkesteijn for the suggestion of using prototype.

Solution 12 - Javascript

This is the only method that worked for me for my NON-MODAL dialog

$(document).mousedown(function(e) {
    var clicked = $(e.target); // get the element clicked
    if (clicked.is('#dlg') || clicked.parents().is('#dlg') || clicked.is('.ui-dialog-titlebar')) {
        return; // click happened within the dialog, do nothing here
    } else { // click was outside the dialog, so close it
        $('#dlg').dialog("close");
    }
});

All credit goes to Axle
https://stackoverflow.com/questions/7919229/click-outside-non-modal-dialog-to-close

Solution 13 - Javascript

For those you are interested I've created a generic plugin that enables to close a dialog when clicking outside of it whether it a modal or non-modal dialog. It supports one or multiple dialogs on the same page.

More information here: http://www.coheractio.com/blog/closing-jquery-ui-dialog-widget-when-clicking-outside

Laurent

Solution 14 - Javascript

I use this solution based in one posted here:

var g_divOpenDialog = null;
function _openDlg(l_d) {
  
  // http://stackoverflow.com/questions/2554779/jquery-ui-close-dialog-when-clicked-outside
  jQuery('body').bind(
   'click',
   function(e){
    if(
      g_divOpenDialog!=null 
      && !jQuery(e.target).is('.ui-dialog, a')
      && !jQuery(e.target).closest('.ui-dialog').length
    ){
      _closeDlg();
    }
   }
  );
  
  setTimeout(function() {
    g_divOpenDialog = l_d;
    g_divOpenDialog.dialog();
  }, 500);
}
function _closeDlg() {
  jQuery('body').unbind('click');
  g_divOpenDialog.dialog('close');
  g_divOpenDialog.dialog('destroy');
  g_divOpenDialog = null;
}

Solution 15 - Javascript

I had same problem while making preview modal on one page. After a lot of googling I found this very useful solution. With event and target it is checking where click happened and depending on it triggers the action or does nothing.

Code Snippet Library site

$('#modal-background').mousedown(function(e) {
var clicked = $(e.target);  
if (clicked.is('#modal-content') || clicked.parents().is('#modal-content')) 
	return; 
} else {  
 $('#modal-background').hide();
}
});

Solution 16 - Javascript

İt's simple actually you don't need any plugins, just jquery or you can do it with simple javascript.

$('#dialog').on('click', function(e){
  e.stopPropagation();
});
$(document.body).on('click', function(e){
  master.hide();
});

Solution 17 - Javascript

I don't think finding dialog stuff using $('.any-selector') from the whole DOM is so bright.

Try

$('<div />').dialog({
    open: function(event, ui){
        var ins = $(this).dialog('instance');
        var overlay = ins.overlay;
        overlay.off('click').on('click', {$dialog: $(this)}, function(event){
            event.data.$dialog.dialog('close');
        });
    }
});

You're really getting the overlay from the dialog instance it belongs to, things will never go wrong this way.

Solution 18 - Javascript

With the following code, you can simulate a click on the 'close' button of the dialog (change the string 'MY_DIALOG' for the name of your own dialog)

$("div[aria-labelledby='ui-dialog-title-MY_DIALOG'] div.ui-helper-clearfix a.ui-dialog-titlebar-close")[0].click();

Solution 19 - Javascript

Smart Code: I am using following code so that every thing remains clear and readable. out side body will close the dialog box.

$(document).ready(function () {
   $('body').on('click', '.ui-widget-overlay', closeDialogBox);
});

function closeDialogBox() {
    $('#dialog-message').dialog('close');
}

Solution 20 - Javascript

I ended up using this code which should work on any open dialogs on the page, ignores clicks on tooltips, and cleans up the resources of the dialog being closed as well.


        $(document).mousedown(function(e) {
            var clicked = $(e.target); // get the element clicked
            if (clicked.is('.ui-dialog-content, .ui-dialog-titlebar, .ui-tooltip') || clicked.parents().is('.ui-dialog-content, .ui-dialog-titlebar, .ui-tooltip')) {
                return; // click happened within the dialog, do nothing here
            } else { // click was outside the dialog, so close it
                $('.ui-dialog-content').dialog("close");
                $('.ui-dialog-content').dialog("destroy");
                $('.ui-dialog-content').detach();

            }
        });

Solution 21 - Javascript

I just ran across the need to close .dialog(s) with an out of element click. I have a page with a lot of info dialogs, so I needed something to handle them all. This is how I handled it:

$(document).ready(function () {    
    $(window).click(function (e) {
        $(".dialogGroup").each(function () {
            $(this).dialog('close');
        })
    });
    $("#lostEffClick").click(function () {
        event.stopPropagation();
        $("#lostEffDialog").dialog("open");
    };
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSonnyView Question on Stackoverflow
Solution 1 - Javascriptstumac85View Answer on Stackoverflow
Solution 2 - JavascriptJasonView Answer on Stackoverflow
Solution 3 - JavascriptPetersenDidItView Answer on Stackoverflow
Solution 4 - JavascriptMichele LocatiView Answer on Stackoverflow
Solution 5 - Javascriptjk.View Answer on Stackoverflow
Solution 6 - JavascriptJerphView Answer on Stackoverflow
Solution 7 - JavascriptMelanieView Answer on Stackoverflow
Solution 8 - JavascriptGuruKayView Answer on Stackoverflow
Solution 9 - JavascriptJonathan MarzulloView Answer on Stackoverflow
Solution 10 - JavascriptVolomikeView Answer on Stackoverflow
Solution 11 - JavascriptDavid van der TuijnView Answer on Stackoverflow
Solution 12 - JavascriptColinView Answer on Stackoverflow
Solution 13 - JavascriptLaurentView Answer on Stackoverflow
Solution 14 - JavascriptAlejoView Answer on Stackoverflow
Solution 15 - JavascriptNikola Mirković - JohnnyView Answer on Stackoverflow
Solution 16 - JavascriptRzasgalView Answer on Stackoverflow
Solution 17 - JavascriptbadboyView Answer on Stackoverflow
Solution 18 - JavascriptperkasView Answer on Stackoverflow
Solution 19 - JavascriptFarid AbbasView Answer on Stackoverflow
Solution 20 - JavascriptKevin BaragonaView Answer on Stackoverflow
Solution 21 - JavascriptBrian TremellingView Answer on Stackoverflow