Thursday, January 17, 2008

Using AjaxControlToolkit ModalPopup Control to Show Confirmation Dialog Instead of Javascript "confirm" Popup Box

In previous blog post we created simple popup box behaving like javascript "alert" function.

This time I want to create universal confirm dialog. I suppose it will work like this:

1) Dialog should be shown from client script. We should be able to call it with javascript function.

2) Javascript function will take three parameters: button object that invoked the function, title - text that will appear as title of confirmation dialog, and html - text tat will appear inside popup dialog - html parameter will be the question or warning that the user will see inside confirmation box.

3) Confirmation dialog will have two buttons - Yes and No (OK/Cancel). Clicking on "No" will do nothing - confirmation dialog will just hide. Clicking "Yes" will post back the button that invoked confirmation dialog to the server, and the server will process event for that button.

The completed demo looks like:

image

You can see it online or download source code.

The trick with posting back a corresponding button works simple. When invoking javascript function responsible for showing dialog, we pass instance of a button object that invoked the function. This way we know the button.name property, and later we can post back the value to the server if user clicked "Yes".

To accomplish this task I created the following files:

Script.js:

/// --------------------------------------------------
/// mainScreen object
/// --------------------------------------------------
var mainScreen =
{
    mainModalExtender : null,           // modalExtender object on main page
    mainModalTitleSpan : null,          // title span object
    mainModalContentsDiv : null,        // div inside modal dialog
    pageTheme : "Default"
}

mainScreen.Init = function() {
    /// <summary>
    /// Initializes mainScreen variables
    /// </summary>
    this.mainModalExtender = $find('mbMain');
    this.mainModalTitleSpan = $get("spanTitle");
    this.mainModalContentsDiv = $get("mainModalContents");
};
mainScreen.ShowConfirm = function(_button,_title, _html) {
    /// <summary>
    /// Shows modal dialog with contents equal to _html
    /// </summary>
    /// <param name="_button">Button object</param>
    /// <param name="_title">Title of modal popup</param>
    /// <param name="_html">HTML that should be shown inside popup</param>
    this.currentButtonUID = _button.name
    this.mainModalTitleSpan.innerHTML = _title;
    this.mainModalContentsDiv.innerHTML = _html;
    this.mainModalExtender.show();
};
mainScreen.CancelConfirm = function() {
    /// <summary>
    /// Hides modal dialog 
    /// </summary>
    this.mainModalExtender.hide();
    this.currentButtonUID = null;
};
mainScreen.SubmitConfirm = function() {
    /// <summary>
    /// Hides modal dialog 
    /// </summary>
    if(this.currentButtonUID) {
        __doPostBack(this.currentButtonUID, "");
    }
    this.mainModalExtender.hide();
    this.currentButtonUID = null;
};


/// --------------------------------------------------
/// Page events processing
/// --------------------------------------------------

Sys.Application.add_load(
    applicationLoadHandler
    );
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
    endRequestHandler
    );
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
    beginRequestHandler
    );

function applicationLoadHandler() {
    /// <summary>
    /// Raised after all scripts have been loaded and 
    /// the objects in the application have been created 
    /// and initialized.
    /// </summary>
    mainScreen.Init()
}

function endRequestHandler() {
    /// <summary>
    /// Raised before processing of an asynchronous 
    /// postback starts and the postback request is 
    /// sent to the server.
    /// </summary>
    
    // TODO: Add your custom processing for event
}

function beginRequestHandler() {
    /// <summary>
    /// Raised after an asynchronous postback is 
    /// finished and control has been returned 
    /// to the browser.
    /// </summary>

    $get("resultDiv").innerHTML = 
        "<img src='App_Themes/"+
        mainScreen.pageTheme+
        "/Img/activity_small.gif'/>";
}

Default.aspx:

<%@ 
    Page 
    Language="C#" 
    AutoEventWireup="true"  
    CodeFile="Default.aspx.cs" 
    Inherits="_Default" 
    Theme="Default" %>

<%@ 
    Register 
    assembly="AjaxControlToolkit" 
    namespace="AjaxControlToolkit" 
    tagprefix="AjaxToolkit" %>

