February 2008
Posted on the 1st at 12:40 AM CST
How to Disable the Submit Button of a Web Form
FiledFiled under ASP.NET, Javascript

I know it has been kinda quiet around here lately, and tonight I finally got some time to post a solution to a legendary web application problem (I also rolled out a few updates to my blog, as you may have already noticed). The issue at-hand probably gets most of its exposure through the use of the ASP.NET framework. On a web form, it is often a requirement to prevent multiple form submissions to maintain efficiency and avoid complications on the server-side. The most visually appealing way to accomplish this is by disabling the submit button as soon as the form submits, essentially stopping the user from going on a clicking spree. Seems like such a trivial task, but unfortunately doing it the normal way will cause problems.

The Problem

When an HTML form gets submitted, an HTTP POST is automatically generated and shipped off to the form tags "action" value. This POST data is obviously comes from the form elements, and this is how data gets from your computer to the server. For example, imagine I have a form with two textboxes and a submit button…

<!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">
<head>
  <title>Test Page</title>
</head>
<body>
  <form id="frmTest" runat="server">
    <asp:TextBox ID="txtBox1" runat="server" Text="Test1"></asp:TextBox>
    <asp:TextBox ID="txtBox2" runat="server" Text="Test2"></asp:TextBox>
    <asp:Button ID="btnSubmit" runat="server" Text="Submit" />
  </form>
</body>
</html>


When that form gets submitted, the following POST is generated (note that I removed the ViewState and EventValidation data, as well as a couple irrelevant HTTP headers from the following POST examples for brevity)…

    POST /Sandbox/default.aspx HTTP/1.1
    Connection: Keep-Alive
    Content-Length: 44
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)

    txtBox1=Test1&txtBox2=Test2&btnSubmit=Submit


In case you are not familiar with POST, the bottom line is the actual data. You can see it is a simple collection of name/value pairs. When a control within the form is disabled, it no longer becomes a part of the POST. A disabled control is meant to be read-only, so it saves space by not including them with the POST. And there inlies the problem. Here is the same HTTP post outlined above, except this time I disable the submit button with Javascript once it gets clicked…

    POST /Sandbox/default.aspx HTTP/1.1
    Connection: Keep-Alive
    Content-Length: 44
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)

    txtBox1=Test1&txtBox2=Test2


You will notice on the bottom line of the POST that the btnSubmit parameter is no longer being passed. You wouldn't think that this would cause a problem, since all of the data inputted by the user still made it to the server. However, ASP.NET takes this button value much more seriously. Typically, you would have some code-behind for the button click event to process the form…

Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
    'Form processing logic is here
End Sub


