Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use jQuery UI Dialog as "confirm before submit" dialog on ASP .NET form

I'm trying to take advantage of jQuery UI (or any other dialog plugin) in order to replace default Confirm dialog. There're plenty similar questions and answers on StackOverflow, for instance:

jquery dialog: confirm the click on a submit button

Yet, in ASP .NET I need something more.

Due to one form on the page constraint, on ASP .NET page (working with ASP .NET 3.5) I can have multiple buttons that submit the same form, and based on submitted header information Page knows which control (Button) triggered form submission, and correct method can be called on the server (method attached to Button's Click event).

If I use solution from other StackOverflow answers, for instance:

        buttons: {
            'Delete all items': function() {
                $(this).dialog('close');
                currentForm.submit();
            },
            'Cancel': function() {
                $(this).dialog('close');
            }
        }

no event handler will be called on PostBack. If I replace it with:

        buttons: {
            'Delete all items': function() {
                $(this).dialog('close');
                $buttonThatWasConfirmed.click();
            },
            'Cancel': function() {
                $(this).dialog('close');
            }
        }

it will result in endless modal dialog recursion. How to solve it in ASP .NET?

like image 631
dragonfly Avatar asked Oct 19 '12 15:10

dragonfly


4 Answers

As an option: use SubmitBehavior="false" for Button controls and place script below before form's closing tag:

<script type="text/javascript">
    var originalDoPostBack = __doPostBack;
    __doPostBack = function (sender, args) {
        $("#dialog").dialog({
            modal: true,
            title: "Confirm action",
            buttons: {
                Yes: function () {
                    $(this).dialog("close");
                    originalDoPostBack(sender, args);
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });
    };
</script>

If you want call confirmation explicitely only for particular buttons, you may use script below (may be placed in header)

function confirmPostBack(sender, args) {
    $("#dialog").dialog({
        modal: true,
        title: "Confirm action",
        buttons: {
            Yes: function () {
                $(this).dialog("close");
                __doPostBack(sender.name, args || "");
            },
            Cancel: function () {
                $(this).dialog("close");
            }
        }
    });
    return false;
}

<asp:Button runat="server" Text="Click Me" OnClientClick="return confirmPostBack(this)" />
like image 186
Yuriy Rozhovetskiy Avatar answered Nov 10 '22 04:11

Yuriy Rozhovetskiy


I had to solve this question a few months ago. I wanted to have multiple buttons on a form, maybe on a cancel button plus included in a templated repeater, and have all of them correctly ask for the appropriate confirmation and either submit the form or cancel based on the user action. The below control can be included on a form as many times as necessary. It inherits from System.Web.UI.WebControls.LinkButton and uses the control's PostbackEventReference to know which control to submit if confirmed. The control can easily inherit from System.Web.UI.WebControls.Button instead if you prefer. I chose to use a link button because it operates very much like the button web control but doesn't emit <input type=submit> which cannot be styled with icons using jQuery UI without using a control adapter.

/// <summary>
///     A <see cref="T:System.Web.UI.WebControls.LinkButton"/> with added jQuery UI functionality to provide a modal dialog box to cancel the form submit client side.
/// </summary>
/// <remarks>This class requires the inclusion of jQueryUI</remarks>
[DefaultProperty("Text")]
[ToolboxData("<{0}:jQueryUIConfirmedLinkButton runat=\"server\"></{0}:jQueryUIConfirmedLinkButton>")]
public class jQueryUIConfirmedLinkButton : LinkButton
{
    /// <summary>
    ///     Holds the postback event reference data so that the emitted client script can execute the postback if the user confirms the action.
    /// </summary>
    protected string eventReference = null;

    /// <summary>
    ///     Gets or sets the emitted dialog's ID attribute.
    /// </summary>
    /// <value>
    ///     The dialog's ID attribute.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("dialog")]
    [Localizable(true)]
    public string DialogCssID
    {
        get
        {
            String s = (String)ViewState["DialogCssID"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogCssID"] = value;
        }
    }

    internal protected string DialogID
    {
        get
        {
            return String.Format("{0}_{1}", this.ClientID, DialogCssID);
        }
    }

    /// <summary>
    ///     Gets or sets the content of the dialog. This can be plain text or HTML.
    /// </summary>
    /// <value>
    ///     The HTML or plain text content of the dialog.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("<p>Are you sure?</p>")]
    [Localizable(true)]
    public string DialogContent
    {
        get
        {
            String s = (String)ViewState["DialogContent"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogContent"] = value;
        }
    }

    /// <summary>
    ///     Gets or sets the title that will appear on the dialog.
    /// </summary>
    /// <value>
    /// The dialog's title.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("Confirm Action")]
    [Localizable(true)]
    public string DialogTitle
    {
        get
        {
            String s = (String)ViewState["DialogTitle"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogTitle"] = value;
        }
    }

    /// <summary>
    ///     Gets or sets the text that will appear on the confirmation button.
    /// </summary>
    /// <value>
    ///     The text that will appear on dialog's confirmation button.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("Yes")]
    [Localizable(true)]
    public string DialogConfirmButtonText
    {
        get
        {
            String s = (String)ViewState["DialogConfirmButtonText"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogConfirmButtonText"] = value;
        }
    }

    /// <summary>
    ///     Gets or sets the text that will appear on the dialog's rejection button.
    /// </summary>
    /// <value>
    ///     The text that appears on the dialog's rejection button.
    /// </value>
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("No")]
    [Localizable(true)]
    public string DialogRejectButtonText
    {
        get
        {
            String s = (String)ViewState["DialogRejectButtonText"];
            return ((s == null) ? String.Empty : s);
        }
        set
        {
            ViewState["DialogRejectButtonText"] = value;
        }
    }

    /// <summary>
    ///     Raises the <see cref="E:System.Web.UI.Control.Load" /> event. Emits the necessary client script for the control to function.
    /// </summary>
    /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        this.eventReference = Page.ClientScript.GetPostBackEventReference(this, string.Empty);
        Page.ClientScript.RegisterStartupScript(this.GetType(), string.Format("{0}{1}", this.ClientID, "-DialogScript"), this.GetClientScript(), true);
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(), string.Format("{0}{1}", this.ClientID, "-DialogShowScript"), string.Format("function {0}Confirm() {{$('#{0}').dialog('open');}}", this.DialogID), true);
        this.OnClientClick = String.Format("{0}Confirm();return false;", this.DialogID);
    }

    /// <summary>
    ///     Renders the contents of the control to the specified writer. Adds the dialog HTML container to the output stream.
    /// </summary>
    /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter" /> object that represents the output stream to render HTML content on the client.</param>
    protected override void RenderContents(HtmlTextWriter writer)
    {
        base.RenderContents(writer);
        writer.AddAttribute("id", this.DialogID);
        writer.RenderBeginTag("div");
        writer.Write(this.DialogContent);
        writer.RenderEndTag();
    }

    public override void RenderEndTag(HtmlTextWriter writer)
    {
        base.RenderEndTag(writer);
    }

    /// <summary>
    ///     Gets the client script.
    /// </summary>
    /// <returns>A string that will be output to the client as script</returns>
    private string GetClientScript()
    {
        return string.Format(@"$(function () {{

                            $('#{0}').dialog({{
                                autoOpen: false,
                                modal: true,
                                resizable: false,
                                buttons: {{
                                    '{1}': function () {{
                                        $(this).dialog('close');
                                        eval({2});
                                    }},
                                    '{3}': function () {{
                                        $(this).dialog('close');
                                    }}
                                }},
                                title: '{4}'
                            }});
                          }});", this.DialogID, this.DialogConfirmButtonText, this.eventReference, this.DialogRejectButtonText, this.DialogTitle);
    }
}
like image 44
Robb Vandaveer Avatar answered Nov 10 '22 05:11

Robb Vandaveer


I have used this lately, although it only works with a link button. You can style them (they're just anchors after all) to look like html buttons if you'd like.

js

$(function () {
    $("#confirmMe").click(function (e) {
        e.preventDefault();
        var $anchor = $(this);
        $("<div>Are you sure you want to do that?</div>").dialog({
            title: "Confirm",
            modal: true,
            buttons: {
                "Ok": function () {
                    window.location = $anchor.attr("href");
                },
                "Cancel": function () {
                    $(this).dialog("close");
                }
            }
        });
    });
});

.net markup (confirmMe_Click event will be raised if you click ok)

<asp:LinkButton Text="Open Me" runat="server" ID="confirmMe" 
    ClientIDMode="Static" onclick="confirmMe_Click" />
like image 28
ScottE Avatar answered Nov 10 '22 05:11

ScottE


Those are my two cents, that worked for my project:

    // Initialices the behaviour when the page is ready
    $(function() {
        // Sets the function to be called when the confirmation button is pressed          
        $('.jqConfirmacionBorrar').click(function(e) {
            // Prevents the default behaviour of the button
            e.preventDefault();
            // Gets the name of the button that was clicked
            var ControlClickedName = $(this).attr('name');
            // Sets up the dialog to be called, with some custom parameters.
            // The important one is to do the postback call when the confirmation
            // button ('Aceptar' in spanish) is clicked.
            $("#DivConfirmacion").dialog({
                width: 650,
                modal: true,
                draggable: true,
                autoOpen: false,
                buttons: {
                    'Cancelar': function() {
                        $(this).dialog('close');
                        return false;
                    },
                    'Aceptar': function() {
                        $(this).dialog('close');
                        __doPostBack(ControlClickedName, '');
                        return true;
                    }
                }
            });
            // Opens the dialog to propt the user for confirmation
            $('#DivConfirmacion').dialog('open');
        });
    });
like image 30
tomasofen Avatar answered Nov 10 '22 05:11

tomasofen