Why doesn't my form post when I disable the submit button to prevent double clicking?
Asked Answered
A

11

10

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">

<html xmlns="http://www.w3.org/1999/xhtml">
<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.

Abroms answered 30/12, 2008 at 15:49 Comment(0)
V
10

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"/>

Explanation

Vocation answered 30/12, 2008 at 16:19 Comment(2)
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 againAbroms
@JohnMacIntyre - I'm sorry, you're worried about a microsoft specific technique in an asp.net control? That seems kind of silly, does it not? asp.net is microsoft specific to begin with.Flitting
T
8

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" />');
});
Trimly answered 27/6, 2009 at 8:49 Comment(1)
This solution worked well for us... especially when you need the input value to still be included in the the form. Thanks!Ahoufe
L
6

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

Lekishalela answered 30/12, 2008 at 16:8 Comment(1)
This link is broken.Jallier
J
4

"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.

Judgeship answered 30/12, 2008 at 15:54 Comment(0)
M
2

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().

Macron answered 30/3, 2010 at 10:44 Comment(0)
L
1
document.getElementById('form1').onsubmit = function() {
    document.getElementById('btn').disabled = true;
};
Losing answered 30/12, 2008 at 16:30 Comment(2)
This does not work and is the code the user was asking to fix. -1Remembrance
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 downvoteLosing
S
1

This is the correct and simple way to do this:

It works in all browsers (unlike the accepted solution above).

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

    Public Shared Sub PreventMultipleClicks(ByRef button As System.Web.UI.WebControls.Button, ByRef page As System.Web.UI.Page)
        button.Attributes.Add("onclick", "this.disabled=true;" + 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, page)

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!

Shape answered 29/10, 2011 at 15:56 Comment(1)
adding javascript to buttons onClick in the html should be avoidedShape
S
1

FOR JQUERY USERS

You will get into all sorts of problems trying to add javascript directly to the onClick event on ASP.NET buttons when using jQuery event listeners.

I found the best way to disable buttons and get the postback to work was to do something like this:

    $(buttonID).bind('click', function (e) {

        if (ValidateForm(e)) {

            //client side validation ok!
            //disable the button:
            $(buttonID).attr("disabled", true);

            //force a postback:
            try {
                __doPostBack($(buttonID).attr("name"), "");
                return true;
            } catch (err) {
                return true;
            }

        }
        //client side validation failed!
        return false;
    });

Where ValidateForm is your custom validation function which returns true or false if your form validates client side.

And buttonID is the id of your button such as '#button1'

Shape answered 31/10, 2011 at 18:3 Comment(0)
A
0

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

Achromatic answered 30/12, 2008 at 16:1 Comment(3)
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?Abroms
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.Achromatic
Oh ok. No it is definitely disabling the button, but then doesn't submit the post. Thanks again.Abroms
H
0

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
}
Hatteras answered 30/12, 2008 at 16:47 Comment(2)
Thanks tj111, but I dont' think the event bubbling is being interupted, since it does postback until I check the button.Abroms
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.Cristacristabel
F
0

One can also try the following way to prevent double clicking of the "SUBMIT" Button:

.buttonload {
    background-color: lightgrey; /* Grey background */
    border: none; /* Remove borders */
    color: black; /* Black text */
    padding: 12px 24px; /* Some padding */
    font-size: 16px; /* Set a font-size */
}

/* Add a right margin to each icon */
.fa {
    margin-left: -12px;
    margin-right: 8px;
}
<!DOCTYPE html>
<html>
<head>
    <!-- Add icon library -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
    <script type="text/javascript">
        $(function () {
            SubmitButton = $("#btn");
            SubmitButton.on("click", function () {
                result = ValidateRecords();
                if (result) {
                    $(this)
                        .hide()
                        .after('<button disabled class="buttonload"><i class= "fa fa-spinner fa-spin"></i>Processing Data...</button >');
                }
            });
        });

        function ValidateRecords() {
            var DateTime = document.getElementById('lit').value;
            if (!DateTime.trim()) {
                return false;
            }
            else {
                return true;
            }
        }
    </script>
</body>
</html>

EXPLANATION(In Order of Code Appearance above):

  • CSS : Handles the spinner element used as part of the icon tag in the replaced button.
  • Adding the Icon Library in header is mandatory in case if you want to use the icon class fa-spinner.
  • In the script tag Validate method is called to check if all the mandatory form elements are filled prior clicking the submit button
  • Post the validation is successful, I am hiding the submit button[.hide()] and replacing with another button[.after()].
  • Setting the DISABLED property on the new button is mandatory or else it will work as an active button.

NOTE: I have used Button to replace the submit Button. But you can use input text or any other suitable element as per your requirements

Fretwell answered 1/9, 2022 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.