如何验证用户在CheckBoxList中至少选择了一个复选框?

39

我有一个CheckBoxList控件,希望要求用户至少选中一个复选框,无论他们是选中了全部、三个或仅一个都可以。

为了符合asp.net的验证控件精神,我该使用什么来强制实现这个需求?我还在使用Ajax验证扩展程序,因此如果它能像其他控件一样,而不是在Codebehind中使用某些过时的服务器验证方法,那就太好了。

<asp:CheckBoxList RepeatDirection="Horizontal" RepeatLayout="Table" RepeatColumns="3" ID="ckBoxListReasons" runat="server">
    <asp:ListItem Text="Preliminary Construction" Value="prelim_construction" />
    <asp:ListItem Text="Final Construction" Value="final_construction" />
    <asp:ListItem Text="Construction Alteration" Value="construction_alteration" />
    <asp:ListItem Text="Remodel" Value="remodel" />
    <asp:ListItem Text="Color" Value="color" />
    <asp:ListItem Text="Brick" Value="brick" />
    <asp:ListItem Text="Exterior Lighting" Value="exterior_lighting" />
    <asp:ListItem Text="Deck/Patio/Flatwork" Value="deck_patio_flatwork" />
    <asp:ListItem Text="Fence/Screening" Value="fence_screening" />
    <asp:ListItem Text="Landscape - Front" Value="landscape_front" />
    <asp:ListItem Text="Landscape - Side/Rear" Value="landscape_side_rear" />
    <asp:ListItem Text="Other" Value="other" />
</asp:CheckBoxList>

2
你会使用jQuery吗?如果是,那么这非常简单。给所有的复选框命名一个类名,比如说“reasons”。当$('.reasons :checked').length == 0时,表示用户没有选择任何复选框,你可以显示错误信息。 - SolutionYogi
2
我想只使用.NET中内置的验证器......我实际上无法使用jQuery。 - John Batdorf
6个回答

65
很容易在服务器端进行此验证,但我假设您想在客户端上执行此操作?如果您有一些具有共同点的内容可用作选择器(例如类别(您的.NET控件上的CssClass)),则JQuery可以非常轻松地完成此操作。您可以创建一个简单的JQuery函数并将其连接到ASP.NET自定义验证器。请记住,如果您确实采用自定义验证器路线,请确保您在服务器端检查它,以防javascript未工作,您不会像其他.NET验证器那样获得免费的服务器端检查。
有关自定义验证器的更多信息,请访问以下链接:www.asp.netMSDN
您不需要使用JQuery,这只是使迭代并查看所有复选框控件的javascript函数更容易,但是如果您喜欢,可以仅使用vanilla javascript。
这里是我在原始链接中找到的示例。
<asp:CheckBoxList ID="chkModuleList"runat="server" >
</asp:CheckBoxList>

<asp:CustomValidator runat="server" ID="cvmodulelist"
  ClientValidationFunction="ValidateModuleList"
  ErrorMessage="Please Select Atleast one Module" ></asp:CustomValidator>

// javascript to add to your aspx page
function ValidateModuleList(source, args)
{
  var chkListModules= document.getElementById ('<%= chkModuleList.ClientID %>');
  var chkListinputs = chkListModules.getElementsByTagName("input");
  for (var i=0;i<chkListinputs .length;i++)
  {
    if (chkListinputs [i].checked)
    {
      args.IsValid = true;
      return;
    }
  }
  args.IsValid = false;
}

顺便提一下:JQuery只是一个你需要添加到页面中的小型js文件包含。一旦你把它包含进去,你就可以使用所有JQuery喜欢的东西了。不需要安装,在下一个版本的Visual Studio中将得到充分支持。


1
有没有办法将这个泛化?我该如何修改JavaScript函数,使其在CustomValidator中获取“ControlToValidate”,而不是硬编码“<%= chkModuleList.ClientID %>”? - Quan
令人困惑的是,OP在评论中说“我实际上不能使用jQuery”,然后这个答案却假定相反的情况,并且更加令人困惑的是,OP接受了它。特别是如果在服务器端(例如使用C#)很容易进行验证,我想知道为什么这个答案不只是展示如何在服务器端进行验证。 - TylerH

14

这里有一个更简洁的 jQuery 实现,它允许在页面上使用任意数量的 CheckBoxList 控件使用同一种 ClientValidationFunction

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;
        }
    });
}

