If you try to use the standard ASP.NET validation controls to validate a CheckBoxList control you may receive an error message that looks like this:
Control 'CheckBoxList1' referenced by the ControlToValidate property of 'RequiredFieldValidator1' cannot be validated
Unfortunately out of the box the RequiredFieldValidator will not work on the CheckBoxList control. In a recent project I had a requirement to validate a number of checkbox lists. I needed to validate that at least one item was checked and in some cases make sure that no more than a certain number of options were selected. I created a new validator control specifically for validating CheckBoxLists to handle this.
Here is a demo of the control in action:
http://www.sourcemotion.com/CheckBoxListTest.aspx
Here is the source code for the validator control:
using System;
using System.Data;
using System.Configuration;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
///
/// Validation control for use with the CheckBoxList control
///
namespace Validators
{
public class CheckBoxListValidator : CustomValidator
{
private const string CheckBoxListValidatorScriptKey = "CheckBoxListValidator_GlobalScript";
private bool _isRequired;
private int _maximumChecked;
private CheckBoxList _listctrl;
public CheckBoxListValidator()
{
_isRequired = true;
_maximumChecked = -1;
}
public int MaximumChecked
{
get
{
return _maximumChecked;
}
set
{
_maximumChecked = value;
}
}
public bool IsRequired
{
get
{
return _isRequired;
}
set
{
_isRequired = value;
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (this.EnableClientScript && !this.Page.ClientScript.IsClientScriptBlockRegistered(this.Page.GetType(), CheckBoxListValidatorScriptKey))
{
StringBuilder script = new StringBuilder();
script.AppendLine("function fixCheckboxValidationEvent(id)");
script.AppendLine("{");
script.AppendLine(" if (document.getElementById(id))");
script.AppendLine(" {");
script.AppendLine(" var checkboxList = document.getElementById(id);");
script.AppendLine(" if (checkboxList.getElementsByTagName)");
script.AppendLine(" {");
script.AppendLine(" var inputs = checkboxList.getElementsByTagName(\"input\");");
script.AppendLine(" for (j=0;j -1) && (selectedCount > maxCount)) ");
script.AppendLine(" {");
script.AppendLine(" args.IsValid = false;");
script.AppendLine(" } ");
script.AppendLine(" else ");
script.AppendLine(" {");
script.AppendLine(" args.IsValid = true;");
script.AppendLine(" }");
script.AppendLine(" }");
script.AppendLine("}");
// This script should only be included once...
this.Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), CheckBoxListValidatorScriptKey, script.ToString(), true);
}
if (this.EnableClientScript && !this.Page.ClientScript.IsStartupScriptRegistered(this.GetType(), this.ClientID))
{
this.Page.ClientScript.RegisterStartupScript(this.GetType(), this.ClientID, GetStartupScript(), true);
}
}
protected string GetScript()
{
return String.Format("var {0}_maxChecked = {1};\r\nvar {0}_isRequired = {2};\r\n",
_listctrl.ClientID,
_maximumChecked,
_isRequired.ToString().ToLower());
}
protected string GetStartupScript()
{
return String.Format("fixCheckboxValidationEvent('{0}');\r\n", _listctrl.ClientID);
}
protected override bool ControlPropertiesValid()
{
Control ctrl = FindControl(ControlToValidate);
if (ctrl != null)
{
if (ctrl is CheckBoxList)
{
_listctrl = (CheckBoxList)ctrl;
if (this.EnableClientScript)
{
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.ClientID, GetScript(), true);
this.ClientValidationFunction = "validateCheckBoxList";
}
return true;
}
else
{
return false; // raise exception
}
}
else
return false; // raise exception
}
protected override bool EvaluateIsValid()
{
int selectedCount = 0;
foreach (ListItem item in _listctrl.Items)
{
if (item.Selected)
{
selectedCount++;
}
}
if (selectedCount == 0 && _isRequired)
{
return false;
}
else if (_maximumChecked != -1 && selectedCount > _maximumChecked)
{
return false;
}
return true;
}
}
}
Notes:
- In the CheckBoxListValidator class I override the ControlPropertiesValid method. This is the method that normally throws an exception if you try to assign a CheckboxList control to the ControlToValidate property of a RequiredFieldValidator control. This method now checks to ensure that the ControlToValidate property is pointing at a CheckboxList control.
- The Javascript function fixCheckboxValidationEvent gets called for each CheckBoxList control and swaps the standard client validation function from the onchange event to the onclick event. By default validation is called on change but for the checkbox you actually need it on click.
Labels: ASP.NET, CheckBoxList, validation controls