Using validator controls with checkboxes

When attempting to set the ControlToValidate property of any of the built-in validator controls (particularly CustomValidator) you’ll find you get the following runtime error:

Control ‘agreeTermsCheckBox’ referenced by the ControlToValidate property of ‘agreeTermsRequiredTrue’ cannot be validated.

In my case, I want to validate a checkbox for my website’s Terms and Conditions to ensure that it’s been marked as true before creating the account.

It turns out that CheckBox controls (and also HiddenField controls) are not supported by the BaseValidator’s ControlToValidate field. Presumably, since this is due to the fact that the value cannot be reliably read or distinguished from an empty value.

Thus there are two possible work arounds:

  1. Don’t use the ControlToValidate property and in your CustomValidator’s ClientValidationFunction and ServerValidate function.
  2. Use an intermediate control to store the checkbox’s check state and validate against it using a CompareValidator.
  3. Use an intermediate control to be able to get a reference to the checkbox to validate using a CustomValidator.

The first is far from ideal since you’ll have to use a hardcoded reference to your checkbox’s ClientID and ID in order to check it. The second is OK, except that you have to add client side events to your checkbox which may be a tiny bit more fiddly to get it functional.

The third is what I ended up doing.

In my case, I added a TextBox to the form whose Text property stores the ClientID of the CheckBox. Ideally I would have used a hidden field, but apparently they’re not supported either! I hide the TextBox using it’s CssClass (with display: none and visibility: hidden).

<asp:TextBox ID="agreeTermsCheckBoxIdField" runat="server" CssClass="hidden" Text='<%# Container.FindControl("agreeTermsCheckBox").ClientID %>' />

Then I add my CustomValidator with ControlToValidate pointing at this new TextBox.

<asp:CustomValidator ID="agreeTermsRequiredTrue" runat="server" Text="*" ControlToValidate="agreeTermsCheckBoxIdField" EnableClientScript="true" ClientValidationFunction="ValidateCheckBoxIsTrue" OnServerValidate="agreeTermsRequiredTrue_ServerValidate" />

The great thing about this, is that now the Value property of the validation function’s arguments will automatically be set to the ClientID of the checkbox making our client side function’s ability to locate the CheckBox nice and easy!

function ValidateCheckBoxIsTrue(source, clientside_arguments) { // Find the checkbox we're validating // In this case, the client ID of the control is stored in a hidden field // whose value is passed in via the ControlToValidate's property. var checkBoxToValidate = document.getElementById(clientside_arguments.Value); // Default value - let it pass... clientside_arguments.IsValid = true; // Set IsValid according to checkbox state. if (checkBoxToValidate != null) { clientside_arguments.IsValid = checkBoxToValidate.checked; return; } }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s