Looked around quite a bit, and can't seem to find a JQuery solution (maybe its just a limitation of JavaScript) for this:
<a href="somelink.php"
onclick="return confirm('Go to somelink.php?');">Click Here</a>
In the above example, when a user clicks on the link, it will only go to its href if the user clicks OK in the confirm box.
What I am trying to do is get a more modern look using a popup div. Perhaps something like this:
<a href="somelink.php"
onclick="return jq_confirm('Go to somelink.php?');">Click Here</a>
(Where jq_confirm is a custom JQuery confirm function that pops up a nice div with a YES/NO or OK/CANCEL button pair).
However, I cannot seem to find any such thing.
I have looked at some JQuery widget libraries etc which offer similar functionality, but none will wait for the response from the user (at least, not in the scenario described above), but instead they just proceed and take the user to the link (or run any JavaScript embedded in the href='' piece of the link). I suspect this is because while you can attach a callback function to many of these widgets to return a true/false value, the onclick event does not wait for a response (callbacks are asynchronous), thereby defeating the purpose of the confirm box.
What I need is the same kind of halt-all-javascript (modal) functionality that the default confirm() command provides. Is this possible in JQuery (or even in JavaScript)?
As I am not an expert in JavaScript nor in JQuery, I defer to you gurus out there. Any JQuery (or even pure JavaScript) solution is welcome (if possible).
Thanks -
I just had to solve the same problem. I wound up using the dialog widget from JQuery UI. I was able to implement this without using callbacks with the caveat that the dialog must be partially initialized in the click event handler for the link you want to use the confirmation functionality with (if you want to use this for more than one link). This is because the target URL for the link must be injected into the event handler for the confirmation button click.
Here's my solution, abstracted away to be suitable for an example. I use a CSS class to indicate which links should have the confirmation behavior.
<div id="dialog" title="Confirmation Required">
Are you sure about this?
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#dialog").dialog({
autoOpen: false,
modal: true
});
$(".confirmLink").click(function(e) {
e.preventDefault();
var targetUrl = $(this).attr("href");
$("#dialog").dialog({
buttons : {
"Confirm" : function() {
window.location.href = targetUrl;
},
"Cancel" : function() {
$(this).dialog("close");
}
}
});
$("#dialog").dialog("open");
});
}); // end of $(document).ready
</script>
<a class="confirmLink" href="http://someLinkWhichRequiresConfirmation.com">Click here</a>
<a class="confirmLink" href="http://anotherSensitiveLink">Or, you could click here</a>
Check out http://www.84bytes.com/2008/06/02/jquery-modal-dialog-boxes/
They have a good variety of modal-boxes for JQuery.
I think you should see http://www.ericmmartin.com/simplemodal/
A modal dialog override of the JavaScript confirm function. Demonstrates the use of onShow as well as how to display a modal dialog confirmation instead of the default JavaScript confirm dialog.
Did you see the jQuery Modal Dialog on jQuery UI site?
Modal Confirmation Dialog demo
I blogged about the solution to this issue here: http://markmintoff.com/2011/03/asp-net-jquery-confirm-dialog/
Even though the article is geared towards ASP.Net it can be easily adapted to php. It relies on preventing the click with a return false and when the user clicks "OK" or "YES" or what-have-you; the link or button is simply clicked again.
var confirmed = false;
function confirmDialog(obj)
{
if(!confirmed)
{
$( "#dialog-confirm" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Yes": function()
{
$( this ).dialog( "close" );
confirmed = true; obj.click();
},
"No": function()
{
$( this ).dialog( "close" );
}
}
});
}
return confirmed;
}
Give it a try and let me know what you think. I hope this solves your problem.
You should be able to override the standard window.confirm function be writing the following code.
window.confirm = modalConfirm
then you will need to make a function like this
function modalConfirm(message){
// put your code here and bind "return true/false" to the click event
// of the "Yes/No" buttons.
}
This should work, although I haven't tested it yet. I am going to do exactly this right now and will let you all know how it worked.
Edit:
I have tested my example above now and it was not possible, you will have to pass in a callback function to your overwritten confirm function like this:
function modalConfirm(message, callback){
...
$("button.yes").click(function(){
callback(result);
});
...
}
..making your call to the function look like this:
confirm("Are you sure?", function(result){
alert(result);
});
In other words, it is not possible to completely override the default window.confirm function without causing a nasty loop that causes the browser to hang. I think that you will have to modify your confirm calls like above.
Since this question seems to be missing the canonical answer: there is no way to programatically pause (and resume) javascript execution like alert or confirm do.
That being said, relying on this behaviour today is usually considered bad practice given the single threaded nature of javascript, and the reason why the aforementioned functions do pause execution is probably because they were designed when the web was still at a very early stage, and later left unchanged to ensure compatibility. Since the focus nowadays is in writing as much non-blocking js code as possible, it's unlikely the functionality to programmatically halt js will ever make it to any future specification of ECMAScript, so your best bet is to rework your site to make sure confirm and alert dialogs can co-exist with other javascript code running in the background.
My way around this problem was to add some arbitrary data to the object, and check for that data on click. If it existed, proceed with the function as normal, otherwise confirm with a yes/no (in my case using a jqtools overlay). If the user clicks yes - insert the data in the object, simulate another click and wipe the data. If they click no, just close the overlay.
Here is my example:
$('button').click(function(){
if ($(this).data('confirmed')) {
// Do stuff
} else {
confirm($(this));
}
});
And this is what I did to override the confirm function (using a jquery tools overlay):
window.confirm = function(obj){
$('#dialog').html('\
<div>\
<h2>Confirm</h2>\
<p>Are you sure?</p>\
<p>\
<button name="confirm" value="yes" class="facebox-btn close">Yes</button>\
<button name="confirm" value="no" class="facebox-btn close">No</button>\
</p>\
</div>').overlay().load();
$('button[name=confirm]').click(function(){
if ($(this).val() == 'yes') {
$('#dialog').overlay().close();
obj.data('confirmed', true).click().removeData('confirmed');
} else {
$('#dialog').overlay().close();
}
});
}
I have a solution that can be used to replace the default window.confirm function. It doesn't require you overriding window.confirm as that is not fully possible.
My solution allows you to have a general class like me, let's say 'confirm-action' that you place on any element that requires a confirmation before being processed. The script is very simple and utilizes jQuery, jQuery UI Dialog and no other plugins.
You can find the complete demo of the implementation on jsFiddle, http://jsfiddle.net/74NDD/39/.
Usage:
Add this javascript code in your html head or before any other click
binding you have in your javascript.
$("#dialog:ui-dialog").dialog("destroy");
$('.confirm-action').live('click', function(e) {
$self = $(this);
if (e && e.stopImmediatePropagation && $self.data('confirmed') !== true) {
e.stopImmediatePropagation();
$('#confirm-action-dialog').dialog({
height: 110,
modal: true,
resizable: false,
draggable: false,
buttons: {
'Yes': function() {
$(this).dialog('close');
$self.data('confirmed', true);
$self.click();
},
'No': function() {
$self.data('confirmed', false);
$(this).dialog('close');
}
}
});
} else if ($self.data('confirmed') === true) {
e = window.event;
e.cancelBubble = false;
$self.data('confirmed', false);
}
return false;
});
Place this html somewhere in the body (it is hidden by default).
<div style="display:none;" id="confirm-action-dialog" title="Confirm Action?">
<p>
<span class="ui-icon ui-icon-alert"></span>
Are you sure you want to continue?
</p>
</div>
Put the class 'confirm-action' on any element that requires confirmation.
confirm-action
This solution works perfect as it does not alter jQuery event bubbling, it merely pauses (stops) all other events until the user decides what they want to do.
I hope this is helpful for someone else as I was unable to find any other solution that doesn't require me installing another jQuery plugin or do some other hack.
Building on top of Banu's solution (thanks a ton!) to make it a one pop solution on top of each page. Paste this code inside:
$(document).ready
And add "confirmLinkFollow" class to all links you want confirmed:
$(".confirmLinkFollow").click(function(e) {
e.preventDefault();
var targetUrl = $(this).attr("href");
var $dialog_link_follow_confirm = $('<div></div>').
html("<p>Are you sure?</p>").
dialog({autoOpen: false,
title: 'Please Confirm',
buttons : {
"Confirm" : function() {
window.location.href = targetUrl;
},
"Cancel" : function() {
$(this).dialog("close");
}
},
modal: true,
minWidth: 250,
minHeight: 120
}
);
$dialog_link_follow_confirm.dialog("open");
});
Put the redirect inside the function like:
<script>
function confirmRedirect(url, desciption) {
if (confirmWindow(desciption)) {
window.location = url;
}
}
</script>
And call it like this:
Go!
Almost three years later, I am looking for something similar. Since I have not found an acceptable "quick" solution, I wrote something that comes very close to the criteria of the OP. I figure others may find it useful in the future.
JavaScript is event-driven and that means it does not support any sort of "wait" or "sleep" loop that we can use to pause a pure-javascript confirm function. The options involve burning processor cycles, using a browser plugin, or AJAX. In our increasingly mobile world, and with sometimes spotty internet connections, none of these are great solutions. This means that we have to return from our "confirm" function immediately.
However, since there is no "false" logic in the code snippet above (ie. nothing is done when the user clicks "Cancel"), we can trigger the "click" or "submit" event again when the user clicks "OK." Why not set a flag and react based on that flag within our "confirm" function?
For my solution, I opted to use FastConfirm rather than a "modal" dialog. You can easily modify the code to use anything you want but my example was designed to use this:
https://github.com/pjparra/Fast-Confirm
Due to the nature of what this does, I do not see a clean way to package it up. If you feel that this has too many rough edges, feel free to smooth them out or rewrite your code the way that everyone else has recommended:
/* This version of $.fn.hasEvent is slightly modified to provide support for
* the "onclick" or "onsubmit" tag attributes. I chose this because it was
* short, even if it is cryptic.
*
* Learn more about the code by Sven Eisenschmidt, which is licensed under
* the MIT and GPL at:
* http://github.com/fate/jquery-has-event
*/
(function($) {
$.fn.hasEvent = function(A, F, E) {
var L = 0;
var T = typeof A;
E = E ? E : this;
var V = (E.attr('on'+A) != undefined);
A = (T == 'string') ? $.trim(A) : A;
if (T == 'function')
F = A, A = null;
if (F == E)
delete(F);
var S = E.data('events');
for (e in S)
if (S.hasOwnProperty(e))
L++;
if (L < 1)
return V; // = false;
if (A && !F) {
return V = S.hasOwnProperty(A);
} else if(A && S.hasOwnProperty(A) && F) {
$.each(S[A], function(i, r) {
if(V == false && r.handler == F) V = true;
});
return V;
} else if(!A && F) {
$.each(S, function(i, s) {
if (V == false) {
$.each(s, function(k, r) {
if (V == false && r.handler == F)
V = true;
});
}
});
}
return V;
}
$.extend($, {hasEvent: $.fn.hasEvent});
}) (jQuery);
/* Nearly a drop-in replacement for JavaScript's confirm() dialog.
* Syntax:
* onclick="return jq_confirm(this, 'Are you sure that you want this?', 'right');"
*
* NOTE: Do not implement "false" logic when using this function. Find another way.
*/
var jq_confirm_bypass = false;
function jq_confirm(el, question, pos) {
var override = false;
var elem = $(el);
if ($.fn.fastConfirm == undefined) {
override = confirm(question);
} else if (!jq_confirm_bypass) {
if (pos == undefined) {
pos = 'right';
}
elem.fastConfirm({
position: pos,
questionText: question,
onProceed: function(trigger) {
var elem = $(trigger);
elem.fastConfirm('close');
if (elem.hasEvent('click')) {
jq_confirm_bypass = true;
elem.click();
jq_confirm_bypass = false;
}
if (elem.hasEvent('submit')) {
jq_confirm_bypass = true;
elem.submit();
jq_confirm_bypass = false;
}
// TODO: ???
},
onCancel: function(trigger) {
$(trigger).fastConfirm('close');
}
});
}
return override ? override : jq_confirm_bypass;
}
So... onclick="return confirm('Do you want to test this?');" would become onclick="return jq_confirm(this, 'Do you want to test this?');" The pos/"right" parameter is optional and is specifically for Fast-Confirm.
When you click, the jq_confirm() function will spawn the jQuery dialog and return "false." When the user clicks "OK" then jq_confirm() sets a flag, calls the original click (or submit) event, returns "true", then unsets the flag in case you want to remain on the same page.
The following link has a jQuery plugin for confirm boxes similar to constructing like confirm("something") in JavaScript
http://labs.abeautifulsite.net/archived/jquery-alerts/demo/
Related
I have written a Jquery-Ui Dialog to popup as a confirmation on particular links. This however does not redirect to my Delete page correctly. However if I open the debugger in chrome to debug, then the code works as expected.
I have found the same question, however the solution does not seem to work for me. It is exactly the same scenario though. Question here JavaScript redirect not working and works only in Chrome if debugger is turned on
So I have my link
<div id="confirm-dialog">
<div class="dialog-inner">
<p id="confirm-dialog-message"></p>
</div>
</div>
Delete
And I have my javascript
$('.confirmLink').click(function (e) {
BodyScrolling(false);
var theHref = $(this).attr("href");
var theTitle = $(this).attr("title") == null ? "Confirm..." : $(this).attr("title");
var theText = $(this).attr("data-confirm-message") == null ? "Are you sure?" : $(this).attr("data-confirm-message");
$("#confirm-dialog-message").html(theText);
$("#confirm-dialog").parent().css({ position: "fixed" }).end().dialog("open");
$("#confirm-dialog").dialog({
title: theTitle,
close: function() {
BodyScrolling(true);
},
buttons: [
{
text: "Yes",
class: "mws-button red",
click: function () {
$("#confirm-dialog").dialog("close");
window.location.href = theHref;
return false;
}
},
{
text: "No",
class: "mws-button black",
click: function () {
$("#confirm-dialog").dialog("close");
}
}]
});
return false;
});
So when I click my Delete link, I am indeed presented with my confirm dialog with Yes and No buttons, css styled correctly, and has captured the link href and bound it to the Yes button. If I click "No", I am kicked back and nothing further happens - Correct!
If I click Yes, it should take send me on to the original href that it captured. I have thrown alert(theHref) on the Yes Button click just before the redirect and it does show me the correct address (/Customer/Delete/73865878346587), but the redirect does not happen.
When I open the chrome debugger to debug the javascript or see if any errors occurred, then everything works as expected and redirects me correctly!
In IE, it does not work either.
I have tried...
window.location.href = theHref
window.location = theHref
location.href = theHref
$(location).attr('href', theHref)
I have also tried adding return false; after my redirect. Nothing works.
The link I added above to the same question said to make sure that the Yes button is being rendered on the page as a ... which mine is.
Can anyone shed any light?
Instead of window.location.href = theHref;
have you tried window.location.replace(theHref);?
Back to basics, try: window.location = theHref;
Well I have found the answer. Javascript was a red herring!
I did try to remove the confirmLink jQuery class so that the link was just a standard link that went straight to my controller to perofm my delete. When I did this test, the link worked perfectly. Therefore I denoted the problem be with my javascript. However, it seems that this was not quite the case and had only worked again if the Debugger in Chrome had been or was open at the time aswell.
When I revisited the non confirm link option again, I found this not to work properly, therefore denoting the problem not with the javascript.
It appears that you cannot perform a Delete action from a HTML Link in MVC. This is obviously because of security risks involved as anyone could perform a Delete on an Id. I had thought of this in my implementation and had added code to check where the Request had come from and if it wasn't from my List page, then it threw back an error and wouldn't perform the Delete. It didn't matter what I named my controller either, eg Test, the link performing my HTTP GET request would never hit this. There must be some algorithm that determines what the action is doing and stops you from performing the action on a HttpGet request. For more information about Delete Actions, check out this post http://stephenwalther.com/archive/2009/01/21/asp-net-mvc-tip-46-ndash-donrsquot-use-delete-links-because
It seems that you can only perform this by a HTTP Post, which means either using a Ajax.ActionLink or by using a Form and a submit button. Then your Action must be specified for HttpPost.
If, like me, you wish to keep your Link as a HTML Link, then you can do the following which is what I did, code below. I kept my HTML Link, set it up to point to my HttpPost Delete Action. Added my confirmLink class for jquery to bind my dialog box to. I pick up the link href and set the Yes button in the jquery dialog to dynamically create a Form and set the method to post and the action to the links href. Then I can call submit on the new dynamically created form to perform my Post to my Delete action.
My Delete Link
Html.ActionLink("Delete", "Delete", "Caterer", new { id = caterer.Id }, new { #class = "mws-ic-16 ic-delete imageButton confirmLink", #data_confirm_title = "Delete " + caterer.Name, #data_confirm_message = "Are you sure you want to delete this caterer, " + caterer.Name + "?" })
My Javascript
function LoadConfirm() {
$('.confirmLink').click(function (e) {
e.preventDefault();
BodyScrolling(false);
var actionHref = $(this).attr("href");
var confirmTitle = $(this).attr("data-confirm-title");
confirmTitle = confirmTitle == null ? "Confirm..." : confirmTitle;
var confirmMessage = $(this).attr("data-confirm-message");
confirmMessage = confirmMessage == null ? "Are you sure?" : confirmMessage;
$("#confirm-dialog").dialog({
autoOpen: false,
modal: true,
width: 400,
closeOnEscape: true,
close: function () { BodyScrolling(true); },
title: confirmTitle,
resizable: false,
buttons: [
{
text: "Yes",
class: "mws-button red",
click: function () {
StartLoading();
$(this).dialog("close");
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", actionHref);
form.submit();
}
},
{
text: "No",
class: "mws-button black",
click: function () {
$("#confirm-dialog").dialog("close");
return false;
}
}
]
});
$("#confirm-dialog #confirm-dialog-message").html(confirmMessage);
$("#confirm-dialog").parent().css({ position: "fixed" });
$("#confirm-dialog").dialog("open");
});
}
My Action
[HttpPost]
[Authorize(Roles = "User")]
public ActionResult Delete(long id)
{
//Perform my delete
return RedirectToActionPermanent("List");
}
I am working with a forum script (simple machines forum)
It is using this kind of javascript confirmation messages:
Remove
And I want to use jgrowl instead that... something like:
<a href="http://domain.net/index.php?action=deletemsg;topic=1.0;msg=1;c6c7a67=f9e1fd867513be56e5aaaf710d5f29f7" onclick="$.jGrowl('Remove this message?', { header: 'Confirmation', sticky: true });"/>Remove</a>
But... how to achieve true/false javascript return using jgrowl?
Can be this done in just one line?
Best regards!
luciano
edited to support using the href
you can't do it just like that because jGrowl will not be modal and block your page's behaviour.
However you could create a function for the code you want to execute after the choice was done, and then call it from within the notification
check this example http://jsfiddle.net/rcxVG/11/
html
<body>
link for 1<br>
link for 2<br>
Will we notify again<div id="will-notitfy-again">yes</div>
<br>
now... If you want to return then
click me
</body>
js
function startDemo(id)
{
$.jGrowl("to do not notify again click <a href='javascript:notFor("+id+")' onclick='closeNotif(this);'>here</a>!", { sticky: true });
}
function notFor(id){
alert("not anymore for "+id);
$("#will-notitfy-again").html("remember, notFor was hit for"+id);
}
function closeNotif(panel){
$(".jGrowl-notification").has(panel).find(".jGrowl-close").click();
}
var counter=0;
var confirmedAttr="data-confirmed";
function returnModal(field){
var $field=$(field);
if($field.attr(confirmedAttr)=="true"){
location.href=$field.attr("href");
}else{
counter++;
//save the element somewhere so we can use it (don't know if it has an unique-id)
$(document).data("id"+counter,$field);
$.jGrowl("click <a href='javascript:confirmClick("+counter+")' onclick='closeNotif(this);'>here</a> to go to google!", { sticky: true });
return false;
}
}
function confirmClick(variableId){
var $field=$(document).data("id"+variableId);
$field.attr(confirmedAttr,"true");
$field.click();
}
Let me know if this was good enought
Since jquery UI dialog does not support returning true/false, I need some other way to replace a javascript confirm.
It has to return true/false, so that my validation processes in javascript will run:
var where_to_coupon = confirm(pm_info_msg_013);
if (where_to_coupon== true) {
doSubmit=true;
return doSubmit;
The only way I know of doing that is passing a callback to the function.
The problem you face is that JQuery UI will not block the execution like confirm to wait for user input so you need to open the dialog and when the user clicks an answer act accordingly.
If you use Jquery UI dialog you can bind the callback functions to the buttons.
For instance:
myConfirm("Are you sure?", function(){ [YES CODE] }, function(){ [NO CODE] });
Your custom confirm will look like this:
var myConfirm = function(msg, yesAction, noAction){
$.dialog{
[CODE],
buttons: {
yes: yeasAction,
no: noAction
}
};
};
jQuery UI can do what you want, you simply have to adjust your code to work in an async way. Ariel Popovosky gave an answer which attempts to wrap a dialog call into a simple function call, and would work well but would require the same basic sync/async code modifications that any change from window.confirm would require.
Using window.confirm we use a synchronous way of doing things--program halts while user makes a decision. See example: http://jsfiddle.net/9jY7E/
Using UI's dialog, we simply move the behavior which should happen on confirm into the behavior assigned to one of the UI buttons. The dialog shows, and the program continues to run. But because you moved your "ok" code into the functionality bound to the button, that code doesn't run until the user clicks it. The following link is the same example I showed with window.confirm, but has been modified to use UI dialog: http://jsfiddle.net/9jY7E/1/
I don't know of any replacement for window.confirm which works just like window.confirm but allows for your own styling. All dialog systems I know of work somewhat similar to UI.
Additional: At the following link you will find a 3rd example of the same external link confirmation using the methodology Ariel gave in his answer: http://jsfiddle.net/9jY7E/2/
This is a little convoluted, but it works for me. It sets a "global" variable and tests that value to see if the dialog should be displayed.
I know it probably isn't the most efficient method.
The confirmIt funciton returns true or false.
The reason for the setTimeout("confirmItConfirmed=false;",500); near the end is to reset the variable so the next time the function is called it won't just return true.
Some browsers do better at handling the auto height and width than others.
The notice function is a replacement for alert and confirmIt replaces confirm.
<html>
<head>
<title>jQuery Confirm & Alert Replacements</title>
<link type=text/css href=http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/redmond/jquery-ui.css rel=stylesheet />
<script type=text/javascript src=https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js></script>
<script type=text/javascript src=https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js></script>
<script type=text/javascript>
var confirmItConfirmed = false;
var jq = $.noConflict();
function notice(message,title,height,width) {
if (!title)
var title = document.title+' says...';
jq('body').append('<span id=noticeDialogSpan style=display:none></span>');
jq('#noticeDialogSpan').html('<div id=noticeDialog title="'+title+'">'+message+'</div>');
if (!width)
var width = jq('#noticeDialogSpan').width()+40;
if (!height)
if (jq('#noticeDialogSpan').height() > jq(window).height()-100)
var height = jq(window).height()-100;
else
var height = 'auto';
jq('#navMenu').hide();
jq('#noticeDialog').dialog ({
height: height,
width: width,
modal: true,
close: function(event,ui) {
jq(this).dialog('destroy');
jq('#noticeDialog').remove();
jq('#noticeDialogSpan').remove();
jq('#navMenu').show();
},
buttons: {
'Close': function() { jq(this).dialog('close'); }
}
});
}
function confirmIt(e,message,title,height,width) {
if (!confirmItConfirmed) {
if (!title)
var title = document.title+' says...';
jq('body').append('<span id=confirmationDialogSpan style=display:none></span>');
jq('#confirmationDialogSpan').html('<div id=confirmationDialog title="'+title+'">'+message+'</div>');
if (!width)
var width = jq('#confirmationDialogSpan').width()+40;
if (!height)
if (jq('#confirmationDialogSpan').height() > jq(window).height()-100)
var height = jq(window).height()-100;
else
var height = 'auto';
jq('#navMenu').hide();
jq('#confirmationDialog').dialog ({
height: height,
width: width,
modal: true,
close: function(event,ui) {
jq('#confirmationDialog').remove();
jq('#confirmationDialogSpan').remove();
jq(this).dialog('destroy');
jq('#navMenu').show();
},
buttons: {
'Confirm': function() {
jq(this).dialog('close');
confirmItConfirmed = true;
e.click();
},
'Cancel': function() { jq(this).dialog('close'); }
}
});
}
setTimeout("confirmItConfirmed=false;",500);
return confirmItConfirmed;
}
function testIt(e) {
if (confirmIt(e,'Are you sure you want to continue?','My Title'))
notice('You clicked Confirm','My Title');
}
</script>
</head>
<body>
<br />
<br />
Click HERE to test a link.
<br />
<br />
Click this button to test it too <input value='Click Me' type=button onclick="testIt(this)" />
</body>
</html>
This could also be done using boopup + callbacks:
Boopup.confirm("This is a boopup confirm!", function(agree) {
console.log(agree);
})
https://github.com/petruisfan/boopup
Currently, I'm working to replace "alert'/"confirm" with the jquery dialog.
But most of legacy codes is written in some asynchronous way, which make it difficult to change. Is there any way to make jquery dialog work in a synchronous way? ( don't use loop or callback function )
For example:
function run()
{
var result = confirm("yes or no");
alert( result );
\\more codes here
}
In this example the alert and other codes will be executed after user's choice.
If we use jquery dialog
var result = $dialog.open()
It will continue to execute the alert, which is asynchronous.
Currently, my solution is to use call back function in the OK|Cancel function.
For example:
OK: function ()
{
$dialog.close();
alert("yes");
//more codes here
}
This method works but it is difficult to make all the synchronous codes become asynchronous, which requires a lot of change (see the following example). So I'm looking for the synchronous jQuery Dialog, is it possible??
For example: ( The real codes are much more complicated than the following example)
function f1()
{
if ( confirm("hello") ) f2();
alert("no");
}
function f2()
{
if( confirm("world") ) f3();
alert("no");
}
function f3()
{
return confirm("!") ;
}
Another example:
vendorObject.on('some-event', function() {
if(confirm("Do you really want to do that?")) {
return true;
}
else {
return false; // cancel the event
}
});
... here the vendor object fires an event, which has to be cancelled if the user confirms. The event can only be cancelled if the event handler returns false - synchronously.
The short answer is no, you won't be able to keep your code synchronous. Here's why:
In order for this to be synchronous, the currently executing script would have to wait for the user to provide input, and then continue.
While there is a currently executing script, the user is unable to interact with the UI. In fact, the UI doesn't even update until after the script is done executing.
If the script can't continue until the user provides input, and the user can't provide input until the script is finished, the closest you'll ever get is a hung browser.
To illustrate this behavior, debug your code and set a break point on the line following a line that changes the UI:
$("body").css("backgroundColor", "red");
var x = 1; // break on this line
Notice that your page background is not yet red. It won't change to red until you resume execution and the script finishes executing. You are also unable to click any links in your page while you've got script execution paused with your debugger.
There is an exception to this rule for alert() and confirm(). These are browser controls, and are treated differently than actual web page UI elements.
The good news is that it really shouldn't be very hard to convert your code. Presumably, your code currently looks something like this:
if (confirm("continue?")) {
// several lines of code if yes
}
else {
// several lines of code if no
}
// several lines of code finally
Your asynchronous version could create a function ifConfirm(text, yesFn, noFn, finallyFn) and your code would look very much the same:
ifConfirm("continue?", function () {
// several lines of code if yes
},
function () {
// several lines of code if no
},
function () {
// several lines of code finally
});
Edit: In response to the additional example you added to your question, unfortunately that code will need to be refactored. It is simply not possible to have synchronous custom confirmation dialogs. To use a custom confirmation dialog in the scenario where an event needs to either continue or cancel, you'll just have to always cancel the event and mimic the event in the yesFn callback.
For example, a link:
$("a[href]").click(function (e) {
e.preventDefault();
var link = this.href;
ifConfirm("Are you sure you want to leave this awesome page?", function () {
location.href = link;
});
});
Or, a form:
$("form").submit(function (e) {
e.preventDefault();
var form = this;
ifConfirm("Are you sure you're ready to submit this form?", function () {
form.submit();
});
});
I'm not exactly sure what the motivation behind not using callbacks is so it is hard to judge what solution might satisfy your requirements, but another way to delay execution is through jQuery's "deferred" object.
http://api.jquery.com/category/deferred-object/
You could set up a function that opens the jquery dialog and add code that "waits" for dialog to close. This ends up working in a fairly similar way to a callback in the case you've laid out but here is an example:
function confirm () {
var defer = $.Deferred();
$('<div>Do you want to continue?</div>').dialog({
autoOpen: true,
close: function () {
$(this).dialog('destroy');
},
position: ['left', 'top'],
title: 'Continue?',
buttons: {
"Yes": function() {
defer.resolve("yes"); //on Yes click, end deferred state successfully with yes value
$( this ).dialog( "close" );
},
"No": function() {
defer.resolve("no"); //on No click end deferred successfully with no value
$( this ).dialog( "close" );
}
}
});
return defer.promise(); //important to return the deferred promise
}
$(document).ready(function () {
$('#prod_btn').click(function () {
confirm().then(function (answer) {//then will run if Yes or No is clicked
alert('run all my code on ' + answer);
});
});
});
Here it is working in jsFiddle: http://jsfiddle.net/FJMuJ/
No, you can't do anything sync in Javascript (alert is breaking the rules, in fact). Javascript is built with "single threaded, async" in the core.
What you can do, though, is disable functionality of the underlying page (lightbox-like) so no event get triggered from the page until you don't take the dialog action, be it OK or Cancel. Thought this does not help you to get your sync code working. You have to rewrite.
Here's some ideas - what you actually want is to block your async event to make it look like sync. Here's some links:
Queuing async calls
Mobl
Narrative JavaScript
Hope this helps you further!!
To answer David Whiteman's more specific question, here's how I'm implementing a "deferred" postback for a LinkButton Click event. Basically, I'm just preventing the default behaviour and firing the postback manually when user feedback is available.
function MyClientClickHandler(event, confirmationMessage, yesText, noText) {
// My LinkButtons are created dynamically, so I compute the caller's ID
var elementName = event.srcElement.id.replace(/_/g, '$');
// I don't want the event to be fired immediately because I want to add a parameter based on user's input
event.preventDefault();
$('<p>' + confirmationMessage + '</p>').dialog({
buttons: [
{
text: yesText,
click: function () {
$(this).dialog("close");
// Now I'm ready to fire the postback
__doPostBack(elementName, 'Y');
}
},
{
text: noText,
click: function () {
$(this).dialog("close");
// In my case, I need a postback when the user presses "no" as well
__doPostBack(elementName, 'N');
}
}
]
});
}
You can use a real modal dialog.
[dialog] is an element for a popup box in a web page, including a modal option which will make the rest of the page inert during use. This could be useful to block a user's interaction until they give you a response, or to confirm an action.
https://github.com/GoogleChrome/dialog-polyfill
I don't really see why you are opposed to using Jquery callbacks to achieve the behavior in your example. You will definitely have to rewrite some code but something like:
function f1() {
$( "#testdiv" ).dialog({
modal: true,
buttons: {
"OK": function() {
$( this ).dialog( "close" );
f2();
},
Cancel: function() {
$( this ).dialog( "close" );
alert('no');
}
}
});
}
function f2() {
$( "#testdiv2" ).dialog({
modal: true,
buttons: {
"OK": function() {
$( this ).dialog( "close" );
f3();
},
Cancel: function() {
$( this ).dialog( "close" );
alert('no');
}
}
});
}
function f3() {
$( "#testdiv3" ).dialog({
modal: true,
buttons: {
"OK": function() {
$( this ).dialog( "close" );
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
}
<div id="testdiv" title="Hello"/>
<div id="testdiv2" title="World"/>
<div id="testdiv3" title="!"/>
I need to use the showModalDialog method to display a message to a user, which will also need to have two buttons, a "Yes" and "No" but unsure how to approach this method.
I am using IE8 and unsure how to declare this and how I need to assign this that will also cater for both "Yes" and "No" options.
If "No" is pressed, I basically want the showModalDialog closed, with no further action required by the user.
If "Yes" is pressed, I then want it to go off and call a JavaScript function.
I have looked online but I can't seem to find any examples relating to what I am after here.
I am seeking links to good examples that relates to my requirement above.
If you are using jQuery, then you would use it's powerfull widget library http://jqueryui.com
DEMO: http://so.devilmaycode.it/help-with-showmodaldialog-together-with-selections
IMPLEMENTATION:
$(function() {
var external_data = "i'm outside the func";
$('.show-modal-dialog').click(function(e) {
var internal_data = "i'm inside the call";
var a = this;
e.preventDefault();
$("#dialog-message").dialog({
title: 'this is a modal dialog',
modal: true,
open: function(event, ui) {
$(this).append(a.href); //append inside the Dialog it self
},
buttons: {
'Yes': function() {
alert(a.href + ' ' + external_data + ' ' + internal_data);
},
'No': function() {
$(this).dialog("close");
}
}
});
});
});
BODY:
<div id="dialog-message"><p>Lorem Ipsum Est</p></div>
<a class="show-modal-dialog" href="http://www.google.it">Show Modal Dialog</a>
If you are using jquery.ui you, checkout this sample. If you don't want to use jquery.ui, take a look at Block.UI plugin.