【问题标题】:Adding a required attribute to multiple checkboxes in a form向表单中的多个复选框添加必需属性
【发布时间】:2021-10-20 13:01:53
【问题描述】:

我的视图中有多个复选框,在测试不同的用例时,我注意到如果我不选择任何文本框并点击提交按钮,它会将我重定向到下一页。但事实上,如果可能的话,我想添加一个必需的属性,以便用户选择至少 1 个复选框。我尝试将 required 属性添加到第一个复选框,但这仅意味着用户必须选择第一个不是我想要的复选框。这在 .cshtml 中可行吗?

这是我的看法:

@using (Html.BeginForm("Data", "Controller"))
{
    for (int i = 0; i < Model.items.Count; i++)
    {
        int counter = 0;

        @Html.CheckBoxFor(r => Model.items[i].IsSelected)
        <label>  @Model.items[i].te</label><br />

        @Html.HiddenFor(h => @Model.items[i].Id)
        @Html.HiddenFor(h => @Model.items[i].Name)

        if (Model.items[i].Selected)
        {
            counter++;
        }
        else if (counter < 1)
        {
           RequiredCustom custom = new();

           custom.IsValid(Model.items);
        }



    }
        
    <input id="Button" type="submit" value="Next" />

}

【问题讨论】:

  • 在帖子描述中,您正在谈论复选框。但是上面的视图包含radio-buttons
  • 对不起,我复制了错误的视图,请查看更新后的帖子@Jackdaw
  • 不,这是不可能的,您必须验证您的 model.plans 至少包含 1 个选定的纯文本,(请参阅 c# 中的自定义数据验证)然后您可以检查此属性是否有效并显示如果不是自定义错误,例如stackoverflow.com/questions/21263063/…
  • 这里是自定义属性stackoverflow.com/a/33495692/2302522 的示例,尝试实现适合您需要的类似属性。
  • @croban 感谢您与我分享这些。我试图实现或者但陷入了困境。请查看更新后的帖子,我在其中展示了处理此问题的控制器

标签: c# html asp.net-mvc checkbox asp.net-core-mvc


【解决方案1】:

好吧,如果您不想使用javascript,那么您必须在asp.net backend 一侧使用custom validator。以下是执行此操作的完整步骤。

Custom Validator Method:

public class RequiredCustom : ValidationAttribute
        {
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {
                var viewModel = (ViewPhoneNumberInput)validationContext.ObjectInstance;

                var checkBoxCounter = 0;
                foreach (var plan in viewModel.plans)
                {
                    if(plan.IsSelected == true)
                    {
                        checkBoxCounter++;
                    }
                    if (plan.IsSelected == true && checkBoxCounter >0)
                    {
                        return new ValidationResult(ErrorMessage = "You have selected  "+ checkBoxCounter + " checkbox!");

                    }
                    else
                    {
                        return new ValidationResult(ErrorMessage == null ? "Please check one checkbox!" : ErrorMessage);
                    }
                    
                }

                return ValidationResult.Success;
            }
        }

Your Existing Model

public class ViewPhoneNumberInput
    {
        [Required(ErrorMessage = "You did not enter your phone number! Please enter your phone number!")]
        public String PhoneNumber { get; set; }
        [RequiredCustom(ErrorMessage = "Please select at least one checkbox")]
        public List<Plans> plans { get; set; }
    
    }

Views:

@model ViewPhoneNumberInput

@{ ViewBag.Title = " "; }

<h2>Select Your Plan</h2>

@using (Html.BeginForm("NewCustomerView", "StackOverFlow"))
{
    for (int i = 0; i < Model.plans.Count; i++)
    {
        int counter = 0;

        @Html.CheckBoxFor(r => Model.plans[i].IsSelected)
        <label>  @Model.plans[i].PlanName</label>


        @Html.HiddenFor(h => @Model.plans[i].PlanId)
        @Html.HiddenFor(h => @Model.plans[i].PlanName)

        <br />@Html.ValidationMessageFor(r => Model.plans)<br />
    }
    <p><strong>Phone Number</strong></p>
    @Html.TextBoxFor(r => Model.PhoneNumber)
    <p>  @Html.ValidationMessageFor(r => Model.PhoneNumber) </p>


    <input id="Button" type="submit" value="Next" />

}

Output:

更新:

我最好采用以下方式处理:

 public class RequiredCustom : ValidationAttribute
        {
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {
                var viewModel = (ViewPhoneNumberInput)validationContext.ObjectInstance;

                var checkBoxCounter = 0;
                foreach (var plan in viewModel.plans)
                {
                    if(plan.IsSelected == true)
                    {
                        checkBoxCounter++;
                    }
                    if (plan.IsSelected == true && checkBoxCounter == 1)
                    {
                        return new ValidationResult(ErrorMessage = "You have selected checkbox!");

                    }
                    else
                    {
                        return new ValidationResult(ErrorMessage == null ? "Please check one checkbox!" : ErrorMessage);
                    }
                    
                }

                return ValidationResult.Success;
            }
        }

注意:这是您收到System.InvalidCastException: 'Unable to cast object of type 'PlanService.API.Models.ViewPhoneNumberInput' to type 'PlanService.API.Models.Plans 的异常的解决方案。因为您将一个列表传递给验证器,但之前它需要一个列表。现在好了。

现在验证器模型需要一个计划列表并且可以采取相应的行动。

更新输出

希望它能帮助您实现目标。

【讨论】:

  • 他要求 [... 如果可能的话,让用户选择至少 1 个复选框...] 您的自定义验证器会检查 List 中的每个项目是否都被选中
  • 哈哈,如果你可以为一个项目设置条件,那对List&lt;OfItems&gt;来说是不是很重要?他需要迭代iteam,最后检查是否至少选择了一个iteam。只需要循环一遍,他已经知道了。
  • :) 我不确定他是否知道
  • 如果 OP 需要,也可以提供。不用担心
  • @croban 提供您关心的解决方案。
猜你喜欢
  • 2017-05-11
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
相关资源
最近更新 更多