ASP.NET will only invoke this click event when the submit button's value is included in the POST. I believe the EventArgument value also has something to do with it, but that's another story for another day. Without that value in the POST, your Page_Load will still get fired, but the code in your button's click event handler will never execute. Granted, you could put some crap code in your Page_Load to look for the existence of certain parameters in the request and react to that accordingly. I think it's safe to say that is nothing close to a reasonable solution. There are a few solutions I have stumbled across, most of which I saw in an ASP.NET forums. None of them were very appealing to me because they required tedious server-side logic that would obviously be a bitch to maintain. I hate wasting time doing maintenace (who doesn't?), so I couldn't settle for that. I wanted a solution that had nothing to do with server-side code; a task this trivial shouldn't! I wanted something that could be implemented on existing forms painlessly. And lastly, I wanted something that could easily be extended and configured to accomodate specific scenarios.

The Basic Idea of My Solution

It's pretty simple, actually. Instead of disabling the submit button itself, I just hide it with Javascript. This is only modifying the style of the control, so the value still comes through with the POST. Then I programatically create a disabled <button> tag with the message of my choice and insert it into the DOM, right before the actual submit button. It will happens so quickly that it will appear that the submit button had been disabled, and it's value changed. Works like a charm!

I have setup a really simple example of this, nothing but pure HTML with all the basic Javascript directly in the markup so you can see the general idea of how it works. That example is not dynamic at all, and it's fairly obtrusive. With that said, I have a much cleaner solution that I'd like to share with you.

Doing Things the Right Way

I finally got some time to do what I wanted with this idea. I created an unobtrusive object model that automatically does everything for you. Once the page loads, it loops through every form and attaches another onsubmit handler to the existing one. If no onsubmit handler exists, or if the existing handler returns true, it will loop through each input element within that form (starting with the last one) and disable each submit button (using the method described above). More specifically, it will disable each <input type="submit"> and <input type="image">. It is designed to stop the loop when it encounters the first textbox for the sake of efficiency, but I have set up a configuration option to toggle that. There is also an option to hide all other buttons on the form when it gets submitted, if they exist (<input type="reset"> and <input type="button">). I put one more option in there to change the document cursor to the "Waiting" icon once the button becomes disabled. I figured that would be one final visual indicator for the user. I put some comments in there explaining the configuration options. The options themselves are directly at the top of the object. Here is the code…

function addLoadEvent(func) {
  if(typeof window.onload != 'function')
    window.onload = func;
  else {
    var oldLoad = window.onload;

    window.onload = function() {
      if(oldLoad) oldLoad();
      func();
    }
  }
}

 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *                     Button Disabler                         *
  *                       Version 1.0                           *
  *                 Written by Josh Stodola                     *
  *                     January 29, 2008                        *
  *                                                             *
  * * * * * * * * * *CONFIGURATION OPTIONS* * * * * * * * * * * *
  *                                                             *
  *   IsTesting  (Boolean, defaults to false)                   *
  *     When this is set to true, the form will never submit.   *
  *     Use this to confirm that the script is working.         *
  *                                                             *
  *   DisabledButtonValue  (String, defaults to 'Please Wait')  *
  *     This is the value to show on the button once disabled.  *
  *                                                             *
  *   HideNonSubmitButtons  (Boolean, defaults to true)         *
  *     When true, the script will also hide any reset buttons  *
  *     or Javascript buttons it encounters.                    *
  *                                                             *
  *   ShowHourglassCursor  (Boolean, defaults to true)          *
  *     When true, the script will change the cursor to the     *
  *     OS-defined "waiting" symbol to indicate loading.        *
  *                                                             *
  *   StopLoopAtFirstTextbox  (Boolean, defaults to false)      *
  *     When true, the script will stop looping through input   *
  *     elements once it encounters the first textbox. The loop *
  *     begins at the bottom of the form. This can be set to    *
  *     true to make the script more efficient.                 *
  *                                                             *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var ButtonDisabler = {
  IsTesting: true,
  DisabledButtonValue: 'Please Wait',
  HideNonSubmitButtons: true,
  ShowHourglassCursor: true,
  StopLoopAtFirstTextbox: false,

  IsCapable: (document.getElementById && document.createElement),
  AddSubmitEvent: function(frm, func) {
    if(typeof frm.onsubmit != 'function')
      frm.onsubmit = func;
    else {
      var oldSub = frm.onsubmit;

      frm.onsubmit = function() {
        if(oldSub) {
          if(oldSub())
            return func();
          else
            return false;
        }
        else
          return func();
      }
    }
  },
  LoadEventHandlers: function() {
    if(ButtonDisabler.IsCapable) {
      for(var i = 0; i < document.forms.length; i++) {
        var frm = document.forms[i];

        ButtonDisabler.AddSubmitEvent(frm, function() {
          ButtonDisabler.DisableForm(frm);
          return !ButtonDisabler.IsTesting;
        });
      }
    }
  },
  DisableForm: function(frm) {
    if(!frm) return;
    var inputs = frm.getElementsByTagName('INPUT');

    for(var j = inputs.length - 1; j >= 0; j--) {
      var elem = inputs[j];

      if(elem.type == 'submit' || elem.type == 'image') {
        var btn = document.createElement('button');

        btn.disabled = true;
        btn.innerHTML = ButtonDisabler.DisabledButtonValue;

        elem.parentNode.insertBefore(btn, elem);
        elem.style.display = 'none';
      }

      if(elem.type == 'reset' || elem.type == 'button') {
        if(ButtonDisabler.HideNonSubmitButtons)
          elem.style.display = 'none';
      }

      if(elem.type == 'text' && ButtonDisabler.StopLoopAtFirstTextbox)
        break;
    }

    if(ButtonDisabler.ShowHourglassCursor)
      document.body.style.cursor = 'wait';

    frm.onsubmit = function() {
      return false;
    }
  }
};

addLoadEvent(ButtonDisabler.LoadEventHandlers);

How to Use the Script

This best part of this script is its ease-of-use. All you have to do is setup the options however you prefer, and import the Javascript into your web page markup (usually in the <head> section) with <script> tags and the script will do the rest. I have tested it in all modern browsers and it works fantastic. I have also tested it with a series of the ASP.NET validator controls and several of my custom form validation methods, all without any problems. There are a few other things you should know about this script…

Web Pages with Multiple Forms
This script is designed to handle pages with multiple forms without any problems. Submit buttons will be disabled on a per-form basis. So, if you submit FormA, FormB will still have a visible, enabled, clickable submit button.
Forms with Multiple Submit Buttons
The script is also designed to handle forms with multiple submit buttons. Once submitted, each and every submit button within the form will become disabled. It does this because the overall purpose is to prevent multiple form submissions. When a form has multiple submit buttons, each of them will submit the same form when clicked, so we must disable them all to achieve the desired effect.

That's it! I have probably read dozens of threads on the ASP.NET forums regarding this problem, and now I am glad that I have solution in place to point people to. Most scripts are not perfect, so if you encounter any kind of oddity or bug that is worth questioning, please feel free to let me know about it through the comments form below.

'Til next time…

Comments (49)
Permalink Comment from Mischa Kroon on February 1st, 2008 at 3:25 AM
I don't get it, when the button is disabled you don't get it in the post.

Which shouldn't be a problem because it can't be clicked because it has been disabled.

So what did I miss ?
Permalink Comment from Josh StodolaEmail on February 1st, 2008 at 7:39 AM
It needs to come in with the POST, that is the problem. The button gets disabled AFTER it has already been clicked. I said this in the post: "ASP.NET will only invoke this click event when the submit button's value is included in the POST".

So, without the value in the POST, the server-side click event will not fire.
Permalink Comment from SeanEmail on February 1st, 2008 at 1:23 PM
PART 1

I use Google's personalized home page to watch for updates on blogs (including this one) and such. When I clicked on the link for this entry, I was directed to "blog.josh420.com/archives/2008/02/how-to-disable-the-submit-button-of-web-form.aspx", which lead me to see "That post was not found!".

I noticed that the actual URL for this page is "blog.josh420.com/archives/2008/02/how-to-disable-the-submit-button-ofweb-form.aspx". The difference lies between the word "of" and "web". Google's link has a dash, the real URL does not.

The weird part is that I used Google's link to view this earlier, or so I thought.

Did you change the page name or URL recently?


PART 2
That's a neat trick that you outline above. I'll keep it in mind for future projects where multiple submits maybe an issue.
Permalink Comment from Josh StodolaEmail on February 1st, 2008 at 1:53 PM
Hi Sean,

Yes, there was a URL rewriting discrepency that caused the post to be inaccessible from my RSS feed, Digg, or DotNetKicks. The problem was with the way it interprets the "a" in the blog title. Because of a silly code error (lack of sleep), it did not strip it out appropriately. I fixed my blog and re-deployed it to the server. Then when I went to update the blog post (I noticed a typo), it corrected the permalink! I never intended to EVER update the permalink field of any blog post after it gets published, so I dont know when I put that code in there or why.

The post was still on the front page of my blog, but all external links were incorrect. I'm embarassed to say that it was like this for about 8 hours. I just changed the subject URL back to what it was before, even though it's not how it really should be. But, I guess permalink means permanent, right?
Permalink Comment from Josh StodolaEmail on February 1st, 2008 at 2:05 PM
I've thought about this situation for a few moments now, and I think I got a plan. I can keep track of every time a blog post title gets updated in a separate MySQL table (1 field for PostID, 1 field for the old PostTitle), and then when a request comes in and the post is not found naturally, I can search that table for the entry that could not be found. If it finds a match, I take the PostID and get the correct permalink and do an automatic 301 redirect. Beautiful!
Permalink Comment from Dave on February 6th, 2008 at 2:09 AM
Hey, Josh.

You can actually do this easier, using the UseSubmitBehavior property of the Button control (in ASP.NET 2.0+). It basically causes the button to __doPostBack instead of relying on the form submission behavior of the browser, leaving you free to disable it on the client side and not interfere with the postback.

http://encosia.com/2007/04/17/disable-a-button-control-during-postback/
Permalink Comment from Josh StodolaEmail on February 6th, 2008 at 9:26 AM
Hi Dave, and thanks for commenting. I have seen that approach on the forums as well. Thanks for posting a link, it's nice to have a collection of methods here so that other visitors can pick and choose what suits their needs best.

The problem I have with any kind of server-side approach to this is that it requires the _doPostback function. I think with the new MVC framework, developers are trying to get rid of this postback/viewstate stuff and are going back to the classic, proven method(s). It also does not seem right for the server-side to have anything to do with a subtle visual enhancement such as this. And maybe this is me being picky, but I don't want inline Javascript at all. I like to keep things as unobtrusive as possible; behavioral separation has numerous benefits. The only inline script you will find on this blog is for the CAPTCHA and the comments with displayed email addresses.

Thanks again for the comment, and have a great day!
Permalink Comment from Ilan on February 11th, 2008 at 1:56 AM
Hi Josh,
I have been looking every where for an "all included solution" like yours.
Sadly i tried it on my site and found that
while using the ASP.NET validation controls with a
validation summary the "disabled button" gets stuck and doesn't let the user fix his input and resubmit.
is there a way that i can check client page validation before invoking your function. Something like the Page.IsValid in C#?
Thanks Ilan
Permalink Comment from Dave on February 14th, 2008 at 7:15 PM
Due to bug 341, I wouldn't dare use the button element in any application in a production environment. Every other browser will not send the innerHTML garbae that IE sends.
See bug report here.
http://webbugtrack.blogspot.com/2007/10/bug-341-button-element-submits-wrong.html
Permalink Comment from Josh StodolaEmail on February 14th, 2008 at 8:59 PM
Thanks for the comment. Although, the <button> tag is inserted into the DOM as a DISABLED control. Any disabled control will not be included in the POST. Therefore, this approach is great.

Regardless, who cares about the garbage that IE sends? It's irrelevant, correct? The server does not give a shit about what this new disabled element will generate. As long as the normal submit button makes its way through, everything will get processed perfectly.

Please tell me if I am wrong. Best regards...
Permalink Comment from Tom Dyer on March 14th, 2008 at 9:33 AM
I love this solution, it is really elegant... but I have a problem....

My form is AJAX enabled and uses an updatepanel. This way, the window.onload function only actually fires once on the first load. At this point the 'Please wait' functionality works perfectly. Problem is every other time I click the button it doesn't work. I had a quick whizz around t'Internet and found a little message board post suggesting using Sys.Application.add_load() instead of window.onload so that the js runs on every postback from the updatepanel but I can't figure out how to modify your script.

Are you able to help at all?
Many thanks in advance

Tom.
Permalink Comment from Josh StodolaEmail on March 14th, 2008 at 11:47 AM
Hi Tom, and thanks for stopping by. What you can try is this...

Remove the bottom line from my script: addLoadEvent(ButtonDisabler.LoadEventHandlers);

In your code-behind, try something like:
Dim Script as String = "Sys.Application.add_load(ButtonDisabler.LoadEventHandlers);"
ClientScript.RegisterStartupScript(Me.GetType(), "load", Script, True)

Please let me know if that works, and I will update the post accordingly. I also have an update to make to the post regarding validation summaries (much thanks to Ilan).
Permalink Comment from Tom Dyer on March 17th, 2008 at 3:52 AM
Hi Josh,

Well I gave it another couple of tries but to no avail.

I popped the above code into the page_load and the updatepanel_load
code behind but it wouldn't play.

After this failed I also tried Sys . UI . DOMEvent . AddHandler to catch the updatepanel load event and pop your script but this didn't work either and kept telling me that the DOM it was trying to catch was NULL or not yet set... I tried this code in a few different places including the 2 methods above and the click event of the button itself but always the same error.

I am all out of ideas (and time for now) though so it is either get rid of the updatepanel or trust the user (LOL!!!!)

Thanks again anyway.
Tom.
Permalink Comment from Tom Dyer on March 18th, 2008 at 6:30 AM
I figured it out Josh, I have emailed you the solution as the scripting was failing spam prevention on here...

Thanks
Tom.
Permalink Comment from Tom Dyer on March 22nd, 2008 at 12:40 PM
I found some time so I have made a technical video blog and I have just posted the update panel solution to this as the first video.

http://tech.kruelintent.com/player.aspx?vid=1

Thanks
Tom.
Permalink Comment from Josh Stodola on March 23rd, 2008 at 2:21 PM
Tom, you are the man! Thanks so much for taking the time to do that. Have a Happy Easter!
Permalink Comment from Sorin Serban on March 27th, 2008 at 3:01 AM
Good to see someone bumped into this also. Gonna try it soon
Permalink Comment from DaveyP on April 30th, 2008 at 6:47 AM
Works perfectly. How would I get it to disable all buttons, but leave the text for all except the one pressed as it is? My Javascript is nonexistant.

Ta
Permalink Comment from Josh StodolaEmail on April 30th, 2008 at 7:38 AM
DaveyP: I will get back to you on this later this evening.
Permalink Comment from Davey on May 1st, 2008 at 11:09 AM
Cheers
Permalink Comment from Mikel on May 14th, 2008 at 3:17 PM
Awesome, you have just made my day :)
Permalink Comment from Mangesh Patil on May 21st, 2008 at 4:10 AM
Hi,
Current script does not work if I have scriptManager tag in my form.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