这是标记:

<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." />

最后,自定义验证器允许客户端函数通过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);
    }
}

不知道为什么,但当 CheckBoxList 在 Update Panel 中并进行部分回发时,即使在部分回发之前已经进行了选择,它也会出现错误。这是 JQuery 的问题,在这种情况下,JavaScript 解决方案被接受为答案。 - Arsalan Adam Khatri
+1个简洁的解决方案。当CheckBoxListFormView中时,我遇到了接受答案的问题。@ArsalanAdamKhatri为了使其与UpdatePanel正常工作,请将Page.ClientScript.RegisterExpandoAttribute(ClientID, "ControlId", ControlId);替换为ScriptManager.RegisterExpandoAttribute(this, ClientID, "ControlId", ControlId, true); - DonD
我曾经很困惑为什么不能使用sender.controltovalidate。后来发现,如果你尝试这样做,你会得到一个错误提示:“Control 'x' referenced by the ControlToValidate property of 'valX' cannot be validated.”即使你自己编写验证函数,当然它是可以被验证的! - Ian Grainger
1
值得注意的是,这个答案在RepeatLayout="UnorderedList"下不起作用 - 与被接受的答案不同。 - Ian Grainger

2
你可以使用带有一点javascript的CustomValidator来实现这个功能。
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Select at least one"
    ClientValidationFunction="checkCheckBoxList"></asp:CustomValidator>

<script type="text/javascript">
    function checkCheckBoxList(oSrc, args) {
        var isValid = false;
        $("#<%= CheckBoxList1.ClientID %> input[type='checkbox']:checked").each(function (i, obj) {
            isValid = true;
        });
        args.IsValid = isValid;
    }
</script>

对于一个RadioButtonList

<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Select at least one" ClientValidationFunction="checkRadioButtonList"></asp:CustomValidator>

<script type="text/javascript">
    function checkRadioButtonList(oSrc, args) {
        if ($("input[name='<%= RadioButtonList1.UniqueID %>']:checked").val() == null) {
            args.IsValid = false;
        } else {
            args.IsValid = true;
        }
    }
</script>

1

这里有另一种解决方案,可以通过GitHub上的Dado.Validators进行考虑。

<asp:CheckBoxList ID="cblCheckBoxList" runat="server">
    <asp:ListItem Text="Check Box (empty)" Value="" />
    <asp:ListItem Text="Check Box 1" Value="1" />
    <asp:ListItem Text="Check Box 2" Value="2" />
    <asp:ListItem Text="Check Box 3" Value="3" />
</asp:CheckBoxList>

<Dado:RequiredFieldValidator runat="server" ControlToValidate="cblCheckBoxList" ValidationGroup="vlgSubmit" />

示例 codebehind.aspx.cs

btnSubmit.Click += (a, b) =>
{
    Page.Validate("vlgSubmit");
    if (Page.IsValid) {
        // Validation Successful
    }
};

https://www.nuget.org/packages/Dado.Validators/

参考:如何在客户端检查一组复选框中是否有被选中的复选框


0
我们也可以用C#来实现这个。
 bool Item_selected = false;
        foreach (ListItem item in checkbox.Items)
        {
            if (item.Selected == true)
            {
                Item_selected = true;
            }
        }
        if (!Item_selected )
        {
          //your message to user
          //  message = "Please select atleast one checkbox";
          
        }

-1

循环遍历ckBoxListReasons中的每个项目。每个项目将是“ListItem”类型。

ListItem将具有名为“Selected”的属性,该属性是布尔值。当选择该项时,它为true。类似于:

Dim bolSelectionMade As Boolean = False
For Each item As ListItem in ckBoxListReasons.Items
 If item.Selected = True Then
  bolSelectionMade = True
 End If
Next

如果用户至少进行了一次选择,则bolSelectionMade将被设置为true。然后,您可以使用它来设置任何特定验证控件的有效状态。

1
C# 中更紧凑的形式是:args.IsValid = ckBoxListReasons.Items.Any(item => item.Selected); - Jacob
1
您无法使用.Any(),因为Items集合不是从IEnumerable<T>继承的 - 它是ListItemCollection。 - Josh Kodroff
2
您可以使用 ckBoxListReasons.Items.Cast<ListItem>().Any(item => item.Selected); - Stuart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接