javascript - language - Plugin de validación de jQuery: invocar errorPlacement function when onfocusout, keyup y click
jquery validate rules (2)
Estoy usando el complemento de validación jquery y quiero usar la función errorPlacement para agregar mensajes de error al atributo de título de campos y mostrar solo ✘ al lado del campo.
Esto funciona muy bien cuando el formulario se envía con el botón de enviar pero cuando se desencadena alguno de los siguientes eventos: - onfocusout - click - onkeyup
Las comprobaciones de validación se ejecutan pero omite la función errorPlacement y agrega el mensaje de error completo después del campo, como el comportamiento predeterminado.
Estoy usando el siguiente código:
$("#send-mail").validate({
debug: true,
// set this class to error-labels to indicate valid fields
success: function(label) {
// set text as tick
label.html("✔").addClass("valid");
},
// the errorPlacement has to take the table layout into account
errorPlacement: function(error, element) {
console.log("errorPlacement called for "+element.attr("name")+" field");
// check for blank/success error
if(error.text() == "")
{
// remove field title/error message from element
element.attr("title", "");
console.log("error check passed");
}
else
{
// get error message
var message = error.text();
// set as element title
element.attr("title", message);
// clear error html and add cross glyph
error.html("✘");
console.log("error check failed: "+message);
}
// add error label after form element
error.insertAfter(element);
},
ignoreTitle: true,
errorClass: "invalid"
});
Gracias jitter ,
Hice algunas excavaciones y encontré el mismo problema.
Logré hacerlo funcionar "pirateando" la función showLabel en jquery.validation.js. No es bonito, pero funciona.
Anular la opción de función showErrors me evitaría tener que cambiar el código del complemento para que lo revise.
Aquí está el código que utilicé para el método showLabel:
showLabel: function(element, message) {
// look for existing error message
var label = this.errorsFor( element );
// existing error exist?
if (label.length) {
// refresh error/success class
label.removeClass().addClass( this.settings.errorClass );
// check if we have a generated label, replace the message then
label.attr("generated");
// is message empty?
if(!message)
{
// add tick glyph
label.html("✔");
// wipe element title
$(element).attr(''title'', message)
}
else
{
// clear error html and add cross glyph
label.html("✘");
// update element title
$(element).attr(''title'', message)
}
// && label.html(message);
}
else {
// create label
label = $("<" + this.settings.errorElement + "/>")
.attr({"for": this.idOrName(element), generated: true})
.addClass(this.settings.errorClass)
.html(message || "");
if ( this.settings.wrapper ) {
// make sure the element is visible, even in IE
// actually showing the wrapped element is handled elsewhere
label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
}
if ( !this.labelContainer.append(label).length )
this.settings.errorPlacement
? this.settings.errorPlacement(label, $(element) )
: label.insertAfter(element);
}
if ( !message && this.settings.success ) {
label.text("");
typeof this.settings.success == "string"
? label.addClass( this.settings.success )
: this.settings.success( label );
}
this.toShow = this.toShow.add(label);
}
Su problema es que el complemento solo llama a la función errorPlacement
una vez para cada elemento que se valida. Namly cuando la etiqueta de error para el elemento se crea por primera vez. Luego, el complemento simplemente reutiliza la etiqueta ya presente y simplemente reemplaza el html dentro (u oculta la etiqueta de error si el elemento ahora es válido). Es por eso que su cruz se elimina y se muestra el mensaje de error real.
Solo para asegurarse de que el flujo del complemento esté despejado.
- elemento (no hay etiqueta de error todavía)
- elemento se valida en algún momento
- el plugin crea la etiqueta de error y llama a
errorPlacement
function - elemento "cruz" (mensaje de error en el título)
- El elemento se enfoca y tú cambias algo
- el complemento revalida el elemento
- Ve que la etiqueta de error ya fue creada (y colocada)
- el plugin simplemente llama a
label.html(message)
lugar de eliminar la etiqueta vieja ylabel.html(message)
alabel.html(message)
Entonces, ves que tu problema es un tipo de optimización que hace el complemento para guardar algunas inserciones / eliminaciones de etiquetas de error innecesarias. Lo cual también tiene sentido.
Puede verificar lo que dije mirando el código de validación-fuente
jquery.validate.js v1.6 check in function showLabel
lines 617-625 para las piezas relevantes.
Una posible solución podría ser proporcionar una devolución de llamada showErrors
personalizada que resuelva el problema con la fuerza bruta.
Algo a lo largo de las líneas de
$("#send-mail").validate({
...
showErrors: function(errorMap, errorList) {
for (var i = 0; errorList[i]; i++) {
var element = this.errorList[i].element;
//solves the problem with brute force
//remove existing error label and thus force plugin to recreate it
//recreation == call to errorplacement function
this.errorsFor(element).remove();
}
this.defaultShowErrors();
}
...
});
Tal vez haya una solución más limpia para esto, pero esto debería hacerlo y darle tiempo para investigar una mejor solución.