<!DOCTYPE html 
    PUBLIC "-//W3C//DTD 
    XHTML 1.0 
    Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    >

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>
        Using AjaxControlToolkit ModalPopup Control 
        to Show Confirmation Dialog Instead 
        of Javascript "confirm" Popup Box
    </title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager 
        EnablePageMethods="true" 
        ID="MainSM" 
        runat="server" 
        ScriptMode="Release"
        LoadScriptsBeforeUI="true">
        <Scripts>
            <asp:ScriptReference 
                Path="~/Scripts/Main.js" />
        </Scripts>
    </asp:ScriptManager>
    <div>
        This sample shows confirm dialog 
        when you click on any button on the page.
        If you confirm the query, 
        original button you clicked 
        will be posted back to the server
        using __doPostBack('button.UniqueID','') method.
        So you can process event as normally in the code behind code.
        <br />
        <br />
        <asp:UpdatePanel 
            runat="server" 
            ID="up"
            UpdateMode="Conditional"
            >
            <ContentTemplate>
                <div>
                    <asp:Button
                        runat="server"
                        ID="btn1"
                        Text="btn1" 
                        onclick="btn1_Click"
                        OnClientClick="
                        mainScreen.ShowConfirm(
                            this,
                            'Please confirm',
                            'Are you sure to submit &lt;b&gt;btn1&lt;/b&gt;?'
                        );
                        return false;"
                        />
                    &nbsp;
                    <asp:Button
                        runat="server"
                        ID="btn2"
                        Text="btn2" 
                        onclick="btn2_Click"
                        OnClientClick="
                        mainScreen.ShowConfirm(
                            this,
                            'Please confirm',
                            'Are you sure to submit &lt;b&gt;btn2&lt;/b&gt;?'
                        );
                        return false;"
                        />
                    &nbsp;
                    <asp:Button
                        runat="server"
                        ID="btn3"
                        Text="btn3" 
                        onclick="btn3_Click"
                        OnClientClick="
                        mainScreen.ShowConfirm(
                            this,
                            'Please confirm',
                            'Are you sure to submit &lt;b&gt;btn3&lt;/b&gt;?'
                        );
                        return false;"
                        />
                    &nbsp;
                    <asp:Button
                        runat="server"
                        ID="btn4"
                        Text="btn4" 
                        onclick="btn4_Click"
                        OnClientClick="
                        mainScreen.ShowConfirm(
                            this,
                            'Please confirm',
                            'Are you sure to submit &lt;b&gt;btn4&lt;/b&gt;?'
                        );
                        return false;"
                        />
                    &nbsp;
                    <!-- 
                        We set UseSubmitBehavior="false"
                        to have __doPostBack function present
                        in the scope of the page
                     -->
                    <asp:Button
                        UseSubmitBehavior="false"
                        runat="server"
                        ID="btn5"
                        Text="btn5" 
                        onclick="btn5_Click"
                        OnClientClick="
                        mainScreen.ShowConfirm(
                            this,
                            'Please confirm',
                            'Are you sure to submit &lt;b&gt;btn5&lt;/b&gt;?'
                        );
                        return false;"
                        />
                    <br /><br />
                </div>
                <div 
                    style="border: dashed 1px black; 
                        font-weight:bold;
                        height:20px;" 
                    id="resultDiv"
                    runat="server"
                    >
                    &nbsp;
                </div>
            </ContentTemplate>
        </asp:UpdatePanel>
        <br /><br />
        <br />
        <br />
        <asp:Panel 
            ID="MPanel" 
            runat="server" 
            Style="display: none">
            <table 
                class="mainModalTable" 
                cellpadding="0" 
                cellspacing="0">
                <tr>
                    <td 
                        class="mainModaTableTD">
                        <table 
                            class="mainModalInnerTable" 
                            cellspacing="0" 
                            cellpadding="0">
                            <tr>
                                <td 
                                    class="mainModalInnerTableTD">
                                    <table 
                                        border="0" 
                                        width="100%" 
                                        cellspacing="0" 
                                        cellpadding="4">
                                        <tr>
                                            <td 
                                                class="mainModalDraggablePanelTD">
                                                <asp:Panel 
                                                    CssClass="mainModalDraggablePanel" 
                                                    ID="MPD" runat="server">
                                                    <span 
                                                        class="mainModalTitle" 
                                                        id="spanTitle" 
                                                        Text="">
                                                    </span>
                                                </asp:Panel>
                                            </td>
                                            <td 
                                                align="right" 
                                                class="mainModalDraggablePanelCloseTD">
                                                    <asp:ImageButton 
                                                        SkinID="CloseModal" 
                                                        runat="server" 
                                                        ID="clB" />
                                            </td>
                                        </tr>
                                        <tr>
                                            <td 
                                            style="text-align:center"
                                                class="mainModalContentsTD" 
                                                colspan="2">
                                                <div 
                                                    id="mainModalContents">
                                                </div>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td 
                                                class="mainModalContentsTD" 
                                                align="center"
                                                colspan="2">
                                                <input
                                                    type="button"
                                                    value="Yes"
                                                    onclick="mainScreen.SubmitConfirm();"
                                                    class="btn btnYes"
                                                    />
                                                &nbsp;
                                                <input
                                                    type="button"
                                                    value="No"
                                                    onclick="mainScreen.CancelConfirm();"
                                                    class="btn btnCancel"
                                                    />
                                            </td>
                                        </tr>
                                    </table>
                                    </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </asp:Panel>
        <AjaxToolkit:ModalPopupExtender 
            ID="mpeModal" 
            runat="server" 
            PopupControlID="MPanel"
            TargetControlID="btnHid"
            BehaviorID="mbMain"
            BackgroundCssClass="modalBackground" 
            CancelControlID="clB"
            OnCancelScript="mainScreen.CancelConfirm();" />
        <asp:Button 
            runat="server" 
            ID="btnHid" 
            style="display:none;" />    
    </div>
    </form>
</body>
</html>

and CSS files.

Hope this helps.