ASP.NET - Disabling the submit button to prevent double submissions

Flattr this

If a user clicks on a form submit button and the page response is slow, the user may often re-click that button. Because the original request has already been submitted, you may find that the user has made a double submission. In e-commerce sites, the double submission of a credit card payment may be very unpopular with your customers. 


This is a common problem faced by web developers, and there are a variety of ways to try to prevent it. However, I have not seen a really elegant way to solve the problem, so I set about trying to find a simple and effective solution.

There were some key issues I wanted to address:
  1. I wanted to disable the button when it was clicked, but only if the page was valid
  2. I did not want to manually add code to every button in my application
  3. I did not want to break the existing validation, especially when using validation groups
  4. I wanted to preserve the CausesValidation property
To achieve these goals, I set about creating a custom button that inherited the standard ASP Button. This custom button would replace the existing buttons in my application.

First add a new class to your App_Code directory called "EnhancedButton" and then override the OnPreRender event:

   1:  namespace Junto.WebControls
   2:  {
   3:      /// 
   4:      /// If CausesValidation then check the current ValidationGroup is valid
   5:      /// and if so, disable the button.
   6:      /// 
   7:      [ToolboxData("<{0}:EnhancedButton runat=server>")]
   8:      public class EnhancedButton : Button
   9:      {
  10:          protected override void OnPreRender(EventArgs e)
  11:          {
  12:              if (this.CausesValidation)
  13:              {
  14:                  StringBuilder sb = new StringBuilder();
  15:                  sb.Append("if (typeof(Page_ClientValidate) == 'function') { ");
  16:                  sb.Append("if (Page_ClientValidate('" + this.ValidationGroup + "') == false) { return false; }} ");
  17:                  sb.Append("this.value = 'Please wait...';");
  18:                  sb.Append("this.disabled = true; ");
  19:                  sb.Append(this.Page.GetPostBackEventReference(this));
  20:                  sb.Append(";");
  21:                  this.Attributes.Add("onclick", sb.ToString());
  22:              }
  23:   
  24:              base.OnPreRender(e);
  25:          }
  26:      }
  27:  }

Now, we add the following to our web.config to take advantage of the tagMapping feature:

   1:  <pages>
   2:      <controls>
   3:          <add tagPrefix="Junto" namespace="Junto.WebControls" />
   4:      controls>
   5:      <tagMapping>
   6:          <add tagType="System.Web.UI.WebControls.Button" mappedTagType="Junto.WebControls.EnhancedButton" />
   7:      tagMapping>
   8:  pages>

The result is that all instances of standard Buttons are replaced with our new Enhanced custom button. You have no need to add extra code in every Page_Load. The Tag Mapping takes care of replacing the standard button across the web application.

And VoilĂ , our job is done!


0 comments:

Post a Comment

Copyright © 2008 - Ben Powell - is proudly powered by Blogger
Smashing Magazine - Design Disease - Blog and Web - Dilectio Blogger Template