views:

1554

answers:

2

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 this article you'll see that issue has been noticed by others as well.

After testing the issue carefully I noted that the exact problem is a result of changing the button to disabled = true 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?

If you'd like to see exactly what's going on, here's an example, and here's the code:

<%@ Page Language="C#" %>

<script runat="server" language="C#">
    void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            this.Button1.Attributes["onclick"] = string.Format("DisableOnSubmit('{0}','{1}');", this.Button1.ClientID, this.Button1.ValidationGroup);
        }
    }

</script>

<!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;
<head runat="server">
    <title></title>

    <script type="text/javascript">
        function DisableOnSubmit(btn, group) {
            if (btn && group) {
                if (Page_ClientValidate(group)) {
                    var btnElement = document.getElementById(btn);
                    if (btnElement) {
                        btnElement.disabled = true;
                        btnElement.value = 'Saving...';
                    }
                }
            }
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server" ValidationGroup="group1">Initial Value</asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="This should come up if the first field is empty."
            ValidationGroup="group1" ControlToValidate="TextBox1"></asp:RequiredFieldValidator>
        <asp:Button ID="Button1" runat="server" Text="Click Me!" ValidationGroup="group1" />
        <br />
        <br />
        <asp:TextBox ID="TextBox2" runat="server" ValidationGroup="group2"></asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="You shouldn't ever see me."
            ValidationGroup="group2" ControlToValidate="TextBox2"></asp:RequiredFieldValidator>
    </div>
    </form>
</body>
</html>
+1  A: 

I always found somethings in ASP.Net flimsy and buggy, it's great most of the times though. Maybe this is just one of those things... or I am just not seeing what's wrong.

Either way, I have usually used the server-side code to control things like you are trying to. Since it works it's all good.

aredkid
+1  A: 

Just guess here, but your function DisableOnSubmit doesn't return any value. The onclick event handler usually expect either true or false. I've also experienced problems with buttons that generated a page reload because the javascript in the onclick event didn't work properly. Considering these together, is it possible that clicking the button results simply in a reload instead of a postback? Try returning true from the javascript to test it out.

Also, does Page_ClientValidate have any side effects?

ADB
After submitting the form with an empty second field, checking <code>IsPostBack</code> in <code>Page_PreRender</code> returns true and <code>Page_IsValid</code> returns false. Returning true from the client side code has no effect on the outcome.
Nathan Taylor
Ok. I now understand that the validation that is causing problem is on the client side. You could change that so to be performed on the server instead and drop the call to Page_ClientValidate. Or you could drop the validation altogether for this button and do it manually in your button event handler. Finally, you can implement option 4 of the page your linked to.
ADB