Лучший подход для расширения ненавязчивого javascript в MVC3 для добавления стиля к стороне клиента div
Я использую html5/Razor/MVC3, используя шаблон Bootstrap из Twitter. Я хочу иметь форму проверки, которая выглядит скользкой, как они документированы (http://twitter.github.com/bootstrap/#forms). Поэтому, если мы посмотрим, как стандартная котельная плита MVC3 для регистрации учетной записи, разметка будет выглядеть так:
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class="form-stacked" })) {
@Html.ValidationSummary(true, "Snap! Something went wrong")
<div>
<fieldset>
<legend>Account Information</legend>
<div class="clearfix error">
@Html.LabelFor(m => m.UserName)
<div class="input">
@Html.TextBoxFor(m => m.UserName)
<span class="help-inline">@Html.ValidationMessageFor(m => m.UserName)</span>
</div>
</div>
<div class="clearfix">
@Html.LabelFor(m => m.Email)
<div class="input">
@Html.TextBoxFor(m => m.Email)
<span class="help-inline">@Html.ValidationMessageFor(m => m.Email)</span>
</div>
</div>
<div class="clearfix">
@Html.LabelFor(m => m.Password)
<div class="input">
@Html.PasswordFor(m => m.Password)
<span class="help-inline">@Html.ValidationMessageFor(m => m.Password)</span>
</div>
</div>
<div class="clearfix">
@Html.LabelFor(m => m.ConfirmPassword)
<div class="input">
@Html.PasswordFor(m => m.ConfirmPassword)
<span class="help-inline">@Html.ValidationMessageFor(m => m.ConfirmPassword)</span>
</div>
</div>
</fieldset>
<div class="actions">
<button class="btn large primary" type="submit">Register</button>
</div>
</div>
Я хочу сделать, чтобы контейнер div вводил класс "error", как я был жестко закодирован в первом входе. (Итак, при входе на страницу у div будет класс "clearfix", но если этот входной блок не прошел проверку, он помечает его как "clearfix error" ). Я полагаю, что мне придется обновить блок div, чтобы включить какой-то идентификатор и, возможно, добавить новый атрибут data в ValidationMessage. У меня нет проблемы с расширением помощника ValidationMessageFor. Я просто не уверен на 100%, какой подход должен быть для расширения библиотеки там. Любые предложения о том, как подойти к этому?
ТИА.
UPDATE
Я думаю, что этот подход разумный:
<div id="UserNameContainer" class="clearfix error">
@Html.LabelFor(m => m.UserName)
<div class="input">
@Html.TextBoxFor(m => m.UserName)
<span class="help-inline">@Html.ValidationMessageFor(m => m.UserName, null, new { @data_container = "UserNameContainer" })</span>
</div>
</div>
Оформляя мое сообщение о подтверждении именем контейнера данных, я мог бы затем настроить таргетинг на контейнер div. Теперь мне просто нужно выяснить, как перехватить сообщение проверки.
Ответы
Ответ 1
Метод $.validator.setDefaults
решил эту проблему для меня с Bootstrap из Twitter. Я использую jquery.validate.js
и jquery.validate.unobtrusive.js
.
Поскольку ненавязчивая проверка в DOM готово сканирует ваш документ и кэширует ненавязчивые параметры проверки для каждой формы, с которой он сталкивается, необходимо вызвать метод $.validator.setDefaults
до сканирования документа.
// setup defaults for $.validator outside domReady handler
$.validator.setDefaults({
highlight: function (element) {
$(element).closest(".clearfix").addClass("error");
},
unhighlight: function (element) {
$(element).closest(".clearfix").removeClass("error");
}
});
$(document).ready(function() {
// do other stuff
});
Ответ 2
Вышел по той же проблеме. Я занимаюсь этим, добавляя и расширяя класс HtmlHelper.
Это то, что я сделал для ValidationSummary:
public static class TwitterBootstrapHelperExtensions
{
public static MvcHtmlString BootstrapValidationSummary(this HtmlHelper helper,
bool excludePropertyErrors,
string message)
{
if(helper.ViewData.ModelState.Values.All(v => v.Errors.Count == 0)) return new MvcHtmlString(string.Empty);
string errorsList = "<ul>";
foreach (var error in helper.ViewData.ModelState.Values.Where(v => v.Errors.Count >0))
{
errorsList += string.Format("<li>{0}</li>", error.Errors.First().ErrorMessage);
}
errorsList += "</ul>";
return new MvcHtmlString(string.Format("<div class=\"alert-message error\"><span>{0}</span>{1}</div>",message,errorsList));
}
}
И в файле .cshtml я заменю Html.ValidationSummary следующим:
@Html.BootstrapValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
Не забудьте добавить namespance вашего класса расширения в файл web.config в файлах представлений.
Я опубликую здесь позже, если я займусь отдельным элементом ввода перед вами.
НТН
Ответ 3
Вместо того, чтобы повторно изобретать это колесо, проверьте плагин validationEngine, доступный в http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/.
Вы можете настраивать элементы всплывающего окна по своему усмотрению, и тривиально подключаться к jQuery.validate.js.
Ответ 4
Я предпочитаю менять CSS bootstrap.
Просто добавил классы проверки jQuery в нужном месте.
ошибка проверки поля и ошибка проверки ввода
form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline, .field-validation-error {
color: #b94a48;
}
form .clearfix.error input, form .clearfix.error textarea, .input-validation-error {
color: #b94a48;
border-color: #ee5f5b;
}
form .clearfix.error input:focus, form .clearfix.error textarea:focus, .input-validation-error:focus {
border-color: #e9322d;
-webkit-box-shadow: 0 0 6px #f8b9b7;
-moz-box-shadow: 0 0 6px #f8b9b7;
box-shadow: 0 0 6px #f8b9b7;
}
Ответ 5
Вы можете интегрировать проверку MVC3 с помощью структуры Bootstrap, добавив на свою страницу следующий javascript (View)
<script>
$(document).ready(function () {
/* Bootstrap Fix */
$.validator.setDefaults({
highlight: function (element) {
$(element).closest("div.control-group").addClass("error");
},
unhighlight: function (element) {
$(element).closest("div.control-group").removeClass("error");
}
});
var current_div;
$(".editor-label, .editor-field").each(function () {
var $this = $(this);
if ($this.hasClass("editor-label")) {
current_div = $('<div class="control-group"></div>').insertBefore(this);
}
current_div.append(this);
});
$(".editor-label").each(function () {
$(this).contents().unwrap();
});
$(".editor-field").each(function () {
$(this).addClass("controls");
$(this).removeClass("editor-field");
});
$("label").each(function () {
$(this).addClass("control-label");
});
$("span.field-validation-valid, span.field-validation-error").each(function () {
$(this).addClass("help-inline");
});
$("form").each(function () {
$(this).addClass("form-horizontal");
$(this).find("div.control-group").each(function () {
if ($(this).find("span.field-validation-error").length > 0) {
$(this).addClass("error");
}
});
});
});
</script>
Кроме того, в представлениях (например, "Create.cshtml" ) убедитесь, что поля в форме отформатированы следующим образом:
<div class="editor-label">
@Html.LabelFor(Function(model) model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(Function(model) model.Name)
@Html.ValidationMessageFor(Function(model) model.Name)
</div>
С помощью этого решения, скорее всего, будет достаточно просто добавить javascript без редактирования представления.
Ответ 6
Что я сделал, то взяли классы css для ошибок проверки и создали новый файл css с теми же классами, но со значениями начальной загрузки.
Вы можете найти его в пакете nuget по адресу: http://nuget.org/List/Packages/MahApps.Twitter.Bootstrap
Это также предоставляет некоторые шаблоны лесов для автоматического создания новых представлений.
Ответ 7
Мне нужно было решить это, используя Bootstrap 3.1 и Razor. Это то, что я использовал:
$.validator.setDefaults({
highlight: function (element) {
$(element).parents(".form-group").addClass("has-error");
},
unhighlight: function (element) {
$(element).parents(".form-group").removeClass("has-error");
}
});
$(function () {
$('span.field-validation-valid, span.field-validation-error').each(function () {
$(this).addClass('help-block');
});
$('form').submit(function () {
if ($(this).valid()) {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length == 0) {
$(this).removeClass('has-error');
}
});
}
else {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
}
});
}
});
$('form').each(function () {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
}
});
});
});
Это комбинация ответа @german и помощь от этого post от "theBraindonor". Обновлено для использования новых классов Bootstrap 3.