jQuery UI modal dialog global close on overlay click - javascript

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?
P.S. 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.
P.S. 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);
});
});

Related

Magnific-Popup close callback does not execute

For each <a> that has mfp-ajax class will be executed as a pop-up box, and this pop-up box use the plugin in Magnific-Popup.
HTML:
View List
Javascript:
magnificSetting: {
type: 'ajax',
mainClass: 'mfp-fade',
ajax: {
settings: {
cache: false
}
}
},
modals: function () {
var self = this;
$('a.mfp-ajax').each(function () {
var $this = $(this);
$this.magnificPopup(self.settings.magnificSetting);
});
}
The codes works fine, however <a> is sometimes dynamically generated in the DOM and I have to create a separate script for Magnific-Popup callbacks. So what I did is I followed what is in the documentation, see the codes below:
$(document).on('mfpClose', '.multiselect-modal', function () {
console.log('test');
});
I tried this code but this does not get executed, how do I attach this in an element that is being generated dynamically in the DOM and when the pop-up opens and the user close it, it will go to the above code. Am I missing something here?
Unfortunately Magnific Popup internally uses triggerHandler() rather than trigger() to implement custom events ,so there is no event for the document to "listen to" so this may never work with current versions
$(document).on('mfpClose', '.multiselect-modal', function () {
console.log('test');
});
There is one fix but that requires you to create global events which is a bad practise so i advice you to make use of callbacks which is close in your case goes like this
$.magnificPopup.instance.close = function() {
//do your stuff here
//this calls the original close to close popup
//you may well comment it out which would totally disable the close button or execute conditional in if else
$.magnificPopup.proto.close.call();
};
these are some properties
//property
magnificPopup.currItem // current item
magnificPopup.index // current item index
// Navigation
magnificPopup.next(); // go to next item
magnificPopup.prev(); // go to prev item
magnificPopup.goTo(4); // go to slide #4

jQuery Widgets not working on tabs loaded by Ajax

I have an application that has many tabs, apart from the first tab - all others are loaded via Ajax.
The tab content all loads correctly.
However if I have a jQuery widget in a (ajax loaded) tab, the widget does not work.
I attempted to use:
$(document).on('click', '#dateOfBirth', function() {
$( '#dateOfBirth' ).datepicker();
});
But the datepicker does not display.
Confusingly (for me):
$(document).on('click', '#dateOfBirth', function() {
alert('This works properly');
});
Works properly! The alert displays when the date field is "clicked".
And of course if I have a simple page without the tabs / ajax content - the datepicker displays as expected when the date field is clicked.
I am using the jQuery 2.2.0 and
jQuery UI 1.12.0 with the "redmond" theme / CSS.
The view html follows the following;
<div class = "emr-bodycontent">
<div id="tabs">
<ul>
<li>Patient Details</li>
<li>Carers</li>
...
...
Here is the JS used for the TABS;
$( "#tabs" ).tabs({
beforeLoad: function( event, ui ) {
ui.jqXHR.fail(function() {
ui.panel.html(
"There seems to be an error retrieving the data you requested."
);
});
}
});
Instead of using click use focus and datepicker will work . Assumes that the element id is valid and is an input
$(document).on('focus', '#dateOfBirth', function() {
$( '#dateOfBirth' ).datepicker();
});
For any other plugins inside tabs you can use load callback of tabs ... see api docs
DEMO
I will suggest you to setup the datepicker() after Ajax content loaded, do not use click event. Because the initiate call of $('#dateOfBirth').datepicker() is to set up the datepicker, you may need to click again to trigger the calendar.
Or, you can try to manually trigger it right after set.
$(document).on('click', '#dateOfBirth', function() {
$(this).datepicker();
$(this).datepicker("show");
});
Firstly, thanks very much for the answers / comments.
Both answers work successfully.
Kieran's worked straight away as it was manually triggering the event.
Charlie's worked, too - but only after I clicked several times.
Though after fixing my underlying issue, Charlie's worked straight away, too.
The underlying issue was indeed a duplicate ID.
(thanks for the prompt to check, Charlie).
Because the TAB contents are their own individual forms / pages - I only ever worried about making ID's unique within individual TABs.
After ensuring that ALL IDs are unique, the widget works correctly / as expected.

How to use Zurb Foundation reveal with open, opened, close, closed callback functions?

