[ACCEPTED]-Disable button on form submission-webforms

Accepted answer
Score: 17

I'm not a huge fan of writing all that javascript 2 in the code-behind. Here is what my final 1 solution looks like.

Button:

<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" OnClientClick="doSubmit(this)" />

Javascript:

<script type="text/javascript"><!--
function doSubmit(btnSubmit) {
    if (typeof(Page_ClientValidate) == 'function' && Page_ClientValidate() == false) { 
        return false;
    }    
    btnSubmit.disabled = 'disabled';
    btnSubmit.value = 'Processing. This may take several minutes...';
    <%= ClientScript.GetPostBackEventReference(btnSubmit, string.Empty) %>;    
}
//-->
</script>
Score: 14

Give this a whirl:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {

         // Identify button as a "disabled-when-clicked" button...
         WebHelpers.DisableButtonOnClick( buttonTest, "showPleaseWait" ); 
    }

    protected void buttonTest_Click( object sender, EventArgs e )
    {
        // Emulate a server-side process to demo the disabled button during
        // postback.
        Thread.Sleep( 5000 );
    }
}



using System;
using System.Web;
using System.Web.UI.WebControls;
using System.Text;

public class WebHelpers
{
    //
    // Disable button with no secondary JavaScript function call.
    //
    public static void DisableButtonOnClick( Button ButtonControl )
    {
        DisableButtonOnClick( ButtonControl, string.Empty );    
    }

    //
    // Disable button with a JavaScript function call.
    //
    public static void DisableButtonOnClick( Button ButtonControl, string ClientFunction )
    {   
        StringBuilder sb = new StringBuilder( 128 );

        // If the page has ASP.NET validators on it, this code ensures the
        // page validates before continuing.
        sb.Append( "if ( typeof( Page_ClientValidate ) == 'function' ) { " );
        sb.Append( "if ( ! Page_ClientValidate() ) { return false; } } " );

        // Disable this button.
        sb.Append( "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 ) ) 
        {
            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 ) + ";" );

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

0

Score: 5

The following function is useful without 6 needing the disabling part which tends to 5 be unreliable. Just use "return check_submit();" as 4 part of the onclick handler of the submit 3 buttons.

There should also be a hidden field 2 to hold the form_submitted initial value 1 of 0;

<input type="hidden" name="form_submitted" value="0">

function check_submit (){
            if (document.Form1.form_submitted.value == 1){
                alert("Don't submit twice. Please wait.");
                return false;
            }
            else{
                document.Form1.form_submitted.value = 1;
                return true;
            }
            return false;
    }
Score: 2

Disable the button at the very end of your 5 submit handler. If the validation fails, it 4 should return false before that.

However, the 3 JavaScript approach is not something that 2 can be relied upon, so you should have something 1 to detect duplicates on the server as well.

Score: 2

if the validation is successful, then disable 1 the button. if it's not, then don't.

function validate(form) {
  // perform validation here
  if (isValid) {
    form.mySubmitButton.disabled = true;
    return true;
  } else {
    return false;
  }
}

<form onsubmit="return validate(this);">...</form>
Score: 1

Set the visibility on the button to 'none';


btnSubmit.Attributes("onClick") = document.getElementById('btnName').style.display = 'none';

Not 4 only does it prevent the double submission, but 3 it is a clear indicator to the user that 2 you don't want the button pressed more than 1 once.

Score: 0

Not sure if this will help, but there's 3 onsubmit event in form. You can use this 2 event whenever the form submit (from any 1 button or controls). For reference: http://www.htmlcodetutorial.com/forms/_FORM_onSubmit.html

Score: 0

A solution will be to set a hidden field 4 when the button is clicked, with the number 3 1.

On the button click handler first thing 2 is to check that number if it is something 1 other than 1 just return out of the function.

Score: 0

You may also be able to take advantage of 4 the onsubmit() javascript event that is 3 available on forms. This event fires when 2 the form is actually submit and shouldn't 1 trap until after the validation is complete.

Score: 0

This is an easier but similar method than 1 what rp has suggested:

function submit(button) {
        Page_ClientValidate(); 
        if(Page_IsValid)
        {
            button.disabled = true;
        }
}

 <asp:Button runat="server" ID="btnSubmit" OnClick="btnSubmit_OnClick" OnClientClick="submit(this)" Text="Submit Me" />
Score: 0

Just heard about the "DisableOnSubmit" property 11 of an <asp:Button>, like so:

<asp:Button ID="submit" runat="server" Text="Save"
    OnClick="yourClickEvent" DisableOnSubmit="true" />

When rendered, the 10 button's onclick attribute looks like so:

onclick="this.disabled=true; setTimeout('enableBack()', 3000);
  WebForm_DoPostBackWithOptions(new
  WebForm_PostBackOptions('yourControlsName', '', true, '', '', false, true))

And 9 the "enableBack()' javascript function looks 8 like this:

function enableBack()
{
    document.getElementById('yourControlsName').disabled=false;
}

So when the button is clicked, it 7 becomes disabled for 3 seconds. If the 6 form posts successfully then you never see 5 the button re-enable. If, however, any 4 validators fail then the button becomes 3 enabled again after 3 seconds.

All this just 2 by setting an attribute on the button--no 1 javascript code needs to be written by hand.

Score: 0

Note that rp's approach will double submit 2 your form if you are using buttons with 1 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);
}
Score: 0

The correct (as far as user-friendliness 17 is concerned, at least) way would be to 16 disable the button using the OnClientClick 15 attribute, perform the client-side validation, and 14 then use the result of that to continue 13 or re-enable the button.

Of course, you should 12 ALSO write server-side code for this, as 11 you cannot rely on the validation even being 10 carried out due to a lack, or particular 9 implementation, of JavaScript. However, if 8 you rely on the server controlling the button's 7 enabled / disabled state, then you basically 6 have no way of blocking the user submitting 5 the form multiple times anyway. For this 4 reason you should have some kind of logic 3 to detect multiple submissions from the 2 same user in a short time period (identical 1 values from the same Session, for example).

Score: 0

one of my solution is as follow:

add the 8 script in the page_load of your aspx file