Could you send me the updated script for the same.
Permalink Comment from deblendewim on May 22nd, 2008 at 8:29 AM
Testing the captcha
Permalink Comment from lavanya on June 4th, 2008 at 11:52 PM
I tried your script itworks great. But I have problem on firefox.

I have assessment test page once student checks answerchoice and hit on submit button, i was to hide the continue button.

Works great on IE. On fire fox when i hit the continue button it wont let me go to next question same question repeats again.
Permalink Comment from lavanya on June 5th, 2008 at 11:19 AM
Can you please let me know who to do for a specific submit button? Thanks.
Permalink Comment from Josh StodolaEmail on June 5th, 2008 at 12:46 PM
To do a specific button, you will have to change the DisableForm function. Just change this line...
    var inputs = frm.getElementsByTagName('INPUT');

To this...
    var inputs = new Array();
    inputs[0] = document.getElementById('YOUR_BUTTON_ID');

You may need to view the source of your rendered page to get the correct button ID. Hope this helps! I'm not sure what your other problem could be in Firefox.
Permalink Comment from lavanya on June 6th, 2008 at 2:13 AM
I tried it. it dosent work same page refreshes again. i can see the please wait button but nothing happens.

here is the another code i used. I am able to take the test but not able www.codeproject.com/…/OneTimeClickableButton.aspx hide the button but style.visibility property. Thanks alot.
Permalink Comment from lavanya on June 6th, 2008 at 7:38 AM
Hi Josh,
I dont have any text boxes in the form. can I eliminate the following code? How do I break the loop? please let me know.

