Using the jQuery UI Dialog widget for confirmation windows

In our web applications, we often have the need to confirm with the user whether or not they want to proceed with an action they attempted to take. For instance, we might have a delete button on our form that responds to a user click by deleting a record in the database. Before we actually do the delete, we want to double-check with the user first. JavaScript has a confirm(msg) function that will display a standard dialog window that you can use to determine whether or not to continue with an action. The standard dialog window looks like the following (in IE): 

The standard confirm window is not very flexible. First, you only get two buttons (and no more), Ok and Cancel, and you can't change the text of either button. Second, you can't change the title on the title bar. You also can't change the question mark icon inside of the dialog. If you need something more flexible, you're going to have to create your own modal overlay window and recreate the functionality that confirm() gives you. Fortunately, jQuery UI has a dialog widget that will get you most of the way there:

 

As you can see, this dialog window definitely doesn't look like the standard confirm. First, I have more than two buttons and with different text. I also have a different title. It can be resized and repositioned. Also, although you can't see it, this dialog window can have the same visual effects (like applying semi-transparent overlays on everything underneath the window) applied to it that can be applied to other html elements by using jQuery. This would not be possible with the standard confirm. I won't bore you with the details of how to set this up. The documentation on the jQuery site sufficiently explains that. What I want to concentrate on is showing you how to make the jQuery dialog widget behave exactly like the standard JavaScript confirm.

When using the standard confirm, all processing stops until the user clicks on either Ok or Cancel in the window. That means that if the button was supposed to post back to the server, the postback won't occur until a selection is made. Usually, we only go ahead with the postback if the Ok button was clicked. This is typically handled by adding something similar to the OnClientClick event handler on our button:

<asp:Button ID="Button1" runat="server" Text="JavaScript" OnClick="Click" OnClientClick="return confirm('Dude, are you sure?');" />

If the user clicked the Ok button, true would be returned by the confirm(msg) function. If the user selected Cancel, false would be returned. Returning false in OnClientClick will effectively cancel the rest of the event processing (i.e., the event handler for the OnClick event won't be triggered).

Now, for the jQuery dialog, this is how I have the button:

<asp:Button ID="Button2" runat="server" Text="jQuery" OnClick="Click" OnClientClick="showjQueryDialog();return false;" />

I call a client-side function showjQueryDialog() which, amazingly enough, handles showing my jQuery dialog (pre-configured in the document ready event handler). After the call to showjQueryDialog(), I go ahead and just return false. The reason why I have to return false here is because, unlike the confirm() function, the browser doesn't stop processing the rest of the client-side script just because the dialog widget is opened. So we have to manually stop it. Now this raises an issue. So if we always return false, how will our event handler for the OnClick event ever be executed? In order for that event handler to execute, we will need to do the postback ourselves. There are a couple of ways to handle this but this is the approach I take:

1. Create a hidden field on the form (called hdnBtnPostback) who's value will be the exact postback function call I need to make in order to emulate the same postback that would occur had the button processing continued. This value can be set in the Page_Load() of the ASP.NET page. But how do we know what the exact postback function call should be? Fortunately for us, that is one of the methods available from the ClientScriptManager object. So the following code will do the trick:

 

this.hdnBtnPostback.Value = Page.ClientScript.GetPostBackEventReference(Button2, string.Empty);

 

This is will generate the exact same call to the __doPostBack() JavaScript function that is generated by the button. 

2. In the event handler for my dialog's Ok button click, all I have to do then is get the value of this hidden field and pass it to the JavaScript eval() function. This will effectively execute the postback and the event handler for the OnClick event will be processed: 

    1    function showjQueryDialog() {

    2 

    3       $("#dialog").dialog("open");

    4    }

    5 

    6    //document on ready.

    7    $(function(){

    8       $("#dialog").dialog({

    9          autoOpen: false,

   10          modal:true,

   11          buttons : {

   12             "Yes" : function() {              

   13                $(this).dialog("close");

   14                eval($("#<%= hdnBtnPostback.ClientID %>").val());

   15             },

   16             "No" : function() {

   17                $(this).dialog("close");

   18             },

   19             "Maybe": function() {

   20                $(this).dialog("close");

   21                //what should we do when "Maybe" is clicked?

   22             }        

   23          }

   24       });

   25    });

The event handler for the Yes button in the dialog are on lines 12-15. Line 14 is where we actually do the postback manually. 

As you can see, it is quite easy to replace the standard confirm dialog and make it function in the same way. All that is needed is a little elbow grease :).

Comments (26) -

Pierre Boucher
Pierre Boucher
4/24/2009 8:42:56 AM #

Very useful article.  You described the proper syntax for opening a jQuery dialog that is just perfect for a newbie with this framework.  You're the first link that actually use the open syntax $("#dialog").dialog("open"); which makes the dialog reusable in the page.  The rest of the information will be useful as well in the future.

