Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

asp.net - disable button when onClick fires

I want to have a button that when clicked, I want to go to disabled so the user cannot click it again. Since I am using postback and the onClick is used for calling the function, I can't get it to make the button disabled on the client side.

I know I could just have the script redirect to "processing..." page, but I would really prefer to have the button disabled and the user to stay on the current page for  the 10-15 seconds of processing time.

Does anyone have an elegant or simple solution for disabling an asp:button after the user clicks on it?

Thanks,
Jason

Jason
Tuesday, June 08, 2004

Just write a quick javascript function to disable the button client-side, and in your Page.Load code, place the following:

btnsubmit.Attributes.Add("onclick", "disablebuttonfunction")

This way, your function will run before the postback, so you can disable the button before processing begins.

Greg Hurlman
Tuesday, June 08, 2004

in Page_Load or somwhere:
myButton.Attributes.Add("onclick", "this.disabled=true;");

Duncan Smart
Tuesday, June 08, 2004

"great minds..."

Duncan Smart
Tuesday, June 08, 2004

Ok, that got me a lot closer, but I still have the problem of re-enabling it. Here is what I have:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

      btnStart.Attributes.Add("onclick", "this.disabled=true;")
End Sub

Public Sub btnStartClick(ByVal sender As Object, ByVal e As System.EventArgs)

      'do some work, then re-enable the button

        btnPhotos.Enabled = True
        'only this doesn't re-enable the button. For some reason it is still disabled

end sub


Thanks again for the help,
Jason

Jason
Tuesday, June 08, 2004

You shouldn't need to re-enable the button because clicking the button causes a postback, which will regenerate the HTML of the page. Basically, don't bother doing anything with the server-side Enabled property.

Duncan Smart
Wednesday, June 09, 2004

I never got this to work, because when the button is disabled client-side, its information is no longer posted back to the server, so its server-side click event does not fire.  I suspect that's the behavior you're seeing.

If you do manage to make this work, I'd love to know how.

Ian Olsen
Wednesday, June 09, 2004

Here's an untested idea - instead of just disabling the button, disable it and submit the form in teh same JS function - that *should* force the postback through, though I may be forgetting some postback rules.

Greg Hurlman
Wednesday, June 09, 2004

Worst case, you could actually render two buttons, one shown and one hidden. When they click the button, hide it, and show the alternate disabled button. Hackish, but should work.

Brad Wilson (dotnetguy.techieswithcats.com)
Wednesday, June 09, 2004

The trouble with client-side disabling of buttons is the edge case where the postback doesn't fully happen.

For instance, if they click the button and it's taking too long, so they hit Stop.  But uh oh!  The button is now disabled and they're screwed!

What I do is to generate a random instance ID at the first load of the page.  On my final submit, I record that that instance has already been posted.  If they try to post it again, depending on the app, they either get an error message or I transparently update the previous submission.

Richard P
Friday, June 11, 2004

A good, well-known solution to the double post problem. It even has a name: the "Carwash Token" solution.