if(elem.type == 'text' && ButtonDisabler.StopLoopAtFirstTextbox)
break;
Permalink Comment from lavanya on June 7th, 2008 at 7:48 PM
I am able to solve my problem. Thanks for the solution.
Permalink Comment from Sameer KulkarniEmail on July 2nd, 2008 at 4:59 AM
If there already exist a onLoad Event on the body tag the code mentioned above does'nt work.
Please suggest an alternative way to do so.
Permalink Comment from Blogging Developer on July 3rd, 2008 at 6:07 AM
Here is my article about how to disable form submit on key press: http://www.bloggingdeveloper.com/post/Disable-Form-Submit-on-Enter-Key-Press.aspx

An alternative approach to the problem :)
Permalink Comment from Josh StodolaEmail on July 11th, 2008 at 8:49 PM
@Sameer: you are correct, that does cause problems. What you need to do is execute your code on the window onload event instead like this...

  window.onload = function() {
    //Your body onload code here
  }

Thanks for pointing this out, and I am sorry for the delayed response.
Permalink Comment from Mark Brandsey on September 3rd, 2008 at 12:16 PM
Josh, this is something I need for my project but I also have a script manager on the form so it does not work. I tried the url posted above by Tom but the url does not work either. Could you please send me the fix that Tom figured out. Thanks
Permalink Comment from Josh StodolaEmail on September 3rd, 2008 at 12:47 PM
Hi Mark! Sorry I cannot recall the fix. I meant to update the post but time always gets the best of me. I will try to email Tom and see if he remembers the solution. I'll come back here when he responds and fill you in.

