38

Estoy validando un formulario utilizando las nuevas características de validación discretas en ASP.NET MVC 3.¿Cómo agregar una función 'submitHandler' al usar jQuery Unobtrusive Validation?

Así que no hay ningún código que haya escrito para configurar jQuery validate para comenzar a validar mi formulario. Todo se hace cargando la biblioteca jQuery.validate.unobtrusive.js.

Desafortunadamente tengo que golpear en un '¿estás seguro?' cuadro de mensaje cuando el formulario es válido pero antes de enviarlo. Con jQuery validar deberá añadir la opción handleSubmit cuando la inicialización de este modo:

$("#my_form").validate({ 
    rules: { 
    field1: "required", 
    field1: {email: true }, 
    field2: "required" 
    }, 
    submitHandler: function(form) { 
    if(confirm('Are you sure?')) { 
     form.submit(); 
    } 
    } 
}); 

Pero no es necesario para inicializar cuando se utiliza la biblioteca discreta.

Alguna idea de cómo/cómo puedo agregar un controlador de envío en ese caso?

Thx

+0

alguien: ¿hay alguna documentación oficial para esto de MS? –

+0

nota: el 'handleSubmit()' se llama solo si todos los valores de formulario validan. No se llama si tiene algún error. Es perfecto para pedir confirmación como usted (porque sabe que todo es válido), pero si desea un manejo especial cuando hay errores debe usar 'invalidHandler' - ver la respuesta de DGreen –

+0

En lugar de esperar hasta que ya esté inicializado, también puede llamar ['jQuery.validator.setDefaults'] (https://jqueryvalidation.org/jQuery.validator.setDefaults/) directamente y cualquier forma de inicialización posterior utilizará esa configuración. Solo asegúrese de que se ejecute antes de que se cargue el DOM y jQuery Validator inicialice automáticamente los formularios. – KyleMit

Respuesta

62

La biblioteca discreta adjuntará el validador sobre todas las formas, así que hay que reemplazar el submitHandler esta manera:

$("form").data("validator").settings.submitHandler = function (form) { alert('submit'); form.submit(); }; 
+2

Gracias @ petrhaus: buena respuesta simple que también ha aumentado mi comprensión de jQuery. – WooWaaBob

+4

Para formularios cargados dinámicamente (por ejemplo, cuadro de diálogo), primero debe llamar $ .validator.unobtrusive.parse ($ ('form')) o $ ('form'). Los datos se devolverán indefinidos. – parliament

+0

La parte frustrante de esto es que estaba atascado tratando de descubrir qué estaba yendo mal, porque si submitHandler se configuró en las etiquetas

59

me encontré con esta pregunta en la búsqueda de una manera de establecer la invalidHandler , a diferencia del submitHandler. Curiosamente, no puede establecer invalidHandler de la misma manera cuando usa una validación discreta.

La función no se activa cuando se detecta una forma inválida:

$("form").data("validator").settings.invalidHandler = function (form, validator) { 
    alert('invalid!'); 
}; 

Este enfoque funciona:

$("form").bind("invalid-form.validate", function() { 
    alert('invalid!'); 
}); 

Parece que se debe a la forma en que el jquery.validate.unobtrusive .js script inicializa el Validate complemento, y la forma en que el complemento invoca el controlador.

+0

Nota: el enfoque 'bind' aquí es, literalmente, la misma forma en que lo hace la función init jquery.validate –

+0

, ¿quién puede ayudar a explicar? no parece una forma "oficial", ¿cómo puedo definir submitHandler? – Elaine

+0

Intenté todo lo anterior para manejar el 'invalidHandler' mostrando una' alerta', pero no aparece. Y '$ ('form'). Data ('validator')' devuelve 'undefined'. – Shimmy

10

prefiero para inyectar un controlador de eventos, por lo que se puede enlazar a ... :)

//somewhere in your global scripts 
$("form").data("validator").settings.submitHandler = function (form) { 
    var ret = $(form).trigger('before-submit'); 
    if (ret !== false) form.submit(); 
};

De esta manera, puedo obligar a la misma en cualquier lugar necesita ...

//in your view script(s) 
$("form").bind("before-submit", function() { 
    return confirm("Are you sure?"); 
});
33

Los siguientes hallazgos pueden ser de interés para entender la diferencia entre:

submitHandler: Llamado cuando el formulario se valida correctamente - justo antes de la devolución de datos del servidor
invalidHandler: Llamado si la validación falla y no hay publicación atrás

@ La solución de DGreen definitivamente parece ser la mejor manera de inyectar un manejo especial si la validación del formulario falla y que hay que hacer algo, como mostrar un resumen de validación emergente (invalidHandler)

