views:

1791

answers:

9

Like every other web developer on the planet, I have an issue with users double clicking the submit button on my forms. My understanding is that the conventional way to handle this issue, is to disable the button immediately after the first click, however when I do this, it doesn't post.

I did do some research on this, god knows there's enough information, but other questions like Disable button on form submission, disabling the button appears to work. The original poster of Disable button after submit appears to have had the same problem as me, but there is no mention on how/if he resolved it.

Here's some code on how to repeat it (tested in IE8 Beta2, but had same problem in IE7)

My aspx code

<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<script language="javascript" type="text/javascript">
    function btn_onClick()
    {
     var chk = document.getElementById("chk");
     if(chk.checked)
     {
      var btn = document.getElementById("btn");
      btn.disabled = true;
     }
    }
</script>
<body>
    <form id="form1" runat="server">
     <asp:Literal ID="lit" Text="--:--:--" runat="server" />
     <br />
     <asp:Button ID="btn" Text="Submit" runat="server" />
     <br />
     <input type="checkbox" id="chk" />Disable button on first click
    </form>
</body>
</html>

My cs code

using System;

public partial class _Default : System.Web.UI.Page 
{
    protected override void OnInit(EventArgs e)
    {
     base.OnInit(e);
     btn.Click += new EventHandler(btn_Click);
     btn.OnClientClick = "btn_onClick();";
    }

    void btn_Click(object sender, EventArgs e)
    {
     lit.Text = DateTime.Now.ToString("HH:mm:ss");
    }
}

Notice that when you click the button, a postback occurs, and the time is updated. But when you check the check box, the next time you click the button, the button is disabled (as expected), but never does the postback.

WHAT THE HECK AM I MISSING HERE???

Thanks in advance.

+4  A: 

"Disabling" HTML controls doesn't always produce consistent behavior in all major browsers. So I try to stay away from doing that on the client-side, because (working with the ASP.NET model) you need to keep track of element's state on client and server in that case.

What I'd do is move button off the visible part of the window by switching the button's className to a CSS class that contains the following:

.hiddenButton
{
  position: absolute;
  top: -1000px;
  left: -1000px;
}

Now, what to put in place of the button?

  1. Either an image that looks like a disabled button
  2. Or just plain text that says "Please wait..."

And this can be done the same way but in reverse. Start with the element being hidden at page load and then switch to a visible className on form submit.

Kon
A: 

For debugging purposes, what happens if you put an else clause against the if(chk.checked)?

Neil Barnwell
Hi Neil, I'm not sure I follow you, but if you are suggesting I reenable the button, it won't work with a simple else, since once it's disabled it can't be clicked. I'd need to create a checkbox click event to reenable it, and I wanted to keep things as simple as possible. Is that what you meant?
John MacIntyre
No, I'm wondering if the reason it doesn't work because the chk,checked might not be returning true, hence the button isn't disabled.
Neil Barnwell
Oh ok. No it is definitely disabling the button, but then doesn't submit the post. Thanks again.
John MacIntyre
+3  A: 

fallen888 is right, your approach doesn't work cross-browser. I use this little snippet to prevent double-click.

Mauricio Scheffer
+3  A: 

I think you're just missing this tag:

UseSubmitBehavior=”false”

Try it like this:

<asp:Button ID=”btnUpdate” runat=”server” UseSubmitBehavior=”false” OnClientClick=”if(Page_ClientValidate()) { this.disabled = true; } else {return false;}” Text = “Update” CssClass=”button” OnClick=”btnUpdate_Click” ValidationGroup=”vgNew”/>

Explaination

Echostorm
Thanks, this does work. But where UseSubmitBehaviour turns off the default browser form posting, and uses the ASP.NET form posting, I'm kind of nervous about a MS specific technique instead of the conventional way of doing things. Do you know if there are any repercussions to using this? thx again
John MacIntyre
none that I've seen. Glad to help
Echostorm
This has worked perfectly in my solutions. Thanks Echostorm.
jwalkerjr
+1  A: 
document.getElementById('form1').onsubmit = function() {
    document.getElementById('btn').disabled = true;
};
I.devries
This does not work and is the code the user was asking to fix. -1
Hogan
no, this is on the onsubmit of the form instead of the onclick of the button. This way it WILL submit the form. But thanks for the downvote
I.devries
A: 

Make sure that your javascript function returns true (or a value that would evaluate to boolean true), otherwise the form won't get submitted.

function btn_click()
var chk = document.getElementById("chk");
    if(chk.checked)
    {
            var btn = document.getElementById("btn");
            btn.disabled = true;
            return true;   //this enables the controls action to propagate
    }
    else    return false;  //this prevents it from propagating
}
tj111
Thanks tj111, but I dont' think the event bubbling is being interupted, since it does postback until I check the button.
John MacIntyre
I ran into the same problem and my first try was this solution. It didn't work on IE, however. I had to go with the solution Vatos explained, i.e. form submit instead of button click.
OregonGhost
+3  A: 

UseSubmitBehavior="false" converts submit button to normal button (<input type="button">). If you don't want this to happen, you can hide submit button and immediately insert disabled button on its place. Because this happens so quickly it will look as button becoming disabled to user. Details are at the blog of Josh Stodola.

Code example (jQuery):

$("#<%= btnSubmit.ClientID %>").click(function()
{
  $(this)
    .hide()
    .after('<input type="button" value="Please Wait..." disabled="disabled" />');
});
Pavel Chuchuva
This solution worked well for us... especially when you need the input value to still be included in the the form. Thanks!
J.13.L
A: 

We use the following JQuery script, to disable all buttons (input type=submit and button), when one button is clicked.

We just included the script in a global JavaScript file, so we don't have to do remember anything when creating new buttons.

$(document).ready(function() {
    $(":button,:submit").bind("click", function() {
        setTimeout(function() {
            $(":button,:submit").attr("disabled", "true");
        }, 0);
    });
});

This script could easily be extended with a check for Page_ClientValidate().

Thomas Jespersen