El mejor enfoque para extender javascript discreto en MVC3 para agregar un estilo a un lado del cliente div

Estoy usando html5 / Razor / MVC3 aprovechando la plantilla Bootstrap de Twitter. Quiero tener una validación de formularios que se vea elegante como lo han documentado (http://twitter.github.com/bootstrap/#forms). Entonces, si echamos un vistazo a cómo el MVC3 de placa de caldera estándar para el registro de cuenta, el marcado se vería así:

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

Lo que quiero hacer es que el contenedor div inyecte la clase "error" como lo he codificado en la primera entrada. (Entonces, al ingresar a la página, el div tendría una clase de "clearfix" pero si ese bloque de entrada falla en la validación, lo etiquetaría como "clearfix error"). Supongo que tendré que actualizar el bloque div para incluir una identificación de algún tipo y quizás agregar un nuevo atributo de datos al ValidationMessage. No tengo problemas para extender el ayudante ValidationMessageFor. Simplemente no estoy 100% seguro de cuál debería ser el enfoque para ampliar la biblioteca que está allí. ¿Alguna sugerencia sobre cómo abordar esto?

TIA.

ACTUALIZACIÓN:

Creo que este enfoque es razonable:

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

Al decorar mi mensaje de validación con un nombre de contenedor de datos, podría apuntar al contenedor div. Ahora solo necesito averiguar cómo interceptar el mensaje de validación.

preguntado el 27 de agosto de 11 a las 15:08

¿Has logrado resolver esto? -

Entonces @JBright, ¿resolviste esto o alguno de estos respondió la pregunta? -

7 Respuestas

La $.validator.setDefaults El método me resolvió este problema con Bootstrap de Twitter. Estoy usandojquery.validate.js y jquery.validate.unobtrusive.js.

Dado que la validación discreta en DOM ready escanea su documento y almacena en caché opciones de validación discretas para cada formulario que encuentra, es necesario llamar al $.validator.setDefaults antes de escanear el documento.

// 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
});

Respondido 22 ago 12, 12:08

Si también te gustan los errores del servidor resaltados, usa algo como $('form .input-validation-error').closest(".clearfix").addClass("error"); en documento listo. - Robert Massa

Encontré el mismo problema. Lo estoy abordando agregando una extensión a la clase HtmlHelper.

Esto es lo que hice para 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));

        }
    }

Y en el archivo .cshtml reemplazo Html.ValidationSummary con esto:

@Html.BootstrapValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")

Recuerde agregar el espacio de nombres de su clase de extensión en la carpeta de vistas del archivo web.config.

Publicaré aquí más tarde si abordo el elemento de entrada individual antes que usted. HTH

Respondido el 01 de Septiembre de 11 a las 22:09

Hice algo similar: un "BootstrapValidationSummary" que podría usarse opcionalmente. Mi código está bastante cerca de mi actualización original, pero me gusta lo que propuso Germán con jquery. - JBright

En lugar de reinventar esta rueda en particular, verifique el complemento validationEngine disponible en http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/.

Puede personalizar los elementos emergentes como desee, y es trivial conectarse a jQuery.validate.js.

Respondido 28 ago 11, 08:08

Prefiero cambiar el CSS de bootstrap. Acabo de agregar las clases de jQuery validate en el lugar correcto. error de validación de campo y error de validación de entrada

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

Respondido el 04 de enero de 12 a las 16:01

Puede integrar la validación MVC3 con el marco Bootstrap agregando el siguiente javascript a su página (Ver)

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

Además, en las Vistas (por ejemplo, "Create.cshtml") asegúrese de que los campos del formulario tengan el siguiente formato ...

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

Con esta solución, lo más probable es que sea suficiente agregar un javascript sin editar la Vista.

Respondido el 14 de diciembre de 12 a las 18:12

Lo que hice fue tomar las clases css para los errores de validación y crear un nuevo archivo css con las mismas clases pero con valores de arranque.

Puede encontrarlo en un paquete nuget en: http://nuget.org/List/Packages/MahApps.Twitter.Bootstrap

Eso también proporciona algunas plantillas de andamio para crear automáticamente nuevas vistas.

respondido 17 nov., 11:09

Necesitaba resolver esto usando Bootstrap 3.1 y Razor. Esto es lo que usé:

$.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');
            }
        });
    });
});

Esta es una combinación de la respuesta de @ german y la ayuda de esto post por "theBraindonor". Actualizado para usar nuevas clases de Bootstrap 3.

respondido 07 nov., 13:21

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.