Puedo hacer que aparezcan popovers usando bootstrap con bastante facilidad, y también puedo hacer validaciones usando el complemento de validación de jQuery estándar o el motor de validación de jQuery , pero no puedo encontrar la manera de introducir uno en el otro.
Creo que lo que necesito es un gancho al que llame el validador cuando quiera mostrar una notificación, darle un cierre que pase el mensaje y el elemento de destino a un popover. Esto parece una especie de inyección de dependencia.
Todo bien en teoría, pero no puedo averiguar dónde está ese gancho, o incluso si existe uno en cualquiera de los motores de validación. Ambos parecen decididos a asumir la responsabilidad de mostrar notificaciones con todo tipo de opciones elaboradas para la ubicación, envoltorios, estilos cuando todo lo que busco son los tipos de error (ni siquiera necesito el texto del mensaje) y el elemento relacionado a. Encontré ganchos para todo el formulario, no para las notificaciones individuales.
Prefiero los sistemas de validación que usan clases para definir reglas, ya que funcionan bien con formularios creados dinámicamente.
¿Alguien tiene una solución o una mejor idea?
fuente
Este es un ejemplo práctico:
$('form').validate({ errorClass:'error', validClass:'success', errorElement:'span', highlight: function (element, errorClass, validClass) { $(element).parents("div[class='clearfix']").addClass(errorClass).removeClass(validClass); }, unhighlight: function (element, errorClass, validClass) { $(element).parents(".error").removeClass(errorClass).addClass(validClass); } });
Realmente no usa ventanas emergentes de arranque, pero se ve muy bien y es fácil de lograr.
ACTUALIZAR
Entonces, para tener la validación de popover, puede usar este código:
$("form").validate({ rules : { test : { minlength: 3 , required: true } }, showErrors: function(errorMap, errorList) { $.each(this.successList, function(index, value) { return $(value).popover("hide"); }); return $.each(errorList, function(index, value) { var _popover; _popover = $(value.element).popover({ trigger: "manual", placement: "top", content: value.message, template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>" }); // Bootstrap 3.x : //_popover.data("bs.popover").options.content = value.message; // Bootstrap 2.x : _popover.data("popover").options.content = value.message; return $(value.element).popover("show"); }); } });
Obtienes algo como esto:
Echa un vistazo a jsFiddle .
fuente
Chris Fulstow lo tenía bien, pero todavía me tomó un tiempo, así que aquí está el código completo:
Esto muestra el popover en caso de error y oculta las etiquetas de error predeterminadas:
$('#login').validate({ highlight: function(element, errClass) { $(element).popover('show'); }, unhighlight: function(element, errClass) { $(element).popover('hide'); }, errorPlacement: function(err, element) { err.hide(); } }).form();
Esto configura el popover. Lo único que necesita de esto es disparador: 'manual'
$('#password').popover({ placement: 'below', offset: 20, trigger: 'manual' });
El título y los atributos de contenido pasados a popover no funcionaban, así que los especifiqué en línea en mi entrada de #password con data-content = 'Mínimo 5 caracteres' y data-original-title = 'Contraseña no válida'. También necesita rel = 'popover' en su formulario.
Esto funciona, pero la ventana emergente parpadea al anular la selección. ¿Alguna idea de como arreglarlo?
fuente
Aquí hay un seguimiento de la excelente sugerencia de Varun Singh que evita el problema del "parpadeo" de la validación que intenta constantemente "mostrar" a pesar de que la ventana emergente ya está presente. Simplemente agregué una matriz de estados de error para capturar qué elementos muestran errores y cuáles no. ¡Funciona de maravilla!
var errorStates = []; $('#LoginForm').validate({ errorClass:'error', validClass:'success', errorElement:'span', highlight: function (element, errorClass) { if($.inArray(element, errorStates) == -1){ errorStates[errorStates.length] = element; $(element).popover('show'); } }, unhighlight: function (element, errorClass, validClass) { if($.inArray(element, errorStates) != -1){ this.errorStates = $.grep(errorStates, function(value) { return value != errorStates; }); $(element).popover('hide'); } }, errorPlacement: function(err, element) { err.hide(); } }); $('#Login_unique_identifier').popover({ placement: 'right', offset: 20, trigger: 'manual' }); $('#Login_password').popover({ placement: 'right', offset: 20, trigger: 'manual' });
fuente
popover
para cada campo que desea validar? Si es así, eso es una locura .Esta extensión de jQuery para el complemento de validación de jQuery (probado con la versión 1.9.0) funcionará.
https://github.com/tonycoco/rails_template/blob/master/files/assets/javascripts/jquery.validate.bootstrap.js
Esto también agrega algunos mensajes de error de Rails-esk.
fuente
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; }
fuente
Así es como lo hice con Bootstrap 2.xy jQuery Validate 1.9
$('#form-register').validate({ errorElement: 'span', errorClass:'help-inline', highlight: function (element, errorClass) { $(element).parent().parent().addClass('error'); }, unhighlight: function (element, errorClass) { $(element).parent().parent().removeClass('error'); }});
fuente
Por favor, eche un vistazo a lo siguiente:
- https://gist.github.com/3030983
Creo que es el más simple de todos.
EDITAR
Código del enlace:
$('form').validate({ rules: { numero: { required: true }, descricao: { minlength: 3, email: true, required: true } }, showErrors: function (errorMap, errorList) { $.each(this.successList, function (index, value) { $(value).popover('hide'); }); $.each(errorList, function (index, value) { console.log(value.message); var _popover = $(value.element).popover({ trigger: 'manual', placement: 'top', content: value.message, template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>' }); _popover.data('popover').options.content = value.message; $(value.element).popover('show'); }); } });
fuente
¡Muchas gracias por el aviso! Aquí está mi versión de Bootstrap pero con información sobre herramientas. En mi opinión, es más elegante que los popovers. Sé que la pregunta era para popovers, así que por favor no vote en contra por esta razón. Quizás a alguien le gustará de esta manera. Me encanta cuando estoy buscando algo y encontré nuevas ideas en Stackoverflow. Nota: no es necesario marcar el formulario.
$('#LoginForm').validate({ rules: { password: { required: true, minlength: 6 }, email_address: { required: true, email: true } }, messages: { password: { required: "Password is required", minlength: "Minimum length is 6 characters" }, email_address: { required: "Email address is required", email: "Email address is not valid" } }, submitHandler: function(form) { form.submit(); }, showErrors: function (errorMap, errorList) { $.each(this.successList, function (index, value) { $('#'+value.id+'').tooltip('destroy'); }); $.each(errorList, function (index, value) { $('#'+value.element.id+'').attr('title',value.message).tooltip({ placement: 'bottom', trigger: 'manual', delay: { show: 500, hide: 5000 } }).tooltip('show'); }); } });
fuente
Así es como hice que sucediera. Pero implica hacer 2 cambios en el script de validación (obtuve el código para bootstrap 1.4 aquí y luego lo modifiqué - http://mihirchitnis.net/2012/01/customizing-error-messages-using-jquery-validate-plugin- para-twitter-bootstrap / )
Mi llamado a validar:
$("#loginForm").validate({ errorClass: "control-group error", validClass: "control-group success", errorElement: "span", // class='help-inline' highlight: function(element, errorClass, validClass) { if (element.type === 'radio') { this.findByName(element.name).parent("div").parent("div").removeClass(validClass).addClass(errorClass); } else { $(element).parent("div").parent("div").removeClass(validClass).addClass(errorClass); } }, unhighlight: function(element, errorClass, validClass) { if (element.type === 'radio') { this.findByName(element.name).parent("div").parent("div").removeClass(errorClass).addClass(validClass); } else { $(element).parent("div").parent("div").removeClass(errorClass).addClass(validClass); } } });
Luego, debe cambiar 2 cosas en jquery.validate.js
1. aplique esta solución: https://github.com/bsrykt/jquery-validation/commit/6c3f53ee00d8862bd4ee89bb627de5a53a7ed20a
2. Después de la línea 647 (en la función showLabel, cree la parte de la etiqueta ) después de la línea
.addClass(this.settings.errorClass)
agregar línea:.addClass("help-inline")
alguien tal vez pueda encontrar una manera de aplicar la segunda corrección en la función de validación, pero no he encontrado una manera, ya que se llama a showLabel después de resaltar.
fuente
Esto es lo que puse en mi validación para cumplir con las pautas de Twitter Bootstrap. El mensaje de validación de error se coloca en a
<span class=help-inline>
y queremos resaltar el contenedor externo comoerror
osuccess
:errorClass:'help-inline', errorElement:'span', highlight: function (element, errorClass, validClass) { $(element).parents("div.clearfix").addClass('error').removeClass('success'); }, unhighlight: function (element, errorClass, validClass) { $(element).parents(".error").removeClass('error').addClass('success'); }
fuente
Aquí hay una actualización de la excelente respuesta de Kenny Meyer anterior . Hubo un par de problemas que impidieron que funcionara para mí, que he abordado en este fragmento:
showErrors: function (errorMap, errorList) { $.each(this.successList, function (index, element) { return $(element).popover("destroy"); }); $.each(errorList, function (index, error) { var ele = $(error.element); //Instead of referencing the popover directly, I use the element that is the target for the popover ele.popover({ trigger: "manual", placement: "top", content: function(){ //use a function to assign the error message to content return error.message }, template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>' }); //bs.popover must be used, not just popover ele.data("bs.popover").options.content = error.message; return $(error.element).popover("show"); }); }
fuente
No estoy seguro de si esto es relevante para la discusión porque el cartel original pedía ganchos para mostrar / ocultar los popovers de arranque.
Estaba buscando una validación simple y los popovers no importaban. Una publicación relacionada y la primera en los resultados de búsqueda de Google ya se ha marcado como duplicado de esta pregunta. Así que tenía sentido mencionar este excelente JS jqValidation de @ ReactiveRaven, acertadamente llamado jqBootstrapValidation, que combina bien con Twitter Bootstrap. La configuración solo lleva unos minutos. Descárgalo aquí .
Espero que esto agregue valor.
fuente
tl; dr evite la necesidad de enumerar elementos emergentes explícitos mediante el uso de un mapa hash para almacenar los identificadores de los elementos y la creación de elementos emergentes sobre la marcha (combinación de los enfoques de Jeffrey Gilbert y Kenny Meyer).
Aquí está mi opinión, que soluciona el problema de parpadeo mencionado por otros, pero a diferencia de la respuesta de @Jeffrey Gilbert, no usa una lista (
errorStates
) sino que usa un mapa de error . Mapas hash FTW. Creo que recuerdo haber leído en alguna parte que todos los problemas en CS se pueden resolver con un mapa hash :)var err_map = new Object(); // <--- n.b. $("form#set_draws").validate({ rules: { myinput: { required: true, number: true }, }, showErrors: function(errorMap, errorList) { $.each(this.successList, function(index, value) { if (value.id in err_map) { var k = err_map[value.id]; delete err_map[value.id]; // so validation can transition between valid/invalid states k.popover("hide"); } }); return $.each(errorList, function(index, value) { var element = $(value.element); if( ! (value.element.id in err_map) ) { var _popover = element.popover({ trigger: "manual", placement: "top", content: value.message, template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>" }); _popover.data("popover").options.content = value.message; err_map[value.element.id] = _popover; return err_map[value.element.id].popover("show"); } }); } });
Gracias a todos los que publicaron ideas sobre esto.
fuente
Mira esto: https://github.com/mingliangfeng/jquery.validate.bootstrap.popover
Muestra cómo usar Bootstrap popover css, en lugar de JS. La ventana emergente del método JS causará un problema de parpadeo.
fuente
Si usa el código Kenny Meyer anterior para ventanas emergentes, tenga en cuenta que las reglas que verifican el contenido de un campo pero no son necesarias, como una URL válida, harán que la ventana emergente no desaparezca al borrar el campo. Vea abajo onkeyup para la solución. Si alguien tiene una mejor solución, publique.
onkeyup: function(element, event) { if($(element).valid()) { return $(element).popover("hide"); } }
fuente