Disable buttons on post back using jquery in .net app

11,613

Solution 1

I just wanted to add an additional resolution. We decided to just completely remove the button once it was clicked and replace it with some text.

To do this we did:

$(function () {
    $(".DisableButton").click(function () {
        $(this).hide();
        $(this).after('<p>Please Wait.  Retrieving information.  This may take up to 60 seconds.</p>');

    });
});

Note that this hides the button then injects some html after the buttons code. Hiding it allows .Net to go ahead and run the onclick handler during post back while removing it as a clickable thing on the screen.

Solution 2

You can do it a slightly different way, like this:

$(function () {
  $("#aspnetForm").submit(function () {
    $('input[type=submit]').click(function() { return false; });
  });
});

What this does is makes future clicks ineffective, basically making them do nothing. When you disable an input, it also removes the key/value pair from being submitted with the <form>, so your server-side action which is triggered by it doesn't work.

It's worth noting, in jQuery 1.4.3 you'll be able to shorten this down to:

$(function () {
  $("#aspnetForm").submit(function () {
    $('input[type=submit]').click(false);
  });
});

Solution 3

The approach of disabling the button before the submit has two effects: -

a) The button takes on the disabled appearance.

b) The button's value is not posted in the form parameters.

If the button's value is not being posted to the server, ASP.Net does not know which button was pressed and thus it does not run the relevent OnClick handler.

To verify add the following to your code behind

protected void Page_Load(object sender, EventArgs e)
{
    Response.Write("Load " + IsPostBack + "<br />");
    foreach (string s in Request.Form.AllKeys)
    {
        Response.Write(string.Format("s:'{0}' = {1}<br />", s, Request.Form[s]));
    }
}

And then run the page (both with J.S. to disable the buttons and without). If the button's value is not being posted to the server, ASP.Net does not know which button was pressed and thus it does not run the relevent OnClick handler.

Solution 4

Just another observation. Alternatively, you can lock UI with a nice overlay busy message.

The Mark-up part:

$(function() { // when document has loaded

    ($.unblockUI); //unlock UI

    //Show busy message on click event and disable UI
    $('#btnHelloWorld').click(function() {
    $.blockUI({ message: '<h4><img src="busy.gif" />Please wait...</h4>' });

    });

});

<asp:Button ID="btnHelloWorld" runat="server" Text="Hello World" /><br/>

The Code behind:

   Protected Sub btnHelloWorld_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnHelloWorld.Click
        Label1.Text = "Hello World"
        Threading.Thread.Sleep(5000)
    End Sub

Check out jQuery BlockUI Plugin

Share:
11,613

Related videos on Youtube

NotMe
Author by

NotMe

Giving advice and other "help" because, well, why not?

Updated on April 22, 2022

Comments

  • NotMe
    NotMe about 2 years

    I have a asp.net app that I want to disable the buttons as soon as they are clicked in order to prevent multiple submissions. I'd like to use jquery for this as the site already liberally uses it anyway.

    What I've tried is:

    $(document).ready(function () {
        $("#aspnetForm").submit(function () {
            $('input[type=submit]', $(this)).attr("disabled", "disabled");
        })
    });
    

    The above will disable the button, and the page submits, but the asp.net button on click handler is never called. Simply removing the above and the buttons work as normal.

    Is there a better way? Or, rather, what am I doing wrong?

    UPDATE Okay, I finally had a little time to put a very simple page together.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SubTest.aspx.cs" Inherits="MyTesting.SubTest" %>
    
    <!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></title>
        <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            $(function () {
                $("#form1").submit(function () {
                    $('input[type=submit]', $(this)).attr("disabled", "disabled");
                });
            });
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
            <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button 2" />
        </div>
        </form>
    </body>
    </html>
    

    The code behind looks like:

    using System;
    
    namespace MyTesting {
        public partial class SubTest : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            if (IsPostBack) {
                // this will execute when any button is pressed
                Response.Write("postback");
            }
        }
            protected void Button1_Click(object sender, EventArgs e) {
            // never executes
                System.Threading.Thread.Sleep(1000);
                Response.Write("Button 1 clicked<br />");
            } // method::Button1_Click
    
            protected void Button2_Click(object sender, EventArgs e) {
            // never executes
                System.Threading.Thread.Sleep(1000);
                Response.Write("Button 2 clicked<br />");
            } // method::Button2_Click
        }
    }
    

    When you click on a button it obviously disables the buttons, but NEITHER of the button clicks are run.

    Rendered HTML

    <!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><title>
    
    </title>
        <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            $(function () {
                $("#form1").submit(function () {
                    $('input[type=submit]', $(this)).attr("disabled", "disabled");
                });
            });
        </script>
    </head>
    <body>
        <form name="form1" method="post" action="SubTest.aspx" id="form1">
    <div>
    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTcxODU4OTc0MWRkParC5rVFUblFs8AkhNMEtFAWlU4=" />
    </div>
    
    <div>
    
        <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKB57WhCAKM54rGBgK7q7GGCC6LlWKFoij9FIBVuI0HOVju/fTy" />
    </div>
        <div>
            <input type="submit" name="Button1" value="Button" id="Button1" />
            <input type="submit" name="Button2" value="Button 2" id="Button2" />
        </div>
        </form>
    </body>
    </html>
    
  • NotMe
    NotMe almost 14 years
    I'm running 1.4.2 right now. the first one doesn't seem to stop multiple button presses;
  • Nick Craver
    Nick Craver almost 14 years
    @Chris - Can you post your markup? Are you using submit buttons or possibly links as well?
  • Nick Craver
    Nick Craver almost 14 years
    @Chris - can you post the rendered html? That's all the javascript's going to care about :)
  • NotMe
    NotMe almost 14 years
    @Nick: rendered version is up.
  • Chris Fewtrell
    Chris Fewtrell almost 14 years
    I have tried Nick's solution and it does work (in chrome and FF 3.6)
  • NotMe
    NotMe almost 14 years
    I'm upvoting and accepting this answer as the only viable solution. Setting a button to disabled screws with asp.net's post back mechanism. However, if I combine the answer here with a step that changes the css class of the button to grey it out, then it achieves basically the same effect. Thanks
  • NotMe
    NotMe almost 14 years
    +1 This was my finding exactly. As you said, it's an interesting gotchya.
  • NotMe
    NotMe about 13 years
    Interesting approach. I'll have to try this.
  • viplove
    viplove about 10 years
    Thanks, this was the simplest answer I've seen yet.