$("form").bind("invalid-form.validate", function() { 
    alert('invalid!'); 
}); 

solución @PeteHaus es la mejor manera de hacer algo si desea evitar la devolución de datos de una forma validado con éxito (submitHandler)

$("form").data("validator").settings.submitHandler = function (form) { 
                alert('submit'); form.submit(); }; 

sin embargo, estaba un poco preocupado por lo que el comportamiento estaba preponderantes con (o no anular) mediante la unión con el método .validate como esto - y por lo que tenía que hacer en cada sentido diferente. Así que revisé la fuente. Recomiendo encarecidamente a cualquiera que quiera comprender este procedimiento, más lo hace también: escriba algunas declaraciones de "alerta" o declaraciones de "depurador" y es bastante fácil seguirlo *

De todos modos resulta que cuando el controlador jquery.validate.unobtrusive inicializa jquery.validate plugin lo hace en el método parseElement() al recuperar las opciones creadas por el método validationInfo().

ValidationInfo() devuelve las opciones de la siguiente manera:

options: { // options structure passed to jQuery Validate's validate() method 
      errorClass: "input-validation-error", 
      errorElement: "span", 
      errorPlacement: $.proxy(onError, form), 
      invalidHandler: $.proxy(onErrors, form), 
      messages: {}, 
      rules: {}, 
      success: $.proxy(onSuccess, form) 
      }, 

El método onErrors() en jquery.validate.unobtrusive es responsable de crear dinámicamente el panel de resumen de validación para MVC. Si no está creando un panel de resumen de validación (con @Html.ValidationSummary(), que por cierto debe estar contenido en el cuerpo del FORMULARIO), este método es completamente inerte y no hace nada para que no tenga que preocuparse.

function onErrors(event, validator) { // 'this' is the form elementz 
    var container = $(this).find("[data-valmsg-summary=true]"), 
     list = container.find("ul"); 

    if (list && list.length && validator.errorList.length) { 
     list.empty(); 
     container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 

     $.each(validator.errorList, function() { 
      $("<li />").html(this.message).appendTo(list); 
     }); 
    } 
} 

Si realmente desea, puede desenlazar el manejador jquery.validate.unobtrusive como esto - pero yo no molestar a mí mismo

$("form").unbind("invalid-form.validate"); // unbind default MS handler 

Si usted se pregunta por qué esto funciona

$("form").data("validator").settings.submitHandler = ... 

y esto no funciona

$("form").data("validator").settings.invalidHandler = ... 

es porque submitHandler se llama explícitamente dentro de jquery.validate cuando se realiza la validación. Por lo tanto, no importa en qué punto está establecido.

validator.settings.submitHandler.call(validator, validator.currentForm); 

pero el invalidHandler está obligado a un evento durante init() como éste, así si se establece en su propio código que sea demasiado tarde

if (this.settings.invalidHandler) 
    $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); 

Un pequeño paso a paso a través del código hace que para una gran cantidad de conocimiento ¡a veces! Espero que esto ayude

* Asegúrese de que no tenga la minificación en paquetes habilitada.

+4

Explicación detallada agradable Simon especialmente comparado con mi respuesta vaga :) – DGreen

+3

@DGreen mis respuestas tienden a ser proporcionales a la cantidad de dolor y tiempo que el problema me ha causado, pero sin su respuesta habría sido mucho más tiempo para cuando lo había descubierto! –

+0

He intentado todo lo anterior para manejar el 'invalidHandler' mostrando una' alerta', pero no aparece. Y '$ ('form'). Data ('validator')' devuelve 'undefined'. – Shimmy

1

Basé esto en la respuesta original, que no funcionó para mí. Creo que las cosas han cambiado en jQuery.

Como es habitual, tome este código y añada una copiosa verificación de errores: D Utilizo un código similar para evitar presentaciones dobles en nuestros formularios y funciona bien en IE8 + (a partir de mvc4 y jquery 1.8.x).

$("#myFormId").confirmAfterValidation(); 

// placed outside of a $(function(){ scope 
jQuery.fn.confirmAfterValidation = function() { 
    // do error checking first. should be null if no handler already 
    $(this).data('validator').settings.submitHandler = confirmValidForm; 
}; 

function confirmValidForm(form) { 
    var validator = $(this); 
    var f = $(form); 
    if (confirm("really really submit?")) { 
     // unbind so our handler doesn't get called again, and submit 
     f.unbind('submit').submit(); 
    } 
     // return value is _ignored_ by jquery.validate, so we have to set 
     // the flag on the validator itself, but it should cancel the submit 
     // anyway if we have a submitHandler 
     validator.cancelSubmit = true; 
    } 
} 
Cuestiones relacionadas