views:

1351

answers:

8

I have a standard ASP.NET 2.0 web page with a Delete button on it. What I need and can't figure out how to pull off is when the user presses the delete button a confirm dialog popups asking the user "are you sure?". If the user says yes then I want to disable the delete button and perform a postback that will run the server side code deleteButton_Click.

Here is the tag:

<asp:Button ID="deleteButton" Text="Delete" OnClick="deleteButton_Click" runat="server" />

Here is the javascript (in jquery) to handle the client side click:

var deleteButton = $(input.eq(0));
deleteButton.click( function()
{
    var a = confirm( "Are you sure you want to delete this item?" );
    if ( a == false )
    {
     return false;
    }
    else
    {
     deleteButton.attr( "disabled", "disabled" );
     __doPostBack( deleteButton.attr( "id" ), "" );
    }
} );

The confirm dialog works as expected and the disabling works ok too. The form does postback fine but it does not run the deleteButton_Click event handler. The __doPostBack javascript code does exist on the page.

I could add UseSubmitBehavior="false" to the deleteButton tag but then it would ignore the confirm dialog answer.

So maybe I'm asking too much of ASP.NET here. Any ideas how to make this work?

Thanks,

Craig

+1  A: 

Take a look at this StackOverflow question I found it very useful:

http://stackoverflow.com/questions/106509/disable-button-on-form-submission/106958#106958

Add the confirm logic... and you should be set...

I went a head and wrote an extension method for you, and me as well :)

public static void ConfirmThenDisableButtonOnClick(this Button buttonControl, string confirmMessage, string clientFunction)
{
    StringBuilder sb = new StringBuilder();

    // If the page has ASP.NET validators on it, this code ensures the
    // page validates before continuing.
    if (buttonControl.CausesValidation && !String.IsNullOrEmpty(buttonControl.ValidationGroup))
    {
        sb.Append("if ( typeof( Page_ClientValidate ) == 'function' ) { ");
        sb.AppendFormat(@"if ( ! Page_ClientValidate('{0}') ) {{ return false; }} }} ", buttonControl.ValidationGroup);
    }

    //pop confirm, if confirm==true, disable button
    sb.AppendFormat("if(confirm('{0}\')){{this.disabled=true;", confirmMessage.Replace("\"","").Replace("'",""));

    // If a secondary JavaScript function has been provided, and if it can be found,
    // call it. Note the name of the JavaScript function to call should be passed without
    // parens.
    if (!String.IsNullOrEmpty(clientFunction))
    {
        sb.AppendFormat("if ( typeof( {0} ) == 'function' ) {{ {0}() }};", clientFunction);
    }

    // GetPostBackEventReference() obtains a reference to a client-side script function 
    // that causes the server to post back to the page (ie this causes the server-side part 
    // of the "click" to be performed).
    sb.Append(buttonControl.Page.ClientScript.GetPostBackEventReference(buttonControl, ""));

    // if confirm==false do nothing
    sb.Append(";}else{return false;}");

    // Add the JavaScript created a code to be executed when the button is clicked.
    buttonControl.Attributes.Add("onclick", sb.ToString());
}

just added validation checking as well :)

BigBlondeViking
Thank you but I have looked at that post. However it does not address the confirm dialog issue.
Craig
You could reduce the JavaScript to one line: return confirm('Are you sure?');
Ian Oxley
Take a look at my answer.
roosteronacid
still like mine, as i take into account Validation, if i had more than 2-3 buttons on a page that needed this, i would say a jQuery solution would be more appropriate( if it took into account validation).
BigBlondeViking
A: 

Javascript:

deleteButton.disabled = true;

C#:

deleteButton.Enabled = false;
Theofanis Pantelides
+1  A: 
btnSubmit.Attributes.Add("onclick", "if(confirm(\"Are you sure you want to delete this item?\" ){this.disabled=true;" + ClientScript.GetPostBackEventReference(btnSubmit, "").ToString() + "}else{return false;}");
George
A: 

You should probably disable the button on the server side in the deleteButton_Click event (because you will do a postback, so you recreate the page).

<asp:Button ID="deleteButton" Text="Delete" OnClick="deleteButton_Click" runat="server" OnClientClick="javascript:return confirm('are you sure blah blah blah ...')" />

And in the code-behind:

private void deleteButton_Click(object sender, EventArgs e) {
    deleteButton.Enabled = false;
    // and the rest of event handling ...
}
ppiotrowicz
if you have deleted something, i don't think you would re-render the page with that data there... not sure i would need to disable server side...
BigBlondeViking
You're right, but maybe he's keeping that data in ViewState.
ppiotrowicz
A: 

It's a little odd that the click event isn't firing. I would've guessed it was due to the button being disabled but usually that only happens when the button is disabled on the server, not just the client. While not the ideal solution in your Page_Load function you can check for an postback and/or async postback and determine the target of the postback (in this case its your button), and then call some method from there. You can also pass in arguments using the __doPostBack() function.

illvm
A: 

Initially, I wasn't sure if you were talking about the client side click event OR the server side click event. I think you should explicitly state that the server side click event is not firing.

Anyway, try <%@ Page EnableEventValidation="false" %> on your ASPX page and see if it works (It is set to true by default). I don't remember the nitty-gritty of this attribute works but this feature makes sure that the server side event is fired only in legitimate cases. E.g. let's say your page had XSS vulnerability and a hacker injected JavaScript to invoke the delete button. This attribute helps prevent those attacks.

SolutionYogi
+1  A: 

Thanks for the feedback but it was a fairly simple solution.

The javascript line should be:

__doPostBack( deleteButton.attr( "name" ), "" );

instead of:

__doPostBack( deleteButton.attr( "id" ), "" );

I didn't realize that the "name" attribute is the one that doPostBack method was looking for.

Craig
A: 
$(":submit").click(function ()
{
    $(this).attr("disabled", true); // disable input

    if (confirm("Press OK to submit"))
    {
        __doPostBack(this.id, ""); // if user presses OK; submit
    }
    else
    {
        // If user presses cancel; enable input and stop submit
        $(this).attr("disabled", false);

        return false;
    }
});
roosteronacid