ASP.NET MVC 3 ненавязчивая проверка и переключатели
Я пытаюсь выполнить необходимую проверку списка переключателей, чтобы заставить пользователя выбрать опцию, чтобы продолжить. Проверка действительно работает, но выводит метаданные только на первую радиокнопку и помечает только первую радиокнопку с классом 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 ответа
Обратите внимание, что ожидаемое поведение следующего кода
@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
событие. Мы можем исправить это, используя это решение: /questions/15294359/est-li-alternativa-domattrmodified-kotoraya-budet-rabotat-v-webkit/15294368#15294368, но, возможно, когда-нибудь позже.
Опять же, я считаю, что нам нужно разработать метод расширения HTML или улучшить и использовать шаблон EditorTemplate, например: https://gist.github.com/973482
Рекомендации:
- /questions/47158302/kak-ya-mogu-ispolzovat-htmleditorfor-dlya-renderinga-pereklyuchatelej-v-mvc3/47158320#47158320
- /questions/33006380/kak-sdelat-shablon-redaktora-po-umolchaniyu-dlya-perechislenij/33006397#33006397
- https://gist.github.com/973482
- Обнаружение события при изменении свойства css с помощью Jquery
Это может быть выполнено с помощью 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");
});
};
То, что я сделал, было отключить CSS для радиопереключателя и показать только сообщение об ошибке. (не уверен, что IE это нравится)
.input-validation-error input[type="radio"]
{
border: 0x solid #ff0000;
background-color: inherit;
}