On zurb foundation's website at http://foundation.zurb.com/docs/reveal.php they listed some Options including
open: callback function that triggers 'before' the modal opens.
opened: callback function that triggers 'after' the modal is opened.
close: callback function that triggers 'before' the modal prepares to close.
closed: callback function that triggers 'after' the modal is closed.
But I have no idea how to use them with my modal.
I tried:
$('#myModal').closed(function()
{});
$('#myModal').trigger('reveal:closed')(
{});
$('#myModal').reveal.closed(function()
{});
$('#myModal').reveal().closed(function()
{});
I have Googled but found no hits. Anyone who can explain it or give me an example or provide a related link?
The suggestion given works, however
I have yet another closely related question for reveal():
Click Me For A Modal);
I tried to add one attribute like data-closeOnBackgroundClick="false" That doesn't seem to work. What should be the correct syntax? Will it work for callback function as well?
The above answer did not work for me. Here's what worked (Foundation 4 and jQuery):
$('#myModal').bind('opened', function() {
console.log("myModal opened");
});
Event Bindings for Zurb Foundation Reveal -
There are a series of events that you can bind to for triggering callbacks:
$(document).on('open.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
$(document).on('opened.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
$(document).on('close.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
$(document).on('closed.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
If you have multiple data-reveal used in single page as follows :
<div class="content reveal-modal" id="element-1" data-reveal>
<div class="content reveal-modal" id="element-2" data-reveal>
Then in this situations you can trigger callback same as explained above but with little modification as shown below :
$(document).on('open.fndtn.reveal', '#element-1[data-reveal]', function () {
// your code goes here...
});
$(document).on('open.fndtn.reveal', '#element-2[data-reveal]', function () {
// your code goes here...
});
Call reveal like you normally would, but include the name of the option and corresponding function as an object:
//Reveal the modal and say "Good bye" when it closes
$("#myModal").reveal({ "closed": function () { alert("Good bye") } });
On Zurb Foundation v6, these events were renamed to xxx.zf.reveal:
closeme.zf.reveal Fires immediately before the modal opens. Closes any other modals that are currently open
open.zf.reveal Fires when the modal has successfully opened.
closed.zf.reveal Fires when the modal is done closing.
Source: http://foundation.zurb.com/sites/docs/reveal.html#js-events
Examples:
Generic callback that will fire for all modals:
$(document).on('open.zf.reveal', '[data-reveal]', function() {
console.log('This works');
});
Callback that will fire when a specific modal is opened:
$(document).on('open.zf.reveal', '#<ELEMENT-ID>[data-reveal]', function() {
console.log('This works');
});
Like meatrobot said, to get this working you want to bind to the modal with the action you are targetting. I got this to work:
$('#myModal').bind('closed', function() {
console.log("myModal closed!");
});
This is a little late but for the second part you add the attributes as a semi-colon separated list of values in the data-options attribute (tested with foundation 5), i.e:
<div id="myModal" data-options="close_on_background_click:false;" class="reveal-modal">
And no, you cannot pass functions this way, i tried :)
Looking at Foundation 5 and found that the reveal library triggers open, opened, close, and closed events. Just attach a handler to the event you want.
$('#myModal').on([event], handler)
You can also pass the handlers via the settings argument.
Check this out: https://github.com/zurb/foundation/blob/master/js/foundation/foundation.reveal.js#L92
The foundation 5 documentation specifies scoping of reveal events to the 'reveal' eventspace. However, the actual modal events do not seem to fire consistently within this eventspace. Removing this specification fixes the issue:
$(document).on('opened.fndtn', '[data-reveal]', function() {
console.log('This works');
});
In foundation 3.2.5 you should bind 'reveal:opened' like this:
$('#myModal').bind('reveal:opened', function() {
console.log("myModal opened");
});
Regards, MarianoC.

JQuery: dialog doesn't fire autocomplete

I'm using the http://docs.jquery.com/UI/Dialog and http://docs.jquery.com/UI/Autocomplete with JQuery 1.7.2 and JQuery-UI 1.8.18.
There is a form with a text box, which will fire the autocomplete fine when loaded in the page as normal. It's nice and simple!
(function() {
jQuery(function($) {
return $("#type").autocomplete({
source: "/auto-suggest/supplies",
minLength: 2
});
});
}).call(this);
However, if the form is rendered via a dialog the autocomplete does not fire (no UI changes, and the server shows no access to the source url). I'm assuming this is because the input field has not been rendered at document load. So, I tried to use dialog's create event to assign the autocomplete, by passing the function to it as a callback. Again, the autocomplete does not fire.
I'm mystified as to how to get this to work. I would be tempted to get the dialog to create and then hide on document load, but in this instance there could be several instances of the dialog as it's related to table data.
Any help with this will be much appreciated.
Try using open event - this will ensure that the DOM elements are ready
$( ".selector" ).bind( "dialogopen", function(event, ui) {
$("#type").autocomplete({
source: "/auto-suggest/supplies",
minLength: 2
});
});
You can even get the values and then in the success call dialog
$.get('/auto-suggest/supplies', function(data) {
//call dialog here
});
Try delegate
Delegate autocomplete
BEST SOLUTION IS WROTE BY: ManseUK

How to destroy YUI Panel on close?

I want to be able to destroy a YUI Panel when the user clicks the close button.
I have tried using hideEvent but that does not work. I'm assuming since the object is still active and therefore cannot be destroyed:
panel.hideEvent.subscribe(function(o) {
panel.destroy();
});
Is there a way I can destroy the Panel when a user clicks close? The close button is not assigned an ID although it is assigned a class:
<a class="container-close" href="#">Close</a>
Ending up having to use the setTimeout() function:
panel.hideEvent.subscribe(function(o) {
setTimeout(function() {panel.destroy();}, 0);
});
Where win is a YUI simple dialog, I use this:
w.win.hideEvent.subscribe(function(e) {
this.destroy();
});
using the hideEvent as above leads to javascript errors in firebug. the following solution works without problems:
dlg -> instance of yui2 dialog or similar.
dlg.close -> is the html element of the close icon
Use the following code after having the dialog rendered:
//remove the default click handler (._doClose)
YAHOO.util.Event.removeListener(dlg.close, "click");
//add a new click handler (._doClose)
YAHOO.util.Event.on(dlg.close, "click", function(){
this.destroy();
}, dlg, true);

Categories