24

I realise this question has been asked but none of the answers worked for my project.

I have a button that when clicked calls an API, so there is a 1 second delay.

I have tried several things nothing works.

btnSave.Attributes.Add("onclick", " this.disabled = true; " + ClientScript.GetPostBackEventReference(btnSave, null) + ";");

Even that does nothing.

Remi Guan
  • 21,506
  • 17
  • 64
  • 87
WhiteSpider
  • 385
  • 1
  • 3
  • 10

9 Answers9

37

Prevent Double Click .Please add below code in your aspx page.

<script type="text/javascript" language="javascript">

   Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
   function BeginRequestHandler(sender, args) { var oControl = args.get_postBackElement(); oControl.disabled = true; }

</script>
Deepak Joshi
  • 1,036
  • 7
  • 17
  • 4
    Best solution so far :-) – gchq Jan 01 '15 at 22:18
  • 2
    could you explain how this works? How is this hooked up to `btnSave`? – nu everest May 07 '15 at 21:02
  • 2
    Doesn't work. I get `Error: 'Sys' is undefined` ... Where exactly do I need to add this script in aspx page? – Pat Dec 22 '16 at 01:21
  • 2
    @nu everest: Disabling of the button must be done on the client-side (javascript) because server-side disabling isn't quick enough. User could click the button few times before server-side code disables the button. ("get_postBackElement" - Gets the postback element that initiated the asynchronous postback.) – Jadran Grba Aug 31 '17 at 08:31
  • 1
    If you get `Error: 'Sys' is undefined` when using this then it is because you need a `ScriptManager` on the page. – Brian Cryer Oct 13 '17 at 13:16
  • 1
    Very helpful. Thanks :) – Manjunath Bilwar Jul 31 '18 at 21:21
  • Works great but only if inside an update panel. It also enables back the button after the post back – Furkan Gözükara May 23 '19 at 12:25
  • Worked for me when I moved the section out of the javascript script and into the button. OnClientClick="Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);" – Stewart Nov 08 '22 at 20:59
  • Amedning previous comments: it doesn't matter where's the script, it matters where's the button - it's the button which should be in an update panel in order for the beginRequest handler to run. see [here](https://stackoverflow.com/a/6814474/3002584). – OfirD May 29 '23 at 20:47
28

This solution is simple and effective. On your button include this code:

OnClientClick="return CheckDouble();"

And wherever you want your JavaScript - e.g. At the bottom of your page:

<script type="text/javascript">
   var submit = 0;
   function CheckDouble() {
     if (++submit > 1) {
     alert('This sometimes takes a few seconds - please be patient.');
     return false;
   }
 }
 </script>
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Antony D
  • 434
  • 4
  • 6
  • This works great as it notifies the user and can help break the habit. Windows does the little "ding" while the alert dialog is up. :) – ahwm Feb 10 '17 at 17:22
  • Beautiful, simple to follow...alert message is nice touch! – Dave May 25 '17 at 18:47
  • Its working fine but server validations not firing like required field validation and etc – Rajesh Pathakoti Oct 26 '17 at 06:47
  • I added this and it did show the message, but still button click event got fired at server side. – User M Dec 04 '18 at 21:28
  • I don't this this work when your button is a submit, because it causes "submit" variable to get reset to zero. I might not be be right about that, but either way, it didn't work for me. – TizzyFoe Aug 18 '20 at 17:46
6

Most of the above suggestions failed to work for me. The one that did work was the following by tezzo:

Me.btnSave.Attributes.Add("onclick", "this.disabled=true;")
Me.btnSave.UseSubmitBehavior = False

Simpler still, rather than using the above in the code-behind, just use the following:

   <asp:Button ID="btnSave" runat="server" Text="Save" 
      UseSubmitBehavior="false"
      OnClientClick="this.disabled='true';" 
   </asp:button>

UseSubmitBehavior="false" is the key.

Dan H.
  • 262
  • 4
  • 12
  • This is the cleanest! Wonder why you have to set UseSubmitBehavior="false" though, why doesnt returning true do the postback – Cale Nov 06 '19 at 20:04
  • 1
    Second approach is the simplest possible, and it fits most of scenarios. Thanks for the answer! – Razvan Oct 08 '20 at 12:01
5

You can prevent double-clicking using this code:

Me.btnSave.Attributes.Add("onclick", "this.disabled=true;")
Me.btnSave.UseSubmitBehavior = False

So you can use btnSave_Click to call your API.

Usually I have a lot of Validators in my Page: setting Validator.SetFocusOnError = True I can run this code to reenable save button if a validation failed.

Me.YourControl.Attributes.Add("onfocus", Me.btnSave.ClientID & ".removeAttribute('disabled');")
tezzo
  • 10,858
  • 1
  • 25
  • 48
  • It works only after the first one, I have another button that says "add another" and after I click that it works but not before on the first one? – WhiteSpider Aug 08 '14 at 10:21
  • Good solution. I implemented this by adding JavaScript on the .aspx page to disable the button when clicked. I added `UseSubmitBehavior="false"` on the control itself. Achieves the same effect for me without relying on code behind. – Jacob Stamm Jul 13 '16 at 15:19
3

This is the one I found works in all cases.