Sound fair?
Permalink Comment from Josh StodolaEmail on September 3rd, 2008 at 5:04 PM
OK, I heard back from Tom and he still has the demo video out on the web, but the link he posted is wrong. The new link is here: http://tech.kruelintent.com/player.aspx?vid=1

Mark, please let me know if this has resolved your issue.
Permalink Comment from TomEmail on September 5th, 2008 at 11:57 AM
Hi guys,

I have just noticed that the video URL has changed so I have updated it and now the video works just fine.

In a nutshell, it was all about catching the beginning and end of the request using sys instead of just the pageload. It is all explained in the video.

Cheers
Tom

http://tech.kruelintent.com
Permalink Comment from Mark Brandsey on September 9th, 2008 at 4:42 PM
I did get the issue resolved Josh. Thanks for your help regarding this. I found an easier fix on the net.

Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder
'This forces the page validation, if any, to execute.
sb.Append("if (typeof(Page_ClientValidate) == 'function') { ")
sb.Append("if (Page_ClientValidate() == false) { return false; }} ")
'Changes the text of the button. Gives the user a processing message.
sb.Append("this.value = 'Processing...';")
'Prevent the button from being pressed a second time.
sb.Append("this.disabled = true;")
'Forces the page to postback.
sb.Append(Me.ClientScript.GetPostBackEventReference(Me.btnAttachDoc, btnAttachDoc.ID))
sb.Append(";")
Me.btnAttachDoc.Attributes.Add("onclick", sb.ToString())

