I have a jQuery UI dialog box with a form inside it. I'm trying to implement a feature where if a field in the form has been modified, we'll be showing a confirmation message using noty
Now, unlike an javaScript confirmation box, noty does not stop script execution. So, in the dialog beforeClose event, I'm -
Showing a noty confirmation if form data is modified and then returning false.
Simply returning true if the form data has not been modified.
All is working well. Now we ask the user -
The data in the form has been modified. Are you sure you want to close?
If he clicks no - we simply close the noty and keep the dialog box open.
But if he clicks yes, we try to close the dialog box, which triggers the beforeClose event handler again and we go into the loop again.
I've tried calling .off on the div that has been converted to a dialog box before calling the close event, but that doesn't seem to be removing the click.
Here is a simple pseudo code to explain the issue -
DialogCloseEvent() {
if data has been modified {
Show noty {
// IMPORTANT - This is executed after return false.
in noty user clicks NO - do not close dialog box {
close noty and done
}
in noty user clicks YES - close the dialog box {
// This calls the DialogCloseEvent again.
call the close method of the dialog box.
close noty
}
}
return false
}
no it has not been modifed {
// Closes the dialog without calling the event again
return true;
}
}
Expanding on your pseudo code you could add a flag to force close the dialog:
var forceClose = false;
DialogCloseEvent() {
if data has been modified and !forceClose {
Show noty {
// IMPORTANT - This is executed after return false.
in noty user clicks NO - do not close dialog box {
close noty and done
}
in noty user clicks YES{
forceClose = true;
- close the dialog box {
// This calls the DialogCloseEvent again.
call the close method of the dialog box.
close noty
}
}
}
return false
}
no it has not been modifed {
// Closes the dialog without calling the event again
return true;
}
}
UPDATE with code
var forceClose = false;
$("#dialog").dialog({
open: function (event, ui) {
forceClose = false; //reset the flag each time
},
beforeClose: function (event, ui) {
if(forceClose){
return true;
}
//your dialog close event
//set the flag to true when you want to close the jqueryui dialog
}
});
According to the code for the close API for Jquery UI dialog, there is no way not to force close a dialog without firing events. Ideally there should be an API which just executes the functionality without triggering events. I tried just a way to enable this by replicating the method for now. Best way as an addition to the API itself. So the change is something on the lines of this,
// code from existing
if(!forceClose && this._trigger("beforeClose") === false){
return;
}
// continue with existing
Have a fiddle for the same here http://jsfiddle.net/Lj3Nk/1/
Going to submit a feature/pull request to jquery ui now. Will update with details when done. In the mean while, let me know if this helps.
UPDATE
Jquery ui ticket - http://bugs.jqueryui.com/ticket/9943
Pull request - https://github.com/jquery/jquery-ui/pull/1218
Example 1
Based on the flag approach:
var notyStatus = null;
$("#dialog").dialog({
beforeClose: function (event, ui) {
// possible values for notyStatus are
// null: preventDefault and show the warning
// else: do nothing and let the dialog close
if (notyStatus === null) {
event.preventDefault();
$('<p title="Replace me with noty">Close the dialog?</p>').dialog({
modal: true,
buttons: {
"Close": function () {
notyStatus = true;
$(this).dialog("close");
$("#dialog").dialog("close");
},
"Keep Open": function () {
$(this).dialog("close");
}
}
});
}
}
});
Demo 1
Example 2
Remove the beforeClose event handler. You can use .dialog("option", "beforeClose") to get, set or unset the event handler. The code looks like this:
$("#dialog").dialog({
beforeClose: function (event, ui) {
event.preventDefault();
$('<p title="Replace me with noty">Close the dialog?</p>').dialog({
modal: true,
buttons: {
"Close": function () {
$(this).dialog("close");
$("#dialog")
.dialog("option", "beforeClose", null)
.dialog("close");
},
"Keep Open": function () {
$(this).dialog("close");
}
}
});
}
});
Demo 2
In both examples, replace the inner jQuery UI confirmation dialog code with noty. It allows you to create action buttons with callbacks so the code will be similar.
You can use the dialog widget's "option" method to change or remove the beforeClose event handler.
So when the user clicks 'yes', you could get the dialog to close by executing:
$('#myDialog')
.dialog('option', 'beforeClose', function() {})
.dialog('close');
Here's a fiddle that shows how it works: http://jsfiddle.net/BrDE7/1/
Jquery UI documentation on the "option" method: http://api.jqueryui.com/dialog/#method-option
Related
I'm using Bootstrap 3 to create modal form. Before user click button to open the modal, there is a field validation.
If it is valid then modal is shown, otherwise prevent the modal from being shown.
The problem is on the second chance, user click the button and the modal won't display.
How to solve this problem?
Code to show modal and prevent modal from being shown: jsfiddle
$("#btnLookupClient").click(function (e) {
if ($("select[name='OfficeID'] option:selected").index() <= 0) {
alert("Please select office");
$("#OfficeID").focus();
$("#clientModal").on("show.bs.modal", function (e) {
return e.preventDefault() // stops modal from being shown
});
} else {
var url = '#Url.Content("~/Client/Search?officeID=")' + $("#OfficeID").val();
$.get(url)
.done(function (data) {
$("#lookup-client-container").html(data);
$("#clientModal").modal(show = true, backdrop = true);
});
}
});
Use one() instead of on().
$("#clientModal").one("show.bs.modal", function (e) {
return e.preventDefault() // stops modal from being shown
});
See here : http://jsfiddle.net/akcbj4n5/1/
Also reference : Difference between jQuery.one() and jQuery.on()
when the alert gets shown you are binding the preventDefault to the event that shows the modal so it will never be shown again, even when the validation passes.
I'd suggest using the .one() function instead of .on() http://api.jquery.com/one/
Also you're modal will fire without having to call it in javascript because you set the toggle to modal and the target to the modal id.
I'm using jQuery 1.9.1, and jQuery Mobile 1.3.1, and I want to create a dialog box, with only one button, informing the user that their time is up in my game. The point is that, as long as I can see dialogs in jQuery appear after certain eventType. For example, after a button is clicked the dialog can appear. But in my situation I don't have any event, it must just appear automatically when the condition in the if statement is true. And when the user clicks OK button on the widget, he/she should be transferred to the page referred below. Any idea how to achieve it?
function showTimer() {
if (timestamp.getMinutes().pad(2) == "59" && timestamp.getSeconds().pad(2) == "59") {
// dialog goes here...
$.mobile.navigate("#finalPage");
}
return false;
}
It's all possible using jQuery:
//Initialise the dialog first
var dialog = $('<p>Are you sure?</p>').dialog({
autoOpen:false,
buttons: {
"Cancel": function () {
$.mobile.navigate("#finalPage"); // Your custom code for navigation on button click
}
}
});
setTimeout(function(){ // When your condition is met, just call the dialog using this code
dialog.dialog('open');
},2000);
Here,I have used timeout just to show how you can open the dialog at any stage without triggering any click.
Demo : http://jsfiddle.net/lotusgodkk/GCu2D/175/
start a timer with setInterval, and check the condition every x milliseconds
I'm trying to add a confirm box to many links, button, or inputs, on the click event.
I can't use location.href, submit(), or other specific features because :
location.href, for example, won't work on a submit button,
location.href, for example, won't trigger other bound handlers.
So what I need to use is the trigger() function, that theorically execute all the handlers AND the native action. The "difficult" part is to execute all handlers, EXCEPT the handler which pop the confirm box.
Here is my code :
$('a, button, input[type="submit"]').each(function() {
var oButton = $(this);
oButton.on('click.pending', function(oEvent) {
console.log('click !');
oEvent.preventDefault();
var oDialog = $('<div class="dialog-example">[Question] ?</div>').dialog({
buttons: {
Cancel: function() {
console.log('cancelled !');
// Nothing to do
oDialog.dialog('close');
},
Ok: function() {
console.log('confirmed !');
// Trigger the rest of the handlers AND the native action, BUT not this one, so this dialog is not used
// Problem : nothing happens here
oButton.trigger('click.confirmed');
oDialog.dialog('close');
}
}
});
});
});
Thanks in advance ! ;)
You should try:
oButton.off('click.pending').trigger('click').get(0).click();
DEMO
I have a confirm box on my colorbox("are you sure you want to leave?").
This triggers when i close the popup. This works when i click on the "cboxClose" div on the popup.
I am trying to show this confirm box on a button click. But the popup just closes right away without showing the confirm box.
My question is how do i trigger the the confirm box when i click on a cancel button. i tried several ways
//This just closes the pop up without showing the confirm box
$('#btnCancel').click(function () {
parent.$.colorbox.close(); });
//doesn't work
$('#btnCancel').click(function () {
$('#cboxClose').click()
});
COLORBOX
onComplete: function () {
$("#cboxClose").click(function (e) {
// stop any other script from firing
e.stopPropagation();
if (confirm('are you sure you want to leave?')) {
$.colorbox.close();
// ensure that the binding is removed when closed
$("#cboxClose").unbind();
}
});
} // close oncomplete
The issue here is that colorbox registers a click handler on the cboxClose element. As a result, neither stopping bubbling nor preventing the click (by returning false in a click handler) will have any effect because the colorbox handler is already registered. The only way of stopping that handler from being run is to unbind it. However, to do that you need a reference to the handler, which you won't get without modifying the colorbox code.
In any case, that's what's going on and why the code you have above doesn't work. Another option for you would be to override the colorbox close function (which is the public colorbox method that is called by colorbox's close button handler). All you need is this:
$.colorbox._close = $.colorbox.close;
$.colorbox.close = function() {
if(confirm("Close?")) {
$.colorbox._close();
}
}
The down side (which may not be an issue in your situation) is that this will affect all colorboxes on the page.
I solved this issue by making this method and binding it to the cancel button
var originalClose = $.colorbox.close;
$.colorbox.close = function (e) {
var response;
var formChanged = localStorage.getItem("isFormChanged");
var saveClicked = localStorage.getItem("saveClicked");
if (formChanged == "true" && saveClicked == "false") {
response = confirm('Do you want to close this window? All your changes will not be saved');
if (!response) {
return
}
}
originalClose();
};
<input type="button" value="Cancel" id="btncancel" onclick="parent.$.colorbox.close()"/>
I am new to jQuery but have already implemented successfully several modal dialogs using the jqueryUI dialog widget. In trying to implement another one, the modal dialog opens, but the code continues on to execute without stopping for user input. Using jQuery 1.7.1 and jquery-ui-1.8.16.
Here is the definition of a "prototype" of the dialog (it is a "prototype" because it doesn't take the actions on the "OK" selection that would be needed to meet requirements):
var $confirm = $('#confirm');
$confirm.dialog(
{
autoOpen:false,
width:440,
modal:true,
buttons:
{
OK: function()
{
$( this ).dialog( 'close' );
},
Cancel: function()
{
$( this ).dialog( 'close' );
}
}
});
Here is some test code that opens the dialog:
[ some javascript that does error checking]
alert('stop1');
$('#confirm').dialog('open');
alert('stop2');
[ more javascript including submitting the form]
What happens is the the first alert displays. Upon clicking on it the dialog opens along with the second alert, indicating that the dialog is not waiting for user input. The second alert is modal and prevents the dialog from being accessed. When it is clicked on, the form submits. This sequence shows that the dialog is not waiting for user input.
I have looked and looked at my other successfully implemented modal dialogs and do not see what might be causing this one to fail.
The dialog won't wait. Instead you'll want to use this as a point to decide what you want to happen. So instead of including additional code that you may or may not want to run after the dialog modal, let that be the last part of the function.
Then, with your OK or Cancel functions, make the call there to continue on with the workflow if they chose ok, or just hide and do whatever cancel stuff needs to be done with the cancel.
In short, the modal dialog will not pause execution of the javascript, it will just run the code to open the modal and keep on going.
You should use a promise:
function deferredConfirm(message) {
$('<div></div>').html(message).dialog({
dialogClass: 'confirmDialog',
buttons:
[{
text: buttonText,
click: function () {
$(this).dialog("close");
defer.resolve();
}
},
{
text: buttonText2,
click: function () {
$(this).dialog("close");
defer.reject();
}
}],
close: function () {
$(this).remove();
}
});
return defer.promise();
}
And to call it:
deferredConfirm("Oh No!").then(function() {
//do something if dialog confirmed
});