<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button1" OnClick="Button1_Clicked" />
<asp:Button ID="Button2" runat="server" Text="Button2" />
</form>

Now here’s the short JavaScript snippet that will disable the button as soon as it is clicked so that when PostBack occurs the button cannot be clicked again.
<script type = "text/javascript">
function DisableButton() {
    document.getElementById("<%=Button1.ClientID %>").disabled = true;
}
window.onbeforeunload = DisableButton;
</script>

The above script disables the ASP.Net Button as soon as the page is ready to do a PostBack or the ASP.Net form is submitted.
But in cases you might want to disable all Buttons and Submit Buttons on the page hence for such cases I have created another function which disables all Buttons and Submit buttons whenever there’s a PostBack or form submission
<script type = "text/javascript">
function DisableButtons() {
    var inputs = document.getElementsByTagName("INPUT");
    for (var i in inputs) {
        if (inputs[i].type == "button" || inputs[i].type == "submit") {
            inputs[i].disabled = true;
        }
    }
}
window.onbeforeunload = DisableButtons;
</script>
Kim
  • 136
  • 7
0

Prevent Double Click .Please add below code in your aspx page

<script type = "text/javascript">
function DisableButton() {
document.getElementById("<%=Button1.ClientID %>").disabled = true;
}
window.onbeforeunload = DisableButton;
</script>
sheshadri
  • 1,207
  • 9
  • 21
  • 3
    While this might be helpful, please do not just post code without commentary explaining what we're looking at. – Andrew Jan 09 '15 at 14:51
0

At first my solution is like this:

<script>
function disableButton(btn) {
    setTimeout(function () { btn.disabled = true; }, 20);
    return true;
}
</script>
<asp:Button runat="server" ID="btnSave" Text="Save" OnClick="btnSave_Click" OnClientClick="return disableButton(this);" />

Without setTimeout the button will be immediately disabled and then the OnClick event will not be fired. The drawback of this approach is that the Save button will not be accessible anymore if some validation fails or some error happens.

So I don't think disable the button is a good solution, and come up with another solution:

     function disableButton(btn) {
        if (btn.hasclicked) return false;
        btn.hasclicked = 1;
        btn.onmouseenter = function () { this.hasclicked = 0; };
        return true;
    }

But my colleague points out that if the post processing is very slow, before it is finished, the user is still able to perform the double postback by leave-enter-click the button. So I figured out another two solutions:

  1. Run the validation from client before submitting the form. But if your page contains multiple ValidationGroup, it is said that the following Page_ClientValidate() should be called multiple times with a passed-in ValidationGroup parameter: e.g. Page_ClientValidate("group1"):

function disableButton(btn) {
  if (Page_ClientValidate) {
    Page_ClientValidate();
    if (!Page_IsValid) {
      btn.setAttribute("btnClicked", "n");
      return true;
    }
  }
  if (btn.getAttribute("btnClicked") == "y") {
    return false;
  } else {
    btn.setAttribute("btnClicked", "y");
    return true;
  }
}
  1. As the ASP.NET has only one form in a page (not ASP.NET MVC), we can also let the onsubmit client event of the form to intercept the double click:

    function disableButton(btn) {
    $("form").submit(function () {
        if (btn.getAttribute("btnClicked") == "y") 
            return false;
        else 
            btn.setAttribute("btnClicked", "y");
            return true;
    });}
    

    I'll ask QA to test those two approaches(Post edit: QA has proved that it is very dangerous to use this approach. Please refer to my following comments for details).

wcb1
  • 665
  • 1
  • 7
  • 6
  • Our QA testing proves that the second approach (the last one that does check at the form submit point) cannot be used as it will make the ASP.NET validation mechanism totally not work. It will not only bypass the validation mechanism at the client side, it will also make your server side validation always be Page.IsValid == true. It is terrible to use this approach. NEVER USE IT! – wcb1 Jul 03 '18 at 22:14
  • Page_ClientValidate is within DoPostbackWithOptions if the submit button is within a UserControl then option 1 could cause problems as well depending on the page the control is on and the way the validation is setup and whether or not Page_ClientValidate is already called. Even if you pass a validation group. You might be better off with using one-time use tokens on the server side so that subsequent requests in the queue are not honored with the used token – Charles Byrne Oct 02 '18 at 12:12
0

Try this way, it's a working solution:

For all browsers including Opera Mobile browser which doesn't support js, means your form will not be blocked in that type of browsers.

Add this in Page_load() method:

BtnID.Attributes.Add("onclick", "if(typeof (Page_ClientValidate) === 'function' && !Page_ClientValidate()){return false;} this.disabled = true;this.value = 'Working...';" + ClientScript.GetPostBackEventReference(BtnID, null) + ";");
X-Coder
  • 2,632
  • 2
  • 19
  • 17
0

This Worked for me too:

BtnID.Attributes.Add("onclick", "if(typeof (Page_ClientValidate) === 'function' && !Page_ClientValidate()){return false;} this.disabled = true;this.value = 'Working...';" + ClientScript.GetPostBackEventReference(BtnID, null) + ";");

  • 1
    Please review the formatting of the answer and add text to explain what exactly your code do that it works and answer the question. – E. Zacarias Mar 21 '23 at 12:36