【问题标题】:ASP.NET MVC 3 unobtrusive validation and radio buttonsASP.NET MVC 3 不显眼的验证和单选按钮
【发布时间】:2011-08-05 12:49:39
【问题描述】:

我正在尝试对单选按钮列表进行必要的验证,以强制用户选择一个选项以继续。验证确实有效,但它仅在第一个单选按钮上输出元数据,并且仅使用类 input-validation-error 标记第一个单选按钮。

例子:

<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>

我希望两个单选按钮都获得验证错误类,否则可能会导致用户选择的选项出现偏差。

我能做什么?

【问题讨论】:

  • 您的视图如何?你有@Html.ValidationMessageFor(x => x.Choices) 吗?

标签: asp.net-mvc-3 unobtrusive-validation


【解决方案1】:

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

@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 =&gt; 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) 应用于单选按钮的父元素,即 &lt;div&gt; 元素。

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

它在 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. Event detect when css property changed using Jquery

【讨论】:

    【解决方案2】:

    这可以通过使用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");
        });
    };
    

    【讨论】:

    • 不幸的是,这导致客户端验证不再阻塞 POST。任何想法为什么?
    【解决方案3】:

    我所做的是禁用单选按钮的 CSS,只显示错误消息。 (不确定 IE 是否喜欢这个)

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

    【讨论】:

      猜你喜欢
      • 2011-07-09
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 2011-12-06
      • 2011-12-22
      • 2011-06-28
      • 2011-09-20
      • 1970-01-01
      相关资源
      最近更新 更多