title: ASP.NET - Client-Side OnClick Event of Button is Breaking Page Validation
body: <p>I have a button on a form that saves a unique value to my database and to prevent the user from submitting twice and getting an error I added some JavaScript logic to do a client-side disable of the button after it is clicked.  Functionally this all works, but it created an unexpected side effect that field Validation is being fired on a control with a completely different validation group that the one I submitted. If I remove my custom OnClick attribute the page behaves as it should once again. If you take a look at item 3 in <a href="http://www.abstraction.net/ViewArticle.aspx?articleID=80" rel="nofollow noreferrer">this article</a> you'll see that issue has been noticed by others as well.</p>
  
  <p>After testing the issue carefully I noted that the exact problem is a result of changing the button to <code>disabled = true</code> in the client. Given this dilemma I'm forced to resort to a server-side solution to the problem I am facing, but I cannot help but wonder why this is happening in the first place. Is this a bug in ASP.NET?</p>
  
  <p>If you'd like to see exactly what's going on, here's <a href="http://www.nathantaylor.name/demos/ValidationBug.aspx" rel="nofollow noreferrer">an example</a>, and here's the code:</p>
  
  <pre><code>&lt;%@ Page Language="C#" %&gt;
  
  &lt;script runat="server" language="C#"&gt;
      void Page_Load(object sender, EventArgs e)
      {
          if (!IsPostBack)
          {
              this.Button1.Attributes["onclick"] = string.Format("DisableOnSubmit('{0}','{1}');", this.Button1.ClientID, this.Button1.ValidationGroup);
          }
      }
  
  &lt;/script&gt;
  
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head runat="server"&gt;
      &lt;title&gt;&lt;/title&gt;
  
      &lt;script type="text/javascript"&gt;
          function DisableOnSubmit(btn, group) {
              if (btn &amp;&amp; group) {
                  if (Page_ClientValidate(group)) {
                      var btnElement = document.getElementById(btn);
                      if (btnElement) {
                          btnElement.disabled = true;
                          btnElement.value = 'Saving...';
                      }
                  }
              }
          }
      &lt;/script&gt;
  
  &lt;/head&gt;
  &lt;body&gt;
      &lt;form id="form1" runat="server"&gt;
      &lt;div&gt;
          &lt;asp:TextBox ID="TextBox1" runat="server" ValidationGroup="group1"&gt;Initial Value&lt;/asp:TextBox&gt;
          &lt;asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="This should come up if the first field is empty."
              ValidationGroup="group1" ControlToValidate="TextBox1"&gt;&lt;/asp:RequiredFieldValidator&gt;
          &lt;asp:Button ID="Button1" runat="server" Text="Click Me!" ValidationGroup="group1" /&gt;
          &lt;br /&gt;
          &lt;br /&gt;
          &lt;asp:TextBox ID="TextBox2" runat="server" ValidationGroup="group2"&gt;&lt;/asp:TextBox&gt;
          &lt;asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="You shouldn't ever see me."
              ValidationGroup="group2" ControlToValidate="TextBox2"&gt;&lt;/asp:RequiredFieldValidator&gt;
      &lt;/div&gt;
      &lt;/form&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>