I have a button that I would like to disable when the form submits to prevent the user submitting multiple times.
I have tried naively disabling the button with java
Disable the button at the very end of your submit handler. If the validation fails, it should return false before that.
However, the JavaScript approach is not something that can be relied upon, so you should have something to detect duplicates on the server as well.
Set the visibility on the button to 'none';
btnSubmit.Attributes("onClick") = document.getElementById('btnName').style.display = 'none';
Not only does it prevent the double submission, but it is a clear indicator to the user that you don't want the button pressed more than once.
Came across rp's code in a legacy app of ours which was struggling with some crazy behaviour.
Tracked it down to a strange combination of event firing - when DisableButtonOnClick() was being used on an asp button inside an UpdatePanel, the POST would be sent twice (once by the doPostBack added by DisableButtonOnClick(), and once by the UpdatePanel). However, this only happened with some browsers (early versions of Edge, but not recent ones, and IE11 did this, Chrome and FireFox did not (at least the versions I tested with)). I presume Chrome and newer versions of Edge are dealing with this scenario internally in some way. Tracking the issue with F12 devtools in IE - the two POSTs happen so closely together that the first one gets immediately ABORTED, but under some conditions (network latency, user machine load, etc) the request does get through to the server before the browser can abort. So this results in a seemingly random double-post coming from button presses throughout the system, and it was a pain to trace back. The fix is to add a "return false;" after the doPostBack to prevent the UpdatePanel from getting involved when older browsers are in play.
TLDR - beware of this code on buttons in updatepanels. It's a good approach and nice method but has a potential issue in my (likely edge) case.
ps - I would have commented on rp's post but I don't have the rep. Thought it might be useful for future travelers.
So simply disabling the button via javascript is not a cross-browser compatible option. Chrome will not submit the form if you just use OnClientClick="this.disabled=true;"
Below is a solution that I have tested in Firefox 9, Internet Explorer 9, and Chrome 16:
<script type="text/javascript">
var buttonToDisable;
function disableButton(sender)
{
buttonToDisable=sender;
setTimeout('if(Page_IsValid==true)buttonToDisable.disabled=true;', 10);
}
</script>
Then register 'disableButton' with the click event of your form submission button, one way being:
<asp:Button runat="server" ID="btnSubmit" Text="Submit" OnClientClick="disableButton(this);" />
Worth noting that this gets around your issue of the button being disabled if client side validation fails. Also requires no server side processing.
Note that rp's approach will double submit your form if you are using buttons with UseSubmitBehavior="false"
.
I use the following variation of rp's code:
public static void DisableButtonOnClick(Button button, string clientFunction)
{
// If the page has ASP.NET validators on it, this code ensures the
// page validates before continuing.
string script = "if (typeof(Page_ClientValidate) == 'function') { "
+ "if (!Page_ClientValidate()) { return false; } } ";
// disable the button
script += "this.disabled = true; ";
// 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))
script += string.Format("if (typeof({0}) == 'function') {{ {0}() }} ", clientFunction);
// only need to post back if button is using submit behaviour
if (button.UseSubmitBehavior)
script += button.Page.GetPostBackEventReference(button) + "; ";
button.Attributes.Add("onclick", script);
}