ASP.NET MVC 3 ненавязчивая проверка и переключатели - PullRequest
11 голосов
/ 14 апреля 2011

Я пытаюсь выполнить необходимую проверку списка переключателей, чтобы заставить пользователя выбрать опцию, чтобы продолжить. Проверка действительно работает, но она выводит метаданные только на первую радиокнопку и помечает только первую радиокнопку классом 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>

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

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

Ответы [ 3 ]

7 голосов
/ 30 июня 2012

Обратите внимание, что ожидаемое поведение следующего кода

@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. Мы можем исправить это с помощью этого решения: 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. Обнаружение события при изменении свойства css с помощью Jquery
4 голосов
/ 17 июля 2012

Это можно сделать с помощью обратного вызова 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");
    });
};
0 голосов
/ 10 августа 2011

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

.input-validation-error input[type="radio"]
{
    border: 0x solid #ff0000;
    background-color: inherit;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...