简体   繁体   中英

jQuery UI modal dialog global close on overlay click

I have several modal dialogs in my page and there will be even more. I plan to use modal dialogs for them all and have them close on overlay click. I don't want to bind the overlay click event in every place I instantiate a dialog, so I would like to extend the dialog prototype or something similar to make it bind the click event globally for all modal dialogs.

http://jsfiddle.net/jurchiks/kLBJm/1/

Let's say I have the following dialog constructor:

$('#dialog').dialog({
    modal: true,
    open: function()
    {
        $(this).find('input[type=text]').focus();
    }
});

I've tried putting this code before dialog instantiation:

$.extend(
    $.ui.dialog.prototype.options,
    {
        open: function()
        {
            var dialog = this;
            $('.ui-widget-overlay').on('click', function()
            {
                $(dialog).dialog('close');
            });
        }
    }
);

but it does not work, jQuery only calls the open function passed in the dialog parameters. I have suspicion that this simply changes the default open function and whatever is passed to the constructor is overriding this.

$.widget(
    "ui.dialog",
    $.ui.dialog,
    {
        open: function()
        {
            this._super();
            var dialog = this;
            $('.ui-widget-overlay').on('click', function()
            {
                $(dialog).dialog('close');
            });
        }
    }
);

This does not work either; jQuery spits out an error - "cannot call methods on dialog prior to initialization; attempted to call method 'close'" - even though the popup is open. How could I make it so the overlay click & close event is global and not overridable?

PS why the hell is this not provided by the jQuery UI library? I would think this is something very popular.

Ok, I made my own slightly hackish solution that works, but it seems that it only works on my version of jQuery (1.10.3). I tried the exact same code with jsfiddle's offered jQuery UI 1.9.2 and it simply didn't call the function. I'm guessing the function name has been renamed in 1.10.

Anyway, here's the code:

$.widget(
    'ui.dialog',
    $.ui.dialog,
    {
        _createOverlay: function()
        {
            this._super();

            if (!this.options.modal)
            {
                return;
            }

            this._on(this.overlay, { click: 'close' });
        }
    }
);

And the test fiddle: http://jsfiddle.net/jurchiks/R944y/1/

Had to add external jQuery UI 1.10.3 CDN links to it to make it work, but hey - at least it works and it's a pretty simple solution, just had to dig inside jQuery UI's code to find out the simplest way to do it.

PS This would take so little effort to be built into the dialog plugin itself, it is remarkable that nobody has done it. All you'd need to do is add an option to enable/disable close on overlay click and the last line of my function inside an IF that checks if that option is enabled, a total of max. 4 lines.

Edit: created a patch for current jQuery UI: https://gist.github.com/jurchiks/7264596

it's not overriding but you can listen to certain events on the document:

$(function() {
  var theDialog;
  $( document ).on("click",
    ".ui-widget-overlay",function(){
      $(theDialog).dialog("close");
  });
  $( document ).on( "dialogopen", function( event, ui ) {
    theDialog=$(event.target);
  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM