Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Single ClientValidationFunction for Multiple Dynamic CustomValidator and CheckBox

0.00/5 (No votes)
2 Dec 2010 1  
Single ClientValidationFunction for Multiple Dynamic CustomValidator and CheckBox

I have been using CheckBoxes and CustomValidators for quite some time now, but never did I know that I will be presented with an issue that I never encountered before and that issue is regarding dynamic CheckBoxes and dynamic CustomValidators. To give you an idea of what I am talking about, if you had developed a website that has that “Agree to Terms and Conditions” required before continuing, then your guess is a bit near. The only difference is making the items dynamic where these questions are pulled from the database, that database table also defines whether the tick is required or not.

For the first scenario (non dynamic), it's easy as you only need these controls:

ASP.NET
<asp:CheckBox ID="CheckBox1" runat="server" />
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="CustomValidator"
ClientValidationFunction="ValidateCheckbox"></asp:CustomValidator>

and this JavaScript to be consumed by the CustomValidator:

JavaScript
<script language="JavaScript" type="text/javascript">
function ValidateCheckbox(source, args) {
    args.IsValid = args.IsValid = document.getElementById
	('<%= CheckBox1.ClientID %>').checked;
}
</script> 

But what if you have 50 checkboxes, will you create one script for each one of them? Wouldn’t it be nice to just pass a parameter to your JavaScipt? By default, you cannot do that as the JavaScript that the CustomValidator uses only 2 parameters which is the source and args. But don’t worry, we can use RegisterExpandoAttribute method to extend an object's attribute.

So what does that method do? The answer is simple. It registers a name/value pair as a custom attribute of the specified control. Having that in mind, we use it in the CustomValidator and extend its attributes to have the ClientID of the checkbox you want to validate. So for clarity, refer to the example below.

So let's say we have the following controls that are dynamically driven by the GridView:

ASP.NET
<asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="False" 
	OnRowDataBound="myGridView_RowDataBound">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Label ID="lblQuestionItem" runat="server" 
		  Text='<%# Bind("QuestionItem") %>'
                    CssClass="Normal"></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:HiddenField ID="hdnIsRequired" runat="server" 
		Value='<%# Bind("IsRequired") %>' />
                <asp:CheckBox ID="chkAnswer" runat="server" 
		CssClass='<%# Bind("ControlClass") %>' />
                <asp:CustomValidator ID="ctmCHKAnswer" 
		ClientValidationFunction="ValidateCurrentCheckbox"
                    runat="server" ErrorMessage="*"></asp:CustomValidator>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Now from the sample above, we defined a CustomValidator and that’s the object that we will extend the attributes to contain the chkAnswer‘s client ID, to do that here is the code behind, also remember that you need to do that on a per row basis as well. That's why it is in myGridView_RowDataBound, and here is how to achieve it.

C#
protected void myGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        HiddenField hdnIsRequired = (HiddenField)e.Row.FindControl("hdnIsRequired");
        CheckBox chkAnswer = (CheckBox)e.Row.FindControl("chkAnswer");
        CustomValidator ctmCHKAnswer = (CustomValidator)e.Row.FindControl("ctmCHKAnswer");

        Page.ClientScript.RegisterExpandoAttribute
		(ctmCHKAnswer.ClientID, "ClientID", chkAnswer.ClientID, false);
        ctmCHKAnswer.Enabled = bool.Parse(hdnIsRequired.Value);
    }
}

If you noticed, we extended ctmCHKAnswer with the “ClientID” attribute that comes from chkAnswer.ClientID. So when you fire the JavaScript, you can then use the source parameter and use source.ClientID to get the checkbox client ID you need.

JavaScript
<script language="JavaScript" type="text/javascript">
function ValidateCurrentCheckbox(source, args) {
    var checkbox = document.getElementById(source.ClientID)
    args.IsValid = checkbox.checked;
}
</script>

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here