问题 ASP.NET MVC 3不显眼的验证和单选按钮


我正在尝试对单选按钮列表进行必要的验证,以强制用户选择继续选项。验证确实有效,但它只在第一个单选按钮上输出元数据,它只标记带有输入验证错误类的第一个单选按钮。

例:

<p>@Html.RadioButtonFor(x => x.Choices, SomeEnum.OptionOne)</p>
<p>@Html.RadioButtonFor(x => x.Choices, SomeEnum.OptionTwo)</p>

结果HTML:

<p><input class="input-validation-error" data-val="true" data-val-required="required text" type="radio" name="Choices" value="OptionOne" /></p>
<p><input type="radio" name="Choices" value="OptionTwo" /></p>

我希望两个单选按钮都能获得验证错误级别,否则可能会使用户选择的选项存在偏差。

我能做什么?


8478
2018-04-14 12:55


起源

你的观点如何?你有@ Html.ValidationMessageFor(x => x.Choices)吗? - PussInBoots


答案:


请注意以下代码的预期行为

@Html.RadioButtonFor(x => x.MyEnumProperty, MyEnum.OptionOne)
@Html.RadioButtonFor(x => x.MyEnumProperty, MyEnum.OptionTwo)
@Html.RadioButtonFor(x => x.MyEnumProperty, MyEnum.OptionThree)

<input id="MyEnumeration" type="radio" value="Option1" 
       name="MyEnumeration" 
       data-val-required="The MyEnumeration field is required." data-val="true">
<input id="MyEnumeration" type="radio" value="Option2" name="MyEnumeration">
<input id="MyEnumeration" type="radio" value="Option3" name="MyEnumeration">

为什么?因为 Html.SomethingFor(model => model.Property) 用于为一个特定属性生成一个html元素。您使用它从一个属性创建多个元素的方式是不正确的。

此外,请查看这3个单选按钮的ID。它们非常相似,不是吗?在html页面上拥有相同ID的元素是否可以接受?绝对不!因此需要修复一些问题。

虽然我认为通过开发新的Html扩展方法(参考文献2)可以更容易地解决这个问题,但我试图以另一种方式解决它(因为我很顽固!)。

首先,我们需要更改剃刀代码:

<div>
    @Html.RadioButtonFor(m => m.MyEnumeration, MyEnum.Option1, new { id = "m1" })
    <label for="m1">
        OPTION 1</label>
    @Html.RadioButtonFor(m => m.MyEnumeration, MyEnum.Option2, new { id = "m2" })
    <label for="m2">
        OPTION 2</label>
    @Html.RadioButtonFor(m => m.MyEnumeration, MyEnum.Option3, new { id = "m3" })
    <label for="m3">
        OPTION 3</label>
</div>

然后,一段JavaScript / jQuery魔术来解决我们的问题:

<script type="text/javascript">
    $(function () {
        $('[name=MyEnumeration]').each(function (index) { domAttrModified(this); });
    });

    function domAttrModified(obj) {
        //$obj = $(obj);
        $(obj).bind('DOMAttrModified', function () {
            if ($(obj).attr('class').indexOf('input-validation-error') != -1)
                $(obj).parent().addClass('input-validation-error');
            else
                $(obj).parent().removeClass('input-validation-error');
        });
    }
</script>

只要第一个单选按钮引发验证错误,此JavaScript代码就会应用错误css类(input-validation-error)到单选按钮的父元素,这是一个 <div> 元件。

并且随时验证错误消失(通过单击任何单选按钮元素),将从父元素中删除错误样式。

它在IE和FF中运行良好,但遗憾的是在Chrome中不起作用。原因是Chrome不支持 DOMAttrModified 事件。我们可以通过使用此解决方案来解决它: https://stackoverflow.com/a/10466236/538387 ,但也许过了一段时间。

同样,我相信我们需要开发HTML扩展方法或改进并使用如下的EditorTemplate: https://gist.github.com/973482 

参考文献:

  1. https://stackoverflow.com/a/7098541/538387
  2. https://stackoverflow.com/a/3448675/538387
  3. https://gist.github.com/973482
  4. 使用Jquery更改css属性时的事件检测

7
2018-06-29 21:38





这可以通过使用 showErrors 回电话:

$("form").data("validator").settings.showErrors = function (errorMap, errorList) {
    this.defaultShowErrors();

    $("input[type=radio][data-val=true].input-validation-error").each(function () {
        $("input[name=" + $(this).attr('name') + "]").addClass("input-validation-error");
    });

    $("input[type=radio][data-val=true]:not(.input-validation-error)").each(function () {
        $("input[name=" + $(this).attr('name') + "]").removeClass("input-validation-error");
    });
};

4
2017-07-16 21:50



不幸的是,这导致客户端验证不再阻止POST。有什么想法吗? - Sprintstar


我做的是禁用radiobutton的CSS,只显示错误信息。 (不确定IE喜欢这个)

.input-validation-error input[type="radio"]
{
    border: 0x solid #ff0000;
    background-color: inherit;
}

-1
2017-08-10 18:35