    HtmlGenericControl includeMyJava = new HtmlGenericControl("script");
    includeMyJava.Attributes.Add("type", "text/javascript");
    includeMyJava.InnerHtml = "\nfunction dsbButton(button) {";
    includeMyJava.InnerHtml += "\nPage_ClientValidate();";
    includeMyJava.InnerHtml += "\nif(Page_IsValid)";
    includeMyJava.InnerHtml += "\n{";
    includeMyJava.InnerHtml += "\nbutton.disabled = true;";
    includeMyJava.InnerHtml += "}";
    includeMyJava.InnerHtml += "\n}";
    this.Page.Header.Controls.Add(includeMyJava);

and 7 then set your aspx button parameters as 6 follow:

<asp:Button ID="send" runat="server" UseSubmitBehavior="false" OnClientClick="dsbButton(this);" Text="Send" OnClick="send_Click" />

Note that "onClientClick" helps to 5 disable to button and "UseSubmitBehaviour" disables 4 the traditional submitting behaviour of 3 page and allows asp.net to render the submit 2 behaviour upon user script.

good luck

-Waqas 1 Aslam

Score: 0

So simply disabling the button via javascript 10 is not a cross-browser compatible option. Chrome 9 will not submit the form if you just use 8 OnClientClick="this.disabled=true;"
Below is a solution that I have tested 7 in Firefox 9, Internet Explorer 9, and Chrome 6 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 5 click event of your form submission button, one 4 way being:

<asp:Button runat="server" ID="btnSubmit" Text="Submit" OnClientClick="disableButton(this);" />

Worth noting that this gets around 3 your issue of the button being disabled 2 if client side validation fails. Also requires 1 no server side processing.

Score: 0

Building on @rp.'s answer, I modified it 3 to invoke the custom function and either 2 submit and disable on success or "halt" on 1 error:

public static void DisableButtonOnClick(Button ButtonControl, string ClientFunction)
{
    StringBuilder sb = new StringBuilder(128);

    if (!String.IsNullOrEmpty(ClientFunction))
    {
        sb.AppendFormat("if (typeof({0}) == 'function') {{ if ({0}()) {{ {1}; this.disabled=true; return true; }} else {{ return false; }} }};", ClientFunction, ButtonControl.Page.ClientScript.GetPostBackEventReference(ButtonControl, null));
    }
    else
    {
        sb.Append("return true;");
    }

    ButtonControl.Attributes.Add("onclick", sb.ToString());
}
Score: 0

Came across rp's code in a legacy app of 32 ours which was struggling with some crazy 31 behaviour.

Tracked it down to a strange 30 combination of event firing - when DisableButtonOnClick() was 29 being used on an asp button inside an UpdatePanel, the 28 POST would be sent twice (once by the doPostBack 27 added by DisableButtonOnClick(), and once 26 by the UpdatePanel). However, this only 25 happened with some browsers (early versions 24 of Edge, but not recent ones, and IE11 did 23 this, Chrome and FireFox did not (at least 22 the versions I tested with)). I presume 21 Chrome and newer versions of Edge are dealing 20 with this scenario internally in some way. Tracking 19 the issue with F12 devtools in IE - the 18 two POSTs happen so closely together that 17 the first one gets immediately ABORTED, but 16 under some conditions (network latency, user 15 machine load, etc) the request does get 14 through to the server before the browser 13 can abort. So this results in a seemingly 12 random double-post coming from button presses 11 throughout the system, and it was a pain 10 to trace back. The fix is to add a "return 9 false;" after the doPostBack to prevent 8 the UpdatePanel from getting involved when 7 older browsers are in play.

TLDR - beware 6 of this code on buttons in updatepanels. It's 5 a good approach and nice method but has 4 a potential issue in my (likely edge) case.

ps 3 - I would have commented on rp's post but 2 I don't have the rep. Thought it might 1 be useful for future travelers.

More Related questions