I am using JQuery's $.dialog(), where I open a dialog with OK and Cancel buttons.
I would have expected that when the dialog opens, the code stops, and would first continue, when the user had selected OK or Cancel.
Here is my complete source code
http://pastebin.com/uw7bvtn7
The section where I have the problem is at line 127-151.
$("#dialog:ui-dialog").dialog("destroy");
$("#dialog-confirm").dialog({
resizable: false,
height: 600,
modal: true,
open: function() {
$(this).children('div.dialog-text').replaceWith("<h3><b>Users</b></h3>" + makeDialogTable(users) + "<h3><b>Owners</b></h3>" + makeDialogTable(owners));
},
buttons: {
"Okay": function() {
$(this).dialog("close");
},
Cancel: function() {
is_okay = 0;
$(this).dialog("close");
}
} // buttons
}); // dialog
alert(is_okay);
What the code does right now is to first show the dialog and then the alert(is_okay) on top.
What I would like is that the code first continues when the user have pressed OK or Cancel.
How could that be done?
You can put your additional code in the "Okay" and "Cancel" button functions. For example:
"Okay": function() {
$(this).dialog("close");
alert(is_okay);
},
That can't be done in a "good" manner plus I strongly recommend not to go that way.
What you describe is a complete blocking, modal window/dialog which is just aweful for web applications. You're already creating the dialog with the modal flag, so a user can't really do anything on your site while the dialog is open, BUT the UI keeps responsive.
Again, there is actually no way to "hold" code execution. Any approach in that direction would freeze the UI thread since Javascript and UI updates share the same thread.
Since quite a few years, developers pushed Javascript to be more and more non-blocking (Javascript in browsers actually always followed that route, which is very good thing). The idea was reborn with nodeJS on the backend. So, you're swimming upstream here, don't do it.
Whatever the problem is you try to solve there, try to think in different way. Think functional, use callbacks and events, think... ECMAscript! :p
The code does execute sequentially. The job of $("#dialog-confirm").dialog() is to popup a dialog box. alert(is_okay) won't execute until the lines above it have been executed. But Okay and Cancel are event listeners.
"Okay": function() {
$(this).dialog("close");
}
The code above assigns event listeners to events. That's all it does, it does not execute those functions, it just assigns those functions to event calls.
I would recommend doing some reading on events and event listeners. If you plan on using JQuery seriously, it will save you a lot of confusion.
$("#dialog-confirm").dialog({ ...
close :(event, ui) { alert(is_okay);}
})
Or you can bind function later :
$( "#dialog-confirm" ).bind( "dialogclose", function(event, ui) {
alert(is_okay);
});
The code doesn't stop and continue like it does with alert , but it will display message only when dialog is closed.
Simply put all code that follows after opening the dialog in a function and call that function from the dialogs callback function for okay / cancel.
function doTheRest(args) {
alert(args);
}
// snippet from dialog options
"Okay": function() {
$(this).dialog("close");
doTheRest(1);
},
"Cancel": function() {
$(this).dialog("close");
doTheRest(0);
}
Browsers use an event-based, asynchronous programming model where many things can (and do) occur at the same time. This is how style-transitions (animations like rolldown or fade) work.
Your example displays a dialog and then throws an alert. It cannot "wait" for the user to click on a button because doing so would stop the browser from doing anything else.
So you'll need to refactor your code to do whatever you require to happen when either the OK or Cancel buttons are clicked within the callback associated with the action.
In other words, you need to:
buttons: {
"Okay": function() { // this function is called when a user clicks the Okay button
// do whatever work is required here
}
}
There is no direct way to "wait" for something in JavaScript -- asynchronous events are generally handled through callbacks. This means you need to think of your program in terms of events and not as sequential code. Instead of your current code:
$("#dialog-confirm").dialog({
...
});
alert(is_okay);
// rest of code
you need to wrap the "rest of code" section into its own function, then call that from the OK/Cancel callbacks of your dialog:
$("#dialog-confirm").dialog({
...
buttons: {
"Okay": function() {
$(this).dialog("close");
what_happens_if_okay();
},
Cancel: function() {
$(this).dialog("close");
what_happens_if_not_okay();
}
} // buttons
}); // dialog
So if I understand correctly you want an alert to show up with the options OK and Cancel and the Dialog would not come up unless OK was hit.
Instead of using another alert why not try using another dialog with Ok and Cancel in it?
In your html do this:
<div id = "hiddenDialogElements">
<button id = "Ok" onclick = "confirm(true)">OK</button>
<button id = "Cancel" onclick = "confirm(false)">Cancel</button>
</div>
With this css:
#hiddenDialogElements
{
display: none;
}
Then you can do this on the event that will create the dialog (Where you want a wait):
$('#hiddenDialogElements').dialog({
//Code
});
And this:
function confirm(ifOk)
{
if(ifOk)
{
//Create Dialog
}else {
//Do nothing
}
}
Do Something Like this ...
function MyAlert(Message, Title,FuncExecAfterOkPressed) {
$("<div>" + Message + "</div>").dialog({
title: Title,
dialogClass: "alert",
width: "auto",
modal:true,
open: function (event, ui) { $(".ui-dialog-titlebar-close").hide(); },
buttons: [
{
text: "Ok", click: function () {
$(this).dialog("close");
if (FuncExecAfterOkPressed != null) {
$.Callbacks().add(FuncExecAfterOkPressed).fire(null);
}
}
}]
});
}
Now Call it like this
MyAlert(data, "Duplicate", function () {
alert("I m moumit");
$("#Name").val("");
});
One thing u need is JQueryUI plugin... Enjoy.
Related
I'm trying to set up a page with a modal window which fires on either the mouse existing the window or on the click of a link.
Firing on exit is ok using Ouibounce:
http://carlsednaoui.github.io/ouibounce/
The documentation on the Ouibounce API suggests I should also be able to fire the modal via a click.
I have changed the link in the above example, giving it an id of #modal_button but I can't get it to fire the window:
// if you want to use the 'fire' or 'disable' fn,
// you need to save OuiBounce to an object
var _ouibounce = ouibounce(document.getElementById('ouibounce-modal'), {
aggressive: true,
timer: 0,
callback: function() { console.log('ouibounce fired!'); }
});
$('#modal_button').on('click', function() {
$('#ouibounce-modal').fire();
});
$('body').on('click', function() {
$('#ouibounce-modal').hide();
});
$('#ouibounce-modal .modal-footer').on('click', function() {
$('#ouibounce-modal').hide();
});
$('#ouibounce-modal .modal').on('click', function(e) {
e.stopPropagation();
});
I set up a jsfiddle here which does the same thing.
http://jsfiddle.net/fr7k3s6f/
(for some reason the 'hide" on the body event doesn't work in the jsfiddle)
You need to use your object _ouibounce to call the fire() function on:
_ouibounce.fire();
and not the jQuery object. And it needs to be a global object if you define it at jQuery.ready(), so no "var" before. But i think this is a bug in the current version (0.0.10).
I hope this helps.
Requirement is to show dialog box on click of a button.I have created dialog box using jQuery UI. Please find the code here http://jsfiddle.net/M4QM6/32/.
ISsue is i have single function for creating dialog box, how can i show multiple dialog box within same page with each dialog box displaying different data,
When i click on dialog2 button, i need to show a dialog box which has textArea and a submit button.Please suggest.
Below is the sample code:
$(function() {
$("#dialog").dialog({
autoOpen: false,
resizable: true,
width:"750",
height:300,
modal: true,
buttons: {
"Close": function() {
$(this).dialog("close");
}
}
});
});
You could go a couple routes. Since your need for dialog content is pretty specific (textarea control - first dialog pops second dialog - etc), I would hard-code the needed divs on the page. So, make a "#textAreaDialog" div and put the needed controls in it ad set its style to display:none.
Next, modify your function to accept parameters (the name of the div that should be popped, the funciton to execute if "OK" is clicked - and the function to execute if "Cancel" is clicked), so you're not limited to using #dialog for all of your modals and you can finely control what happens when each button is clicked (not always just closing the dialog. Then, set event handlers for the click events of the buttons you need, and call your dialog accordingly.
html:
<input type="button" id="btnPopFirstModal" Value="Open First Modal"/>
<div id="divFirstModal" style="display:none;">
Here is the content for the first modal
</div>
<div id="divSecondModal" style="display:none;">
Here is the content for the second modal
</div>
Javascript functions:
function PopDialog(divToPop, OkFunction, CancelFunction)
{
$("#" + divToPop).dialog({
autoOpen: false,
resizable: true,
width:"750",
height:300,
modal: true,
buttons: {
"Ok": function() {
OkFunction();
$(this).dialog("close");
},
"Cancel": function(){
CancelFunction();
$(this).dialog("close");
}
}
});
});
}
function PopSecondModal(){
PopDialog("divSecondModal", function(){ put code for OK Click here}, function(){put code for Cancel Click here});
}
Javascript event handlers:
$("#btnPopFirstModal").click(function(e){
e.preventDefault();
PopDialog("divFirstModal", PopSecondModal, function(){}); //empty function for cancel, but you can add your own code as needed
return false;
});
Remember, you can expand this as much as you want, adding more event handlers and custom divs to use for more tailored modals. Also, as you can see, you can write your OK and Cancel funcitons inline when calling the PopDialog function - or you can pass it a function name (this is preferable if you're going to reuse that function).
Here is how I did:
$(
//when JQuery is ready
funciton()
{
$('#SomeButton').on
(
'click',
function()
{
//Note that content could be anything (HTML, text...)
//This dynamicly create a div to be your dialog
$('<div>').append(content).dialog
(
{
//autoOpen: false, I removed it you can put it back in if you need it but I dont think its important for now
resizable: true,
//I remove the double quotes here because height didn't have any but maybe it was the other way around
width:750,
height:300,
//I put this on false because if two or more dialog would need to be displayed at the same time you can't have them modals.
modal: false,
buttons:
{
Close: function()
{
$(this).dialog("close");
}
},
//this is important it destroys and remove the dynamically create dialog when you close them so you don't get 20 dialog not displayed in your html markup.
close:
function()
{
$(this).dialog('destroy').remove();
}
}
);
}
);
}
);
I am using a jQuery plugin for showing notifications.
so i can use something like this
show_notification("Successfully Saved your data","success");
we can use html content as message.
Now i want to perform some actions
ex.
show_notification("Do you want to save your data","success");
so this is a question to the user and user need to reply by clicking yes or no [both will be passed as html message]
what i need to do is when user clicks on yes/no i need to perform some actions.
i can use id or class to attach a click event,but i have many types of actions,and need to use very different id or class.
can i use a call back function or something like that ?
Please help me or give me your valuable suggestions .
Thank you.
Note : I know that it is not possible with current plugin and not talking about its functionalities ,i am just trying to modify the plugin.
In case there is no way to send a callback to your plugin, you would have to manually add the Yes/No-buttons to your message, and target them either by live delegates or by assigning a listener after the notification has been shown.
$(function() {
$('body').on('click', '.notification-yes', function() {
// yes-callback
});
$('body').on('click', '.notification-no', function() {
// no-callback
});
});
show_notification('Do you want to proceed? <button class="notification-yes">Yes</button> <button class="notification-no">No</button>', 'success');
If it is this plugin that you're using, you'll want your listeners to call closeNotification(). I realize that the syntax is not exactly the same, but that could be a versioning issue. It'd be easier to help you with the specifics if we knew the details of the plugin you're using.
You'll also need a way of knowing which notification was showing when the button was clicked. You could of course have unique button class names for different notifications. Another approach, if there is always just one notification showing at any given time, would be to have a small state object for the callback of interest. For instance:
var myNotifications = {
onYes: function() { },
onNo: function() { }
};
$(function() {
$('body').on('click', '.notification-yes', function() {
myNotifications.onYes();
closeNotification();
});
$('body').on('click', '.notification-no', function() {
myNotifications.onNo();
closeNotification();
});
});
function showCertainNotification() {
myNotifications.onYes = function() {
// specific callback for this notification.
};
show_notification('Confirm? <button class="notification-yes">Yes</button> <button class="notification-no">No</button>', 'success');
}
If there could be several notifications showing at any one time, a simple variable like that won't do. In that case you'd have to wrap your message in a container, the ID of which you could extract from your listener, and call a specific callback based on that, or passing that as a parameter. I won't go into detail here, seeing as the simple nature of show_notification implies an equally simple manner of close_notification. Since no ID's seems to be anywhere to be found, I'll assume that multiple active notifications are not supported.
A more appealing solution might have been to modify the plugin itself, rather than to work around it, so that you could pass callback functions directly to the plugin. Something like this:
show_notification({
message: 'Confirm',
type: 'success',
buttons: [
{ caption: 'Yes', click: function() { } },
{ caption: 'No', click: function() { } }
]
});
But of course, this is no way near possible to help you with, without first having a chance to look at what the plugin you're currently using looks like.
I have posted on this thread - How do I pass function as a parameter in javascript for creating pop up box request with several functionality.
One of the answers there stated a problem that I thought should have a new thread.
My task is this - I have several buttons for each item (let's say I have several articles and each one I can delete, edit etc..) - for each button I want a pop up box that asks me if I'm sure or not sure I want to do this task.
How do I do it correctly?
this is an example for what happens when I click on of the delete buttons:
$('.delete').click(function(){
var obj={title:"The Header",someText:"Are you sure?"};
DisplayPopUp(obj,function(){console.log('going to delete');});
});
after I have the "are you sure?" pop up - this is the pop up function:
function DisplayPopUp(obj, callback) {
//On Action Clicked
$('#actionButton').click(function(e){
e.preventDefault();
callback(obj);
});
}
My main concern is that each time I click the delete button - I multiply the "are you sure" button function. How do I delete this event before I re-create it? Where do I need to put it?
and in general - is this the right method to do it or is there a better, cleaner code (assuming I need to do it without using jQuery-UI?
take to consideration that I want it to be fluid and to work on several tasks like create/delete/edit etc...
thanks,
Alon
=========== THE HTML ==============
looks like this: - I use $('content').html(theContentIneed) to fill the content and toggle display modes to hide/unhide it.
<div id="popup">
<div id="content">
</div>
<a id="actionButton">action</a>
</div>
You might want to use the jQuery plugin pattern:
$.fn.displayPopUp = function(data, callback) {
return this.each(function() {
// popup stuff
if (typeof callback == 'function') {
callback.call(this);
}
};
});
$('.delete').click(function(){
$(this).displayPopUp({
title: "The Header",
someText: "Are you sure?"
}, function() {
console.log('going to delete');
});
});
Now that we can see that you're only hiding/showing the HTML (not creating/destroying it), you can solve the issue of too many click handlers by assinging the event handler once before anything starts and use the .data() method to store your context:
$('#actionButton').click(function(e){
e.preventDefault();
var fn = $(this).data("callback");
fn();
});
function DisplayPopUp(obj, callback) {
$('#actionButton').data("callback) = function() {callback(obj);};
// do other stuff here to make the popup visible, etc...
}
Or, if you really wanted to do it the way you were doing it and are using jQuery 1.7+:
function DisplayPopUp(obj, callback) {
//On Action Clicked
$('#actionButton').on('click', (function(e){
$(this).off('click');
e.preventDefault();
callback(obj);
});
}
Here is the code I'm using
http://jsbin.com/evike5/edit
When the jQuery UI dialog is fired second time. The updated title is not shown.
Am I doing something wrong?
This is because you're opening the same dialog, for it to take effect you either need to destroy the old dialog, like this:
$("#hello").dialog('destroy').attr("title", "Helloooooooo!")
Try it here.
Or just set the title and button behavior without re-creating the dialog, like this for your OK button:
OK: function () {
$(this).dialog("close")
.dialog("option", {
buttons: {
OK: function () {
$(this).dialog("close");
}
},
title: "Helloooooooo!"
}).dialog("open");
}
You can give that a try here.