Подтвердить что ты не робот

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>

Я хочу, чтобы оба переключателя получили класс ошибки проверки, или он может подвергнуть сомнению, какой вариант пользователь выбирает.

Что я могу сделать?

4b9b3361

Ответ 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 => model.Property) предназначен для создания одного html-элемента для одного конкретного свойства. Способ, которым вы используете его для создания нескольких элементов из одного свойства, неверен.

Кроме того, посмотрите идентификаторы этих 3 переключателей. Они такие же, а? Допустимо ли иметь элементы с одинаковыми идентификаторами на странице html? Точно нет! Поэтому что-то нужно исправлять.

Хотя я решил, что решить эту проблему проще, разработав новые методы расширения 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. Мы можем исправить это, используя это решение: fooobar.com/questions/139600/..., но, возможно, когда-нибудь позже.

Опять же, я считаю, что нам нужно разработать HTML Extension Method или улучшить и использовать EditorTemplate следующим образом: https://gist.github.com/973482

Литература:

Ответ 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");
    });
};

Ответ 3

Что я сделал, так это отключить css для radioobutton и показать сообщение об ошибке. (не уверен, что IE это нравится)

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