Cheers Mark
Permalink Comment from Josh StodolaEmail on September 9th, 2008 at 4:47 PM
Thanks for the update, Mark! I am happy to hear your issue is now resolved.
Permalink Comment from Arun on October 22nd, 2008 at 11:31 PM
Permalink Comment from David on October 27th, 2008 at 2:33 PM
Like this solution, but I can't get it to work with ValidationGroups. The pages buttons should only be disabled if the validators in the clicked buttons validation group is valid.
Is there an easy fix for this?
Permalink Comment from webform on December 25th, 2008 at 1:32 AM
Nice blog !

Good job, Thanks for the information
Permalink Comment from xuxu on March 5th, 2009 at 11:35 AM
please tell me how to send a click event to a submitbutton with vb.net, code is apreciated.
i need some data from a website to display on my program, i could fill in all text to a textbox of that webpage but i cant send to button validate with click event. Inthe source code of the page i found the name and the id of the button, its type is "submitbutton". im newbie please helip, many thanks.
Permalink Comment from val on March 19th, 2009 at 2:00 PM
hi, Josh.
I am trying to use this solution on my jsp page that contains Multiple Forms. Each form have own validation javascript. I have 2 issues:

1. it can't break the loop with following code
if(elem.type == 'text' && ButtonDisabler.StopLoopAtFirstTextbox)
break;
so I used this instead:
if(elem.type != 'submit')
break;
Am I doing it right?