Thanks!

bart_tubalinal
bart_tubalinal
4/27/2009 3:56:56 PM #

Glad you found it useful, Pierre.

Gcobani
Gcobani
7/3/2009 4:27:25 AM #

Hi, I'm trying to use your concept as explained above but I have no luck in deploying jquery into my wss3.0 environment, mind you I'm working with application pages(ascx and aspx) pages under 12 hive.....If you dont mind detailing how did you go about deploying and refferencing jquery scripts in you pages (an example would be nice)

Please help!!

Thanks

robert fang
robert fang
7/22/2009 3:16:50 PM #

Very useful article. thank you.

bart_tubalinal
bart_tubalinal
8/11/2009 3:43:23 AM #

Gcobani,

Please see www.deviantpoint.com/.../...-menu-with-jQuery.aspx. There is a comment I posted there on how to deploy the jQuery scripts. The only difference for you will be that the master page you'll want to modify is the application.master page since you said you created application pages. By default, application pages use the application.master page rather than default.master.

BXT

colin
colin
11/16/2009 9:35:28 AM #

That is soooooo helpful! Thanks!

I dinked around, and ended up doing it slightly different. I'll put the code here, in case you find it useful... Mine ended up being a little different. I wanted the user to enter in a message to post inside of the dialog.

I added 2 "data" pieces.
--1) When a button is clicked it checks it's IsConfirmed flag to see if it is already confirmed.
--2) When a button is clicked, it sets itself as the "button" for the dialog, so that the dialog can click back to it.

It seems to work on firefox/ie.

Let me know your thoughts... Smile

===============

<script type="text/javascript">
    function openDialog(event){
        if (!$(this).data("IsConfirmed")){
            $("#dialog").data("button", this);
            $("#dialog").dialog('open');
        return false;
    } else {
        $(this).data("IsConfirmed", false);
        return true;
    }
    }
    
    $(function() {
        $("#dialog").dialog({
          bgiframe: true,
          resizable: false,
          modal: true,
          autoOpen: false,
          overlay: {
            backgroundColor: '#000',
            opacity: 0.5
          },
          buttons: {
            'Add Note': function(event) {
              $(this).dialog('close');
              var button = $(this).data("button");
              $(button).data("IsConfirmed",true);
              button.click();
            },
            Cancel: function() {
              $(this).dialog('close');
            }
          }
      });

        $(".DialogInput").data("IsConfirmed",false).bind("click",{ }, openDialog);
    });
</script>

<div id="dialog" title="Add Note">
<p>
    <asp:TextBox ID="txtNote" runat="server" Rows="5" Columns="40" TextMode="MultiLine"></asp:TextBox>
</p>
</div>
<table width="100%">
<tr>
    <td>
        <asp:LinkButton ID="btnAddNote" runat="server" Text="Add Note" CssClass="DialogInput" OnClick="btnAddNote_Click" />
    </td>
    <td align="right">
        <asp:LinkButton ID="btnAddNotePrivate" Visible="false" runat="server" Text="Add Private Note" CssClass="DialogInput" OnClick="btnAddNotePrivate_Click" />
    </td>
</tr>
</table>

seguro de coche
seguro de coche
11/26/2009 8:51:45 PM #

jQuery widgets are great to use.I am having some problems loading them.

dgd
dgd
12/9/2009 2:59:09 PM #

Beautiful, thanks for posting.

Claire
Claire
12/18/2009 4:00:28 PM #

aaahh!! Thankyou, thankyou for saving me from a hair pulling moment.  I knew there had to be a simple elegant way to to this & this is it.

Jeff
Jeff
1/21/2010 2:44:51 PM #

Great post....I've been struggling with the jquery ui dialog for a bit, until now...one question though...how would I load a .aspx page within the dialog, allow user to enter data, and, after user closes the dialog, refresh the data on the original page? I'm messing around with iFrames, but that seems a little cludgy.  The link you reference is no longer available...thanks!

Kevin
Kevin
1/22/2010 9:52:39 AM #

Woah nice! Thanks for this. I ran into this scenario and needed a fast fix. I couldn't get eval($("#<%= hdnBtnPostback.ClientID %>").val()); to work (not sure why) but I managed to get this to work instead:

1) declare a protected string in the code behind file, ex: protected string hiddenFieldPostback = string.Empty;
2) in the page load set hiddenFieldPostback = Page.ClientScript.GetPostBackEventReference(btnSaveGadgetChanges, string.Empty);
3) build a javascript function like this to perform the postback:
    function DoHiddenFieldPostBack() {
        <%= hiddenFieldPostback %>
    }

Seemed to work for me.

Thanks again for the post.

