jQuery Validate: agrega un error o valida la clase al div principal

Estoy utilizando Bootstrap de Twitter como marco para un proyecto en el que estoy trabajando. Estoy intentando validar un formulario de contacto simple usando el complemento jQuery Validate pero está causando algunos dolores de cabeza.

Estoy buscando agregar una clase de error o válida a la división principal de la entrada de cada formulario. Aquí está mi código de formulario:

 
@

Como puede ver, mi grupo div.control es el div al que quiero agregar la clase. Intenté usar el resaltado (como se sugiere aquí , pero esto simplemente no funcionó) y errorPlacement (ver más abajo) pero no lo estoy haciendo correctamente.

Idealmente, quiero que la clase se agregue / elimine en keyup para que mantenga la gran funcionalidad que ofrece el complemento. Este código simple funciona, pero no elimina la clase y solo funciona en el envío del formulario:

 $("#msg-form").validate({ errorPlacement: function(error, element) { $(element).parent('div').addClass('error'); } }); 

¿Alguien puede sugerir qué opción debería usar para lograr esto?

Gracias de antemano, puedo proporcionar cualquier información adicional si es necesario.

Intente usar las funciones de highlight y unhighlight :

 $("#msg-form").validate({ highlight: function(element) { $(element).parent('div').addClass('error'); }, unhighlight: function(element) { $(element).parent('div').removeClass('error'); } }); 

Desde mi respuesta en agregar clase a padre div si se produce un error de validación al usar la validación jQuery porque creo que agrega valor a las respuestas existentes en esta pregunta …

Acceda a la configuración del validador

La primera tarea es modificar el objeto de settings en el validador de su formulario. Puedes hacerlo de cualquiera de las siguientes maneras:

  1. Antes de cargar el formulario para todos los formularios, llame a jQuery.validator.setDefaults()
  2. Al inicializar el formulario pasando las opciones en .validate([options])
  3. Después de la inicialización, localice el objeto validador en el formulario con $("form").data("validator").settings

Ya que está usando MVC, la opción # 2 está fuera de cuestión, ya que la validación discreta iniciará automáticamente el formulario. Así que vamos a utilizar la opción 3 en el futuro: el objective aquí es poder personalizar la configuración en el formulario.

Anular el comportamiento predeterminado

Los métodos predeterminados que desearemos modificar son highlight y no resaltar , lo que resaltará los campos no válidos o revertirá los cambios realizados por la opción de resalte, respectivamente. Aquí está su comportamiento por defecto de acuerdo con el código fuente :

 highlight: function( element, errorClass, validClass ) { if ( element.type === "radio" ) { this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); } else { $( element ).addClass( errorClass ).removeClass( validClass ); } }, unhighlight: function( element, errorClass, validClass ) { if ( element.type === "radio" ) { this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); } else { $( element ).removeClass( errorClass ).addClass( validClass ); } } 

Así que tienes un par de opciones aquí también.

  1. Reemplace completamente esas funciones y escríbalas por su cuenta.
  2. Envuelva esas funciones y llámelas como de costumbre, pero agregue su propio código personalizado antes o después.

Opción 1 – Reemplazar al por mayor

Esta ruta es bastante fácil. Sólo escribe lo que quieras allí. Tal vez semilla del código fuente, tal vez haga lo suyo.

 var valSettings = $("form").data("validator").settings valSettings.highlight = function(element, errorClass, validClass) { ... } valSettings.unhighlight = function(element, errorClass, validClass) { ... } 

Opción 2 – Funciones de ajuste

Esto es menos intrusivo, así que probablemente sea preferible en la mayoría de los casos.

Como en última instancia, reemplazará el valor de valSettings.highlight , necesitará acceso a una versión original de la función original. Puedes guardar el tuyo o tomar uno de los valores predeterminados globales

 // original highlight function var highlightOriginal = $("form").data("validator").settings.highlight; var highlightDefaults = $.validator.defaults.highlight 

En términos de ajuste de las funciones de JavaScript, hay un par de ejemplos aquí , aquí y aquí . Aquí hay un ejemplo analizado de uno de esos, que ayudará a vincular this contexto a través de llamadas a funciones, preservará la aridad de los argumentos que se están pasando y persistirá el valor de retorno:

 function wrap(functionToWrap, beforeFunction) { return function () { var args = Array.prototype.slice.call(arguments), beforeFunction.apply(this, args); return functionToWrap.apply(this, args); }; }; 

Luego, también deberá definir rápidamente cualquier comportamiento adicional que desee activar cada vez que se realice la llamada. En este caso, busquemos la división primaria más cercana al elemento y actualicemos las siguientes clases:

 function highlightDecorator(element, errorClass, validClass) { $(element).closest("div").addClass(errorClass).removeClass(validClass); } 

Envolviéndolo todo (mira lo que hice allí)

 $(function () { var valSettings = $("form").data("validator").settings valSettings.highlight = wrap($.validator.defaults.highlight, highlightDecorator) valSettings.unhighlight = wrap($.validator.defaults.unhighlight, unhighlightDecorator) }); function wrap(functionToWrap, beforeFunction) { return function () { var args = Array.prototype.slice.call(arguments); beforeFunction.apply(this, args); return functionToWrap.apply(this, args); }; }; function highlightDecorator(element, errorClass, validClass) { $(element).closest("div").addClass(errorClass).removeClass(validClass); } function unhighlightDecorator(element, errorClass, validClass) { $(element).closest("div").addClass(validClass).removeClass(errorClass); } 

Entonces, cuando combinamos todas las funciones anteriores, debería verse algo como esto:

Demo de trabajo en fragmentos de stack y jsFiddle

 $(function () { var valSettings = $("form").data("validator").settings valSettings.highlight = wrap($.validator.defaults.highlight, highlightDecorator) valSettings.unhighlight = wrap($.validator.defaults.unhighlight, unhighlightDecorator) }); function wrap(functionToWrap, beforeFunction) { return function () { var args = Array.prototype.slice.call(arguments); beforeFunction.apply(this, args); return functionToWrap.apply(this, args); }; }; function highlightDecorator(element, errorClass, validClass) { $(element).closest("div").addClass(errorClass).removeClass(validClass); } function unhighlightDecorator(element, errorClass, validClass) { $(element).closest("div").addClass(validClass).removeClass(errorClass); } 
 input.input-validation-error { border: solid 1px red; } .input-validation-error label { color: red; } 
    

Puede que esté equivocado, pero parece que necesita .parent (‘div.control-group’) no .parent (), lo que agrega .error a la división incorrecta y no cambia los colores de las formas BootStraps a rojo.

Esto se debe a que la entrada que JQuery Validate está tratando de resaltar está dos debajo del grupo de control que BootStrap requiere para que .error surta efecto.

 $("#form").validate({ highlight: function(element, errorClass, validClass){ $(element).parents("div.control-group").addClass(errorClass).removeClass(validClass); }, 

Espero que esto ayude