开发者

Disable buttons on post back using jquery in .net app

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>


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);
  });
});


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.


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


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.


Add this attribute to your button:

usesubmitbehavior="False"

This will insert something like the following into onclick:

javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$Main$Tabs$SaveTab$Cancel", "", true, "", "", false, false))

This code will cause a post back even if the button is disabled. Showing a confirmation dialog and allowing the post back to be cancelled gets a little more interesting:

    var click = $("[id$='_Cancel']")[0].onclick;
    $("[id$='_Cancel']")[0].onclick = null;
    $("[id$='_Cancel']").bind('click', function (event) { addFeeSchedule.onCancelClick(event) });
    $("[id$='_Cancel']").bind('click', click);

In order to prevent the post back from occurring immediately, remove the onclick code inserted by .net and bind it after your own function using jQuery. Use event.stopImmediatePropagation(), to prevent the post back:

onCancelClick: function (event) {

    var confirmResponse;

    confirmResponse = confirm('No fee schedule will be created.\n\nAre you sure you want to cancel?');

    if (confirmResponse == true) {

        showWait();
        event.target.disabled = 'true';

    } else {

        event.stopImmediatePropagation();

    }

},


The answer provided by Nick Craver is by far the best solution that I've found anywhere on the net. There is one situation, however, where the solution does not work well - when the form contains submit buttons within an UpdatePanel with it's UpdateMode property set to "Conditional" and/or ChildrenAsTriggers property set to false.

In these situations, the contents of the update panels are not automatically refreshed when the async postback has completed. So if these update panels contained any submit buttons then the given solution would effectively leave these buttons permanently disabled.

The following enhancement to the solution handles this problem by re-enabling the buttons after an async, or 'partial', postback:

var canProcessClicks = true;

if (typeof (Sys) != 'undefined') {
    // handle partial-postback
    var requestManager = Sys.WebForms.PageRequestManager.getInstance();
    requestManager .add_initializeRequest(function() {
        // postback started
        canProcessClicks = false;
    });
    requestManager .add_endRequest(function() {
        // postback completed
        canProcessClicks = true;
    });
}

$(function () {
    $('input[type=submit]').on("click", function () {
        return canProcessClicks ;
    });
    $("#aspnetForm").submit(function () {
        if (typeof (Sys) != 'undefined' && Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
            // this is an async postback so ignore because this is already handled
        } else {
            // full postback started
            canProcessClicks = false;
        }
    });
});


For this you have to use input button attribute disable all the controls

<script language="javascript" type="text/javascript">
    function MyDisableFunction() {
        alert(`Now You Postback Start`);
        $(":input").attr("disabled", true);
        return true;
    }

</script>

Fore more detail check this link

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