Simon
Simon
2/4/2010 4:39:37 PM #

Thank for your information.  It is great and it works for most of the Confirmation.  However, I find some problems when I deploy this approach into Gridview (ASP.NET) delete button.  How can I write
"this.hdnBtnPostback.Value = Page.ClientScript.GetPostBackEventReference(Button2, string.Empty);"
where Button2 is within Gridview.

I had tried to write a button outside Gridview, it works but the program treat it as I click the dummy button, not the row deletion.  My Delete routine is not fired.
I would like to replace JavaScript Return Confirm.  Once it is confirm yes, it will continue my main flow and fire the delete routine.

Best regards

Simon

russ
russ
3/9/2010 5:23:59 PM #

Thanks for this.. Was about to embark on something very similar, good to see you've already got a working solution.

Thirupathi
Thirupathi
4/8/2010 8:03:55 PM #

I have wrote the ShowMsg() in Js file, in which I have passed the Title and Message to show the information to user like (Record Added successfully, Record Updated successfully) through the model dialog box. Just I can able to show the message only by using this method. In this method, I have to create the Model dialog box. I have faced a problem. If I want to delete a record, I have to ask the confirm message to user to delete the record. If User clicks the Continue button, we have to remove the record otherwise we have to close this dialog box. Here we are unable to get the return the dialog result. Please let me know what we have to do for this issue. I have shown my function below.

function ShowMsg()
{
    if($('#sd_hidden_msg').length > 0)
    {
        if($('#sd_hidden_msg').val()!="")
        {
            var ShowMsg;
            var strMsgTitle=$('#sd_hidden_msg').val();
            if (strMsgTitle=='Success')
            {
                ShowMsg='New record has been successfully added.';
            }
            else if(strMsgTitle=='Error')
            {
                ShowMsg='Duplicate record found. <br/> Make the necessary changes and update again, edit the existing record.';
            }
            else if(strMsgTitle=='Confirm')
            {
                ShowMsg='Delete this record?';
            }
            else if(strMsgTitle=='ConfirmSuccess')
            {
                strMsgTitle='Success';
                ShowMsg='Record deleted successfully.';
            }
            else if(strMsgTitle=='Update')
            {
                ShowMsg='Record updated successfully.';
            }

            var dialogContainer = $('<div></div>').attr('title',strMsgTitle);
          dialogContainer.append('<p style="margin: 5px 0;">'+ShowMsg+'</p>');
          dialogContainer.dialog({
            resizable: false,
            modal: true,
            autoOpen: true,
            close: function() {
              $(this).dialog('destroy').remove();
              },
            buttons: {
              Ok: function() {
                   $('#form1')[0].submit();
                $(this).dialog('close');
              }}
            });
        $('#sd_hidden_msg').val('');
        }
    }
    };

Adrian
Adrian
4/15/2010 6:23:56 AM #

Genius! Thanks for this Bart, it works a treat and manually generating a postback is a great tip.

Craig
Craig
8/10/2010 1:51:19 AM #

Great tip, will be getting well used! Smile

Eswar.D
Eswar.D
9/9/2010 8:20:35 AM #

nice, we can use $("Button1").click(); to raise button's click event on the dialog's ok.
cheers!

Eswar.D
Eswar.D
9/9/2010 8:22:33 AM #

No, I was wrong......$("Button1").click(); will again call the dialog.....hahahahaha
me....idiot....

Irish Whistler Working
Irish Whistler Working
10/1/2010 10:43:46 AM #

Brilliant post! You helped me a lot. Thanks so much Smile

Ali
Ali
3/16/2012 10:39:02 PM #

Very much thanks for your help, i used your code with some modifications and it is working great

squiel
squiel
5/22/2012 11:17:18 PM #

thanks

squiel
squiel
5/22/2012 11:17:37 PM #

thanks

JCru
JCru
10/29/2012 6:27:51 AM #

Thanks for this. I used this combined with Mark Mintoff's solution and cleaned it up a little bit. Rather than using a hidden field and setting it's value in the code-behind page, you can just use some asp.net code in the callback for the Yes button, like so:
<%= Page.ClientScript.GetPostbackEventReferences(this.myBtn, string.Empty %>

samuel
samuel
2/6/2013 4:20:59 AM #

Thanks!

samuel
samuel
2/6/2013 4:21:20 AM #

Thanks!

Jongmin
Jongmin
3/1/2013 1:45:45 AM #

It is very helpful for me... Thanks.

Pingbacks and trackbacks (2)+

Add comment

biuquote
  • Comment
  • Preview
Loading

About the author

Bart X. Tubalinal is a Solutions Architect with over 10+ years experience in building enterprise applications. He also considers himself to be, pound for pound, one of the best developers there is.

Archives

Comments

Comment RSS