2. The page stuck after the submit and disable the button, it doesn't goes to server side. How should I modify the onsubmit?
frm.onsubmit = function() {
return false;
}

Thanks!!
Permalink Comment from Josh StodolaEmail on March 19th, 2009 at 4:08 PM
If you want it to break at the first textbox, you have to set the correct variable towards the top of the script, like this:

StopLoopAtFirstTextbox: true,

If your native onsubmit function returns false, then of course the form will not submit to the server-side. Returning false literally cancels the submission.
Permalink Comment from Randy on March 26th, 2009 at 1:28 PM
Great thread. I am having difficulty summing it up, though. Would you mind doing so? Is there one bullet proof solution to the problem of disabling buttons on a form during submit? Are there different bullet proof solutions, depending on whether validation controls or Ajax is being used? Thanks!
Permalink Comment from KenPalmer on April 20th, 2009 at 3:42 PM
Thanks for the great thread Josh. Your insight into disabled buttons being dropped from the HTTP POST header was a huge help. I implemented a JavaScript-only approach that works on a standard ASP.Net page with one form, though it could be extended for multiple forms. It's untested for Ajax and MVC. Since it's all client-side, this could be adapted to non-ASP.Net applications as well.

With this approach call the AddDisableEventToSubmitButtons() function in <body onLoad>. That function finds all the submit elements on the form and adds an onClick event to call the DisableSubmitButtons() method when a button is clicked. When a submit button is clicked, DisableSubmitButtons() iterates through the submit elements and disables all of them EXCEPT for the button that was clicked.

The clicked button doesn't get disabled. Rather, its click event gets sabotaged by making the button return false whenever it is selected. Once that button is clicked, it doesn't matter how long the postback takes because that button's click event is effectively disabled.

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

function AddDisableEventToSubmitButtons() {
// Call this from <body onLoad>
DocForm = document.forms[0];
for (var i=0; i < DocForm.elements.length; i++) {
el = DocForm.elements[i];
if (el.type.toLowerCase() == "submit")
{
// To prevent a clicking spree during slow postbacks.
el.onclick = function() { DisableSubmitButtons(this.id) };
}
}
}

function DisableSubmitButtons(ButtonID) {
DocForm = document.forms[0];

// Decremental loop since submit buttons typically appear at the end of a form.
for (var i = DocForm.elements.length-1; i > -1; i--) {
el = DocForm.elements[i];
if (el.type.toLowerCase() == "submit")
{
if (el.id == ButtonID) {
// Don't disable the submitting button or it will be removed from the HTTP POST header that ASP.Net depends upon for button event detection.
// Instead, sabotage the click event of the submitting button to sap its power.
el.onclick = function() { return false };
} else {
el.disabled = true;
}
}
}
DocForm.submit();
}

</script>
Permalink Comment from Jon on June 9th, 2009 at 3:15 PM
Thanks so much. I spent hours and hours trying to figure out how to do this, until I finally stumbled upon your page.
Permalink Comment from David Jafferian on June 25th, 2009 at 11:19 PM
Hi Josh -

I have an onSubmit handler which performs a form validation that requires a lot of processing time. I want to display a "please wait" message of some sort while the handler runs, but no matter what changes are made to the DOM, the display is not updated until the handler returns. So your script doesn't solve my problem. Let me know if you get any other ideas.
Permalink Comment from Andrew on July 23rd, 2009 at 3:25 AM
Works great and so simple to implement, thanks!

Guess What?

There are a few basic guidelines you should be aware of before leaving a comment…

  • If you choose to display your email address, it will not be detected by spam bots
  • Comments are limited to 3,000 characters; so far you have used none of them
  • HTML will be encoded; links and line breaks will be converted automatically
  • Comments containing five or more links will be subject to moderation

Have Your Say

← Answer this to prove you are human
 
 

Chill Out…

No Trackbacks