(For those who aren't familiar... when you buy a carwash at one of those "drive in and sit" carwashes that are typically attached to gas stations, they give you a receipt with a number on it, that can only be used once. The carwash token concept for the browser is the same: give them a new token every time they get a form, and stash the most recent token off in session. When the postback comes back, take some evasive action if they have the wrong token.)

Brad Wilson (dotnetguy.techieswithcats.com)
Saturday, June 12, 2004

The "car wash token" is essentially how we solved it.  The reason it's not a dead issue is related to the user's perception. 

Our users are not technically savvy, and it's difficult to come up with an "evasive action" when the tokens don't match that doesn't utterly confuse them or cause fear and panic.    We think disabling the button right after it's clicked would be more intuitive, but we haven't found a satisfactory way to pull it off.

I must confess we haven't tried the hidden pseudo-button suggested.  That could work.

Ian Olsen
Wednesday, June 16, 2004

dear sir,
          asp.net form is not open in my system, it shows error of path (error 404).
what should i do ?

manoj mittal
Thursday, June 24, 2004

Hi All,

Just a note to say that the ghost button hack works a treat! I've posted an article here that explains all:

http://www.2404.co.uk/index.php?path=articles/view.php&articleId=19

Hope you find useful.

Cheers,

Stephen

Stephen
Thursday, July 01, 2004

here's how to get around the disable/asp.net even problem.

add a javascript function called function disableControlls(){} (or whatever u want to call it) then call that from the body event "onbeforeunload" so your body tag would look something like this:

<body MS_POSITIONING="GridLayout" onbeforeunload="disableControlls();">  the original values for the controls still post back, as well as events before the unload event, so when you disable the controls at that point there is no adverse effect.

Nathan Maffeo
Friday, December 03, 2004

Forgot to add in my original post, in the disableControlls function add the code to disable the controls you want to have disabled.

Nathan Maffeo
Friday, December 03, 2004

onclick="return disableme()"

function disableme()
{
  // code to disable button here

  return false;
}

returning false back to the onclick event then returns false back to the button which cancels the postback...

better late then never!

pete b
Friday, January 07, 2005

I used this code.
<form onsubmit="document.myLittleForm.myButton.disabled = true;" yada yada>
<input type="submit" id="mybutton">

This particular example is plain HTML, i'm not into ASP.net that much but I cant find a reason why it should'nt work there.

Mattias
Tuesday, January 18, 2005

Ok, I've been playing with this and think I've found a nice, easy, and uncomplicated way to do it (at least in vs2003)

If you want to disable a button on your asp.net page when it's clicked but still fire the server side event:

In your page_load event, add
btnSubmit.Attributes.Item("onclick") = "this.disabled=true;" & GetPostBackEventReference(btnSubmit).ToString

This will force the page to generate a postback request, even when the control is disabled.  In my implementation, I also change the caption of the button to 'Uploading...'

Bill Thomas
Wednesday, January 19, 2005

Many thanks to Bill Thomas of finally coming up with a solution that works!

JasonBSteele
Wednesday, February 16, 2005

...except if there's client side validation!

If that's the case check this out
  http://msmvps.com/anguslogan/archive/2004/12/22/27223.aspx

JasonBSteele
Wednesday, February 16, 2005

If this one is still open for debate:

A simple solution that works with client and server-side validation.

I use a hidden field called "resubmitted", and my client side form validation function follows the following format:


function validateOnSubmit() {

    if (document.forms.ts1.resubmitted.value == "true")
    {
        // stops this resubmission and disables the button
        // but the server will finish processing the original request
        document.forms.ts1.btnNext.disabled = true;
        return false; 
    }
    
    // Normal form validation ....
    if (isDateValid(document.forms.ts1.txtPeriodEnding.value) != 0)
    {
        alert('Period Ending must be in the format dd/mm/yyyy.');
        document.forms.ts1.txtPeriodEnding.focus();
        return false;
    }

    // Mark this form as being submitted sucessfully
    document.forms.ts1.resubmitted.value = "true";
    return true;

};

The button does not disable the first time its clicked so the button value is still passed back.  the second time its clicked the button will be disabled.

Its easy and works well with asp.net.

Jon Richardson
Thursday, February 17, 2005

in the page's render method, add the following...

btnCreate.Attributes.Add("onclick", GetPostBackEventReference(btnCreate) & ";this.value='Please wait...';this.disabled = true;")

substitute your button control name for "btnCreate" both times in this sample line of code.

Brent Stineman
Wednesday, March 09, 2005

The following solution does not work:

this.my_ImageButton.Attributes.Add("onclick", GetPostBackEventReference(this.my_ImageButton).ToString()+";this.value='Please wait...';this.disabled = true;");

Has anybody managed it to work under ASP.NET?

Thanks

FYK
Wednesday, March 16, 2005

Bill's suggested method works quite well, if there is NO client-side validation. The key to this method is to first, disable the button, then call the required Javascript function. I don't think the reverse order works. The more elegant way to do this is to create a generic Javascript function that disables an element passed into it. This function could also set the value of the element.

Such as:

function toggleDisabled(elem,txt){
if ((elem != null) && (elem.disabled != 'undefined')){
elem.disabled = !(elem.disabled);
if (txt != '')
elem.value = txt;
}
}

Then in your form initializer you can add the code as Bill suggested (this is the C# version):

btnSubmit.Attributes.Add("onclick", "toggleDisable(this,'Please Wait...')" + GetPostBackEventReference(btnSubmit).ToString());

If you have client-side validation going on and you need to give the visitor the ability to re-click the button after validation (if the form has errors), you can simply call this generic Javascript function to re-activate the button.

Justin Perkins
Tuesday, April 05, 2005

That C# code should be:

btnSubmit.Attributes.Add("onclick", "toggleDisabled(this,'Please Wait...')" + GetPostBackEventReference(btnSubmit).ToString());

Justin Perkins
Tuesday, April 05, 2005

Here's yet another option that works well if there is only one button that submits the form.  Use the page's code-behind to modify the Form tag's OnSubmit attribute.

RegisterOnSubmitStatement( "ServerForm", "if (this.submitted) return false; this.submitted = true; return true;" );

The effect is that once the form is submitted once, it cannot be submitted again.

Howard Hoffman
Tuesday, April 19, 2005

Found another way without using ghost buttons or having any postback problems.

Simply set the buttons class to a CSS class that has the, "Display : none" property.  Then when the button is clicked it is simply not visible on the page and the impatient user can' keep clicking it.

Hope this helps.

Karl

Karl Shifflett
Thursday, May 05, 2005

I have this script  btnBack.Attributes.Add("onclick", GetPostBackEventReference(btnBack) & ";this.value='Please wait...';this.disabled = true;")

Working fantastically on 4 pages but on my 5th page it keeps retuning a client script error stating Invalid Charater, any idea's?

Thanks

Steve Irons
Thursday, June 23, 2005

*  Recent Topics

*  Fog Creek Home