Reputation:
I have a CheckBoxList that I am trying to validate that at least one of the checkboxes is checked.
Markup:
<asp:CustomValidator ID="RequiredFieldValidator8" ValidationGroup="EditArticle"
runat="server" ErrorMessage="At least one Category is required."
OnServerValidate="topic_ServerValidate" />
<asp:CheckBoxList id="checkboxlistCategories" runat="server"></asp:CheckBoxList>
Code-behind:
protected void topic_ServerValidate(object source, ServerValidateEventArgs args)
{
int i = 0;
foreach (ListItem item in checkboxlistCategories.Items)
{
if (item.Selected == true)
i = i + 1;
}
if (i == 0)
args.IsValid = false;
else
args.IsValid = true;
}
If I add ControlToValidate="checkboxlistCategories" in the CustomValidator control, it blows up! The exception I get is:
System.Web.HttpException: Control 'checkboxlistCategories' referenced by the ControlToValidate property of 'RequiredFieldValidator8'
Am I missing something?
Upvotes: 3
Views: 8257
Reputation: 6426
Here's a cleaner jQuery implementation that allows one ClientValidationFunction for any number of CheckBoxList controls on a page:
function ValidateCheckBoxList(sender, args) {
args.IsValid = false;
$("#" + sender.id).parent().find("table[id$="+sender.ControlId+"]").find(":checkbox").each(function () {
if ($(this).attr("checked")) {
args.IsValid = true;
return;
}
});
}
Here's the markup:
<asp:CheckBoxList runat="server"
Id="cblOptions"
DataTextField="Text"
DataValueField="Id" />
<xx:CustomValidator Display="Dynamic"
runat="server"
ID="cblOptionsValidator"
ControlId="cblOptions"
ClientValidationFunction="ValidateCheckBoxList"
ErrorMessage="One selection required." />
And finally, the custom validator that allows the client function to retrieve the target control by ID:
public class CustomValidator : System.Web.UI.WebControls.CustomValidator
{
public string ControlId { get; set; }
protected override void OnLoad(EventArgs e)
{
if (Enabled)
Page.ClientScript.RegisterExpandoAttribute(ClientID, "ControlId", ControlId);
base.OnLoad(e);
}
}
Upvotes: 1
Reputation: 11795
As Mehdi mentioned, 4 Guys covered this in the article he links to in his answer.
For brevity, here's the code listing-
public class CheckBoxListRequiredFieldValidator : BaseValidator
{
private ListControl _listctrl;
public CheckBoxListRequiredFieldValidator()
{
base.EnableClientScript = false;
}
protected override bool ControlPropertiesValid()
{
Control ctrl = FindControl(ControlToValidate);
if (ctrl != null)
{
_listctrl = (ListControl)ctrl;
return (_listctrl != null);
}
else
return false;
}
protected override bool EvaluateIsValid()
{
return _listctrl.SelectedIndex != -1;
}
}
Pop this badger into you user controls library and away you go.
HTH.
Upvotes: 0
Reputation: 7941
Maybe I'm missing something. But CheckBoxList
control does not have the ValidationPropertyAttribute
. Thus you can't use it as ControlToValidate
property. Try this:
CheckBoxList.cs
[ValidationProperty("SelectedIndex")]
public class CheckBoxList : System.Web.UI.WebControls.CheckBoxList
{
}
Web.Config
<tagMapping>
<add tagType="System.Web.UI.WebControls.CheckBoxList, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mappedTagType="Namespace.CheckBoxList, Assembly"/>
</tagMapping>
Anyway Scott Mitchell has written a great article about it here.
Upvotes: 0
Reputation: 8078
Just a suggestion, but you could use radio buttons instead and define a group name. This would eliminate the need for the validation b/c only one radio button can be checked within the group.
Upvotes: 0
Reputation: 38336
Considering that your server side validation method topic_ServerValidate
is tied specificly to the checkboxlistCategories
field, you do not need to set the ControlToValidate
property.
The reason that it "blows up" when you add the ControlToValidate
property, is the type of the control you are referencing - a CheckBoxList
. When assigning a ControlToValidate
to any kind of validator, that validator will automatically do a "non empty" check on the referenced control before performing the actual validation logic. If the field is empty, no validation will be done (i.e. validation success). That is, of course, unless you set ValidateWhenEmpty = true
. Apparently, the validators do not know how to check if a CheckBoxList
is empty, and instead they throw an exception.
In your specific case, where the CustomValidator
really just serves as non-empty check, you definatly want validator to occur even when the referenced control is left "empty". As stated in the first paragraph of my answer, the simplest way to achieve this is to remove the offending - and unnecessary - property.
Upvotes: 0