4

My Problem is ,I have a simple web form, which contains two textboxes and a button.there are some asp.net validator controls on page.so i want client side disabling of button when all validation is done.and also after disabling of button, i am executing some server side code.All of this is working fine but, in case when I set postback url of button it gets fail. bellow is some part of coding that will give you some brief idea. Any hint will be highly appreciated.......

I wanted to make this functionality in composite control. here is button class

public class MyButton : Button
{

    protected override void OnPreRender(EventArgs e)
    {
        if (this.CausesValidation)
        {
            if (!String.IsNullOrEmpty(this.ValidationGroup))
            {
                this.Attributes.Add("onclick", @"javascript:

             if (typeof(Page_ClientValidate) == 'function')
                 {
                    if (Page_ClientValidate('" + this.ValidationGroup + "')){" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) +

              "}else{return;}}  else{" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) + "}");
            }

            else
            {
                this.Attributes.Add("onclick", @"javascript:

                 if (typeof(Page_ClientValidate) == 'function')
                   {
                      if (Page_ClientValidate()){" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) +
                  "}else{return;}}  else{" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) + "}");
            }
        }
        else
            this.Attributes.Add("onclick", "javascript:" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this));

        base.OnPreRender(e);
    }
1
  • There is a problem with all of these solutions that if the button is clicked rapidly enough when the system is sluggish then a second push can be queued and will invoke the on-click method a second time even if the first click disabled the button. Commented Oct 22, 2014 at 18:00

7 Answers 7

11

This is the correct and simple way to do this:

Create a helper method in your application (say in a Utlity Namespace):

    Public Shared Sub PreventMultipleClicks(ByRef button As System.Web.UI.WebControls.Button)
        button.Attributes.Add("onclick", "this.disabled=true;" & button.Page.ClientScript.GetPostBackEventReference(button, String.Empty).ToString)
    End Sub

Now from the code behind of each of your web pages you can simply call:

    Utility.PreventMultipleClicks(button1)

where button1 is the the button you want to prevent multiple clicks.

What this does is simply sets the on click handler to: this.disabled=true

and then appends the buttons own post back handler, so we get:

onclick="this.disabled=true";__doPostBack('ID$ID','');"

This does not break the default behaviour of the page and works in all browsers as expected.

Enjoy!

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for this answer. Works great. I created the same solution through an extension method vs utility/helper, but it works great.
I wasted HOURS on this -- thank you for your answer. I have up-voted your answer, and I hope O.P. will someday accept it.
This does break the default behaviour; it still posts-back and disables the button when ASP.NET validation fails.
I had a linkbutton and just modified the script to: button.Attributes.Add("onclick", "if(this.disabled) return false; this.disabled=true;"...
1

If you disable the button then form submission will not happen. Correct way would be to set timer to disable the button. I would also suggest to use submit behavior instead of putting post-back event ref. For example,

function clickHandler(id, validate, validationGroup) {
   var isValid = true;
   if (validate && typeof(Page_ClientValidate) == 'function') {
     isValid = validationGroup? Page_ClientValidate(validationGroup): Page_ClientValidate();
   }
   if (isValid)
   {
      // set timer to disable the button
      var b = document.getElementById(id);
      var f = function() { b.disabled = 'disabled'; };
      setTimeout(f, 100);
      return true;
   }
   return false;
}

And now attach function to your button

protected override void OnPreRender(EventArgs e)
{
    this.Attributes.Add("onclick", 
       string.Format("return clickHandler('{0}', {1}, '{2}')", 
       this.ClientID, this.CausesValidation ? "true" : "false", 
       this.ValidationGroup));
}

1 Comment

is the first function Javascript or C#?
1

If you disable a submit button once it is clicked, then it won't postback. I've been researching this for many many hours now, and the best solution I've seen is here. (The best solution is at the bottom of the page)

I'm now writing a custom server control to add to the toolbox that extends from Button, and uses a slightly modified version of this code. (overriding the OnLoad method)

I'm allowing the user the ability to change the 'processing...' text for something else and may make an attribute that allows the text to change to something else when submission is complete(which would be produced when the postback returns)

Comments

0

I have come up with the solution. Just hide the button after you click it. The postback will take place as usual. After completion of the postback, you will get your button as it is! See the detailed steps on how to disable asp.net button on postback and master the art!

Comments

0

Assuming this is asynchronous, and that you validate prior to saving, you can try as pseudo-follows:

    bool hasSavedAlready = false;

    savedata(){
       if (!hasSavedAlready){ 
       //normal saving code
       ...
       //after success
       hasSavedAlready = true;

       }
    }

That's the simplest solution I can think of.

Comments

0

I had this problem and none of the previous solutions worked for me but after some messing around I used:

<asp:LinkButton runat="server" OnClientClick="this.setAttribute('disabled','disabled'); this.text = 'Submit in progress...';" UseSubmitBehavior="false" ID="btnSubmit" ValidationGroup="formSubmit"</asp:LinkButton>

Comments

0

You need to consider that if the same session/user opens a page (example.whatever) on a window or tab lets say window1 ,and he again opens the same page (example.whatever) on window2.

When the user clicks the button on window1 and before 30 secs ends he clicks that button on window2 the server will think you clicked that button twice.

To avoid this in asp.net, i use :

Application["isButtonGettingClickedByAnyOne"] this an array that is shared bettwen all Sessions (all the users of your website).

or

Session["isButtonGettingClickedByThisUserInAnotherTab"] you can see it as shared bettwen all tabs (of the same user).

And make the server checks if they are reserved by some one or not.

  • if yes then wait 30sec + you turn ...
  • if no then you can 1st reserve it, and then execute your function, and when you finish the function free it so that others can use it again.

I hop this was useful and not painful to read.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.