The dreaded ASP.NET submit button double click

I’m sure every one of us has ran into the issue of a user inadvertently or even intentionally double clicking the buttons on our web applications, many times this can lead to invalid states or duplicated submissions or even the worst, duplicated billing. Through out my time as an asp.net developer this along with the back button has been a bane to web aplication development, I’ve seen many solutions for dealing with this issue however I seemed to find a very simple and reliable one.

Inside the aspx, create 2 buttons one for your active click one to be a place holder

<asp:Button ID=”btnSave” runat=”Server” CssClass=”button” Text=”Save Entry” OnClick=”btnSave_Click” />
<asp:Button ID=”btnSaveDisabled” Enabled=”false” runat=”server” Text=”Save Entry” CssClass=”button” Style=”visibility: hidden;” />

Note the style on the Disabled button that’s a key to this solution. Now inside the PageLoad

if (!Page.IsPostBack)
{
btnSave.OnClientClick = string.Format(“javascript:{0}.style.visibility = ‘hidden’;{0}.style.display  = ‘none’;{1}.style.visibility = ‘visible'”, btnSave.ClientID, btnSaveDisabled.ClientID);

With this in the code behind you always have the guaranteed client id of the controls without any need for any complex object finding that is browser specific and a very simple on client click method will remove the actual submit button from the page entirely and set the disabled one to show.

This solves both issues of double submitting and removing the button from the form entirely with the visibility = ‘none’ protecting from any type of html manipulation or JavaScript manipulation to click the button again even thought it’s not visible to the user.

BloggingContext.ApplicationInstance.CompleteRequest();

Advertisements

23 thoughts on “The dreaded ASP.NET submit button double click

  1. Yes this should work on all browsers as long as javascript is enabled. The only way to do this outside of requiring javascript is you need to keep track of the state of the form server side using variables stored in the session or perhaps even workflow to know whether a person has submitted the page already.

  2. I tried to change <asp:Button to <asp:ImageButton but then i get an error with btnSaveDisabled is undefined.

    Why doesn’t it work with ImageButton?

    I’ve also tried this but it doesn’t work in firefox.
    btnSave.Attributes.Add(“OnClick”, ClientScript.GetPostBackClientHyperlink(btnSave, “”, false) + “;this.disabled=true;”);

    When is microsoft to publish a ClickOnce=true property on all the buttons…

    cheers

  3. This has to do with the naming syntax html uses for the disabled properties on form input objects the property you really are looking to set disabled to is disabled=”disabled” however you need to verify it is actually cross browser friendly.

    I believe I have tried similar approaches before and found it to not affect Firefox. That’s the reason I published my solution since it is based on actually removing the button from the page mark up. When it is clicked it is hidden from the page by the time the post back has finished with display=”none” it will actually have been removed entirely from the markup.

    If the button fails validation or at the end of the post back you want the button back it’s as simple as calling btnSubmit.visible = true; btnSubmitDisabled.visible = false; in the code behind and the buttons will render out to their original without any extra javascript manipulation.

    Working with ASP.NET as opposed to ASP 3.5 MVC Framework I tend to label custom JavaScript ALMOST bad practice to use. Unfortunately it can be unavoidable at some point for a rich web application which means having to fight with ASP.NET’s naming conventions to even be able to access objects. As the web continues to evolve I really expect MVC to start to grow for dynamic web orientated businesses sadly not overall since businesses that hit middle to large scale usually become archaic in technology regardless of how vital it can be.

  4. Yes but your approach only works with buttons not imagebuttons.
    I don’t find the button control very nice if you have some kind of interest in the design of the layout.

    There is also a problem with the second ‘hidden’ button, that it still takes up the space width if you have some buttons next to each other like say a cancel button to the right.

  5. wee

    I’m not sure off hand with image buttons it’s most likely dependent on whether or not image buttons render anchor tags or an actual button element. The ASP.NET controls that render out to anchor tags can cause some extremely weird browser specific issues due to Internet Explorer acknowledging OnClick events that are attached to anchor tags even though they are not correct in the HTML specification where as other browsers that correctly follow the specifications will ignore them.

    You can use regular buttons with css to display an image on them and get the same look and feel of the image buttons. It does require some playing around with styling for it end up right but I have done it before without too many issues.

    You are right about that display=”hidden” will reserve space for the button, if that alters the display of your page like with multiple buttons as you said you could always go a little further and add that the button in the mark up has float: left and then when the submit button is clicked to switch the button to float: right that it will fall into the space where the submit button is or vice-a-versa on left and right.

  6. There isn’t a sure fire css slice for the buttons as it is all based on image dimensions (perhaps there is one that take’s in to account the x,y dimensions of the image but i haven’t experimented enough.) Basically the jist of it is you will declare the button similar to
    asp:button id=”button” text=”” style=”width: 100px; height: 50px; color: transparent; background: transparent url(‘button.gif’) no-repeat fixed center;”

    You might want to play around with the color transparent and try either none, or some actual color variation. This was just off the top of my head but i know it’s similar to what I did previously it just takes some fudging to get it to work. Sadly you lose the nice button clicking up and down feature when you go this route. To emulate up and down events you would most likely have to write a javascript image replacer for the background on the onmousedown onmouseup events.

  7. Try with this…I had solution from one of my colleague… will work fine..

    btnConfirm.Attributes[“onclick”] = “fnClickOnce(this,'” + btnConfirm.UniqueID + “‘)”;

    var boolClicked = false;
    function fnClickOnce(sender, buttonUid) {
    sender.setAttribute(‘href’, ‘javascript:void(0);’);
    if (!boolClicked) {
    sender.disabled = ‘disabled’;
    __doPostBack(buttonUid, ”);
    boolClicked = true;
    }
    }

    • @Ashish, that looks like it should work but what would happen with javascript disabled would it even be able to submit still? My goal was to create a solution requiring the least amount of javascript as possible.

  8. You should use style.display=’none’ instead of style.visible=’hidden’ to avoid leaving empty space on your page.

  9. @steve, that would be a personal preference, i prefer using hidden to make sure that the browsers reserve space for the button but on your layout its possible none might be preferred.

  10. This is a great workaround. Since I’m using partial page postback and UpdateProgress, the button disappears long enough for the partial page to process and then returns, preventing double click but allowing the user to hit the button again after the method has been processed. Thanks!

  11. I used this code for image button in Page_Load in “if (IsPostBack) { … }” section and it works.

    imgBtn.Attributes.Add(“onclick”, ” this.disabled = true; ” + ClientScript.GetPostBackEventReference(imgBtn, null) + “;”);

    • @Galip, Did you try that on other browsers? Some browsers ignore images having an onclick event and your button won’t be able to work. I ran into that issue myself before.

  12. I have been looking for a way to correct the double click problem. Your solution looked very good to me. I did however have a problem with it. I am new to this stuff so please bear with me as I might be missing something.

    I tried to use you solution with a page that had the two ‘save’ buttons your solution requires as well as a textbox and a required field validator for that textbox. Given the following:

    The user submits the page without providing data to the textbox.

    This means that the disabled button is visible while the save button is now hidden. This also means that the btnSave_Click never ran because the required field validator prevented this event from running.

    At this point the user see’s the error message from the required field validator and realizes that he/she needs to provide data in the text box. The user puts data in the text box and then hits the save button. Only nothing happens because the disabled save button that has no server side events is what is visible. Therefore the user is forced to hit the save button a second time in order to post back to the server.

    Does my analysis make any sense? Am I missing something? If you want I will provide you with the test program that I created.

    Thanks so much.

  13. Yes I have most certainly come across this many times in my development career.
    The easiest way is just to make the button invisible (visible = false) or alternatively disable the button (enabled = false)
    Hope it helps 🙂

  14. Thanks! Spinning my wheels for several hours now trying to integrate two javascript functions: confirm, and the button hide for one ClientClick event to no avail. This saves the day!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s