jquery - validate - resetform()
Agregar y eliminar manualmente los errores de validación al validador jQuery (3)
Tengo un formulario de búsqueda y una cuadrícula basada en nocaut para obtener resultados. Cuando se realiza la búsqueda, hay una validación del lado del servidor en asp.net mvc, y si el estado del modelo no es válido, se devuelve la lista de errores del modelo a través de JSON.
Tengo la validación de jQuery ya configurada, y las validaciones predeterminadas (expresiones regulares, requeridas, etc.) se asignan automáticamente usando el complemento jquery.unobtrusive
. Encontré $.validate().showErrors({prop:error})
como una forma de mostrar dinámicamente errores basados en la respuesta json del servidor, pero estoy pensando que esta no es la forma correcta de usarlo para mostrar los mensajes de validación del servidor. ya que el campo no se puede restablecer después (la class
input-validation-error
no se elimina).
Necesito un método de trabajo para establecer y restablecer errores en el cliente, si existe en $.validate
.
Hay un ejemplo de mi problema en jsFiddle: http://jsfiddle.net/goranobradovic/ughCm/
Para reproducirlo, haga clic en agregar error, luego elimine el error, la entrada se mantiene roja.
Esto se debe a que la función showErrors no agrega ninguna regla que se desencadene por validación, por lo que el campo permanece ''válido'' y no está en la lista elements()
que se utiliza en resetForm
para eliminar la class
input-validation-error
de los campos no válidos.
Básicamente, quiero una manera simple de agregar / eliminar la regla de validación con un mensaje personalizado que nunca se satisface en el cliente, para evitar el envío de formularios cuando configuro el error manualmente y tengo que eliminar la class
invalid
después de eliminar el mensaje de error.
Hice algo un poco más simple: básicamente, agregué la capacidad de registrar más completamente el error en el validador. Agregué lo siguiente a jquery.validate.js (debajo de showErrors):
addErrors: function (errors) {
for (var i = 0; i < errors.length; i++) {
this.errorList.push({
element: $(errors[i].element)[0],
message: errors[i].message
});
}
this.showErrors();
},
a continuación, en lugar de llamar a form.validate (). showErrors () puede hacer, por ejemplo
form.validate().addErrors([{
element: $(''#myinput''),
message: ''A manual error message''
}]);
Finalmente, dado que es posible que el formulario no se haya marcado como no válido cuando se envió, es posible que desee forzar una validación de la clave o similar:
$(''#myinput'').one(''keyup'', function(){ $(this).valid(); });
(Nota: esto no es una prueba de batalla, pero estoy seguro de que al menos una solución se encuentra de esta manera en alguna parte)
Lo he resuelto anulando la función showErrors en el validador de jQuery con el mío, que es compatible con tramos de validación generados discretamente y limpiando campos válidos que tienen una clase no válida. No es una solución muy agradable, pero funciona.
Aquí está jsfiddle con la solución: http://jsfiddle.net/goranobradovic/ughCm/5/
ACTUALIZACIÓN: como el enlace al sitio externo no es la respuesta adecuada de acuerdo con las directrices del sitio, voy a agregar código de muestra aquí. Para cualquiera que ya esté familiarizado con la validación de jQuery, solo mire dos líneas de código en la función showErrors. Lo asigné al validador con validator.settings.showErrors = showErrors ;.
HTML:
<form id="experiment" action="/" method="post">
<fieldset>
<legend></legend>
<div class="editor-label">
<label for="Email">Email</label>
</div>
<div class="editor-field">
<input data-val="true" data-val-email="&#39;Email&#39; not valid email address." data-val-required="&#39;Email&#39; is mandatory." id="Email" name="Email" type="text" value=""><span class="field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="FirstName">First name</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="FirstName" name="FirstName" type="text" value="">
<span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="LastName">Last name</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="LastName" name="LastName" type="text" value="">
<span class="field-validation-valid" data-valmsg-for="LastName" data-valmsg-replace="true"></span>
</div>
</fieldset>
<p>
<button type="submit" class="save ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-secondary" value="Save" role="button" aria-disabled="false"><span class="ui-button-text">Save</span><span class="ui-button-icon-secondary ui-icon ui-icon-disk"></span></button>
</p>
</form>
<br/>
<button id="add">Add error</button>
<button id="remove">Remove error</button>
<br/>
<br/>
Debug:
<div id="debug"></div>
JavaScript:
var validator = {};
function addError(e) {
validator.showErrors({
"FirstName": "test error"
});
}
function removeError(e) {
validator.showErrors({
"FirstName": null
});
fixValidFieldStyles($("form"), validator);
}
$(document).ready(function() {
var $form = $("#experiment");
// prevent form submission
$form.submit(function(e) {
e.preventDefault();
return false;
});
$("#add").click(addError);
$("#remove").click(removeError);
$("#debug").html("<h1>Validator properties:</h1>");
validator = $form.validate();
validator.settings.showErrors = showErrors;
for (var i in validator) {
var row = $("<span></span>").html(i).append("<br/>");
$("#debug").append(row);
}
});
function showErrors(errorMessage, errormap, errorlist) {
var val = this;
errormap.forEach(function(error, index) {
val.settings.highlight.call(val, error.element, val.settings.errorClass, val.settings.validClass);
$(error.element).siblings("span.field-validation-valid, span.field-validation-error").html($("<span></span>").html(error.message)).addClass("field-validation-error").removeClass("field-validation-valid").show();
});
}
function fixValidFieldStyles($form, validator) {
var errors = {};
$form.find("input,select").each(function(index) {
var name = $(this).attr("name");
errors[name] = validator.errorsFor(name);
});
validator.showErrors(errors);
var invalidFields = $form.find("." + validator.settings.errorClass);
if (invalidFields.length) {
invalidFields.each(function(index, field) {
if ($(field).valid()) {
$(field).removeClass(validator.settings.errorClass);
}
});
}
}
Terminé resolviendo el problema de una manera simple limpiando los errores y luego mostrando los nuevos errores.
// get the form inside we are working - change selector to your form as needed
var $form = $("form");
// get validator object
var $validator = $form.validate();
// get errors that were created using jQuery.validate.unobtrusive
var $errors = $form.find(".field-validation-error span");
// trick unobtrusive to think the elements were succesfully validated
// this removes the validation messages
$errors.each(function(){ $validator.settings.success($(this)); })
// clear errors from validation
$validator.resetForm();
// Then show the errors
$.validator().showErrors({prop:error}