2010-01-03 26 views
21

He estado haciendo un desarrollo utilizando el marco xVal para .NET para vincular algunas de las reglas de validación para modelos en el lado del servidor junto con la validación del lado del cliente usando el jQuery Validation plugin junto con el jQuery Form plugin para enviar el formulario.¿Cómo utilizar el complemento jQuery Validation con metadatos, jQuery Forms y xVal juntos?

Sin embargo, tengo problemas para vincularlas todas.

que estoy tratando de lograr lo siguiente:

  1. permitir que el cliente debe realizarse la validación básica utilizando reglas definidas llamando rules("add", options") plug-in para jQuery Validación (esto es lo que utiliza para obtener XVal reglas definidas en el lado del servidor en el modelo).

  2. Si la validación del cliente tiene éxito, realice la llamada al servidor para ingresar los datos del formulario realizando la validación nuevamente (en elementos que fueron validados en el cliente, así como cualquier otra validación que no pudo realizarse en el cliente) .

  3. Haga que el servidor devuelva un objeto en JSON que indique cualquier error que pueda tener campos específicos y luego configure la visualización de error para los campos.

He creado los metadatos para el plugin en la página ASP.NET MVC a través de una llamada a XVal de la siguiente manera:

<%= Html.ClientSideValidation<Model>("model") %> 

Esto se traduce en lo siguiente en el lado del cliente :

<script type="text/javascript"> 
xVal.AttachValidator("model", 
{ 
    "Fields": 
    [ 
     { 
      "FieldName":"title", 
      "FieldRules": 
      [ 
       { 
        "RuleName":"Required", 
        "RuleParameters":{} 
       }, 
       { 
        "RuleName":"StringLength", 
        "RuleParameters": 
        { 
         "MaxLength":"250" 
        } 
       } 
      ] 
     }, 
     { 
      "FieldName":"body", 
      "FieldRules": 
      [ 
       { 
        "RuleName":"Required", 
        "RuleParameters":{} 
       } 
      ] 
     } 
    ] 
}, {}) 
</script> 

lo anterior realmente sólo se traduce en una serie de llamadas a rules("add", options) la que el validador plugin de jQuery entonces procesos.

Sin embargo, al intentar publicar este formulario a través de formularios jQuery, la validación no tiene lugar en los valores del formulario. El formulario envía, pero los valores no se validan en absoluto.

¿Cómo puedo enviar el formulario utilizando el complemento jQuery Form mientras se valida mediante el complemento jQuery Validation a través de una llamada al ajax?

Respuesta

5

El más importante cosa a tener en cuenta al poner todo esto junto es la pequeña parte de la documentación (que no es muy evidente en la documentación de XVal, que abstrae la llamada a rules("add", options) en la llamada a xVal.AttachValidator) para rules("add", options) (énfasis mío):

Agrega las reglas especificadas y devuelve todas las reglas para la primera elemento emparejado. Requiere que el formulario padre esté validado, es decir, $ ("formulario"). Validate() se llama primero .

Esto es especialmente importante cuando el plugin Formulario jQuery entra en juego, y que desea enviar el formulario a través de AJAX, ya que tienes que configurar una opción submitHandler en la llamada a validate(options), así:

<script type="text/javascript"> 
    $(document).ready(function() { 
     // Initialize the form. Store the validator. 
     var validator = $("form").validate({ 

      // Called when the form is valid. 
      submitHandler: function(form) { 

       // Submit the form via ajax. 
       $(form).ajaxSubmit({ 

        // The return data type is json. 
        dataType: "json", 

        // The callback on a successful form 
        // submission. 
        success: function(data, statusText) { 

         // If the new location is not null, then 
         // redirect to that location. 
         if (data.data.newLocation) { 
          // Go to the new location. 
          document.location.href = data.data.newLocation; 

          // Get out. 
          return; 
         } 

         // There are errors, pass them to the validator 
         // for display. 
         validator.showErrors(data.data.errors); 
        } 
       }); 
      } 
     }); 
    }); 
</script> 

Debido a la documentación citada anteriormente en relación con las llamadas a rules("add", options), la llamada a validate(options) debe llegar antes que las llamadas a rules("add", options).

Si no lo hacen, entonces el submitHandler se ignora, nunca se llama.

Al final, esto significa que el código del lado del cliente tiene que tener este aspecto cuando se lo ponga todo junto:

<script type="text/javascript" src="jquery-1.3.2.min.js"></script> 
<script type="text/javascript" src="jquery.validate.min.js"></script> 
<script type="text/javascript" src="jquery.form.js"></script> 
<!-- Note this is only needed if using xVal. --> 
<script type="text/javascript" src="xVal.jquery.validate.js"></script> 
<!-- The call to validate the form must come first. --> 
<script type="text/javascript"> 
    $(document).ready(function() { 
     // Initialize the form. 
     $("form").validate({ 

      // Called when the form is valid. 
      submitHandler: function(form) { 

       // Submit the form via ajax. 
       $(form).ajaxSubmit({ 

        // The return data type is json. 
        dataType: "json", 

        // The callback. 
        success: function(data, statusText) { 

         // Alert the users to the message. 
         window.alert(statusText); 
        } 
       }); 
      } 
     }); 
    }); 
</script> 

<!-- Now make the calls to rules("add", options), AFTER the call to --> 
<!-- validate (options). It's separated into another block for  --> 
<!-- emphasis, but could be done in the block above.    --> 
<script type="text/javascript"> 
    // Make calls to rules("add", options). 
</script> 

<!-- Or, if you are using xVal, make the following call in the ASP.NET --> 
<!-- page but again, note it must come AFTER the call to    --> 
<!-- validate(options).            --> 
<%= Html.ClientSideValidation<Model>("model") %> 

Finalmente, con todo esto cableado, lo último que hay que hacer es lo que debe hacer cuando el método del lado del servidor retorna.

Querrás que el JSON que se devuelve de estas llamadas sea algo así como un shell de modelo de vista estandarizado donde tienes el contenido específico de respuesta envuelto en una pieza más estandarizada que expone la información que necesitas a través de llamadas homogéneas, algo como esto :

{ 
    // An integer, non-zero indicates faulure, with predefined ranges 
    // for standard errors across all operations, with other ranges for custom 
    // errors which are operation-specific. Examples of shared errors 
    // are not authenticated, not authorized, etc, etc. 
    resultCode: 0, 

    // A string, which is to be displayed to the user (usually in the 
    // form of a jQuery dialog, usually used for the common ranges of 
    // errors defined above. 
    message: null, 

    // An object with operation-specific results. 
    data: null 
} 

para los errores en el servidor, devuelven el mismo que el anterior, pero con una ubicación que tiene la URL, que el usuario debe ser redirigido a el éxito (o nulo si no se ha realizado correctamente) y un mapa que se puede pasar directamente al método showErrors(errors) si hay errores en los campos:

{ 
    resultCode: 0, 

    message: null, 

    data: 
    { 
     // Returned as a string. If not null, then this is the url 
     // that the client should be redirected to, as the server-side 
     // operation was successful. 
     newLocation: null, 

     // If not-null, then this is a map which has the names of the 
     // fields with the errors, along with the errors for the fields. 
     errors: 
     { 
      "model.title": "The title already exists in the system.", 
      "model.body": "The body cannot have malicious HTML code in it." 
     } 
    } 
} 

Teniendo en cuenta que, el pasado success field of the options parameter a ajaxSubmit debe quedar claro:

// The callback on a successful form 
// submission. 
success: function(data, statusText) { 

    // If the new location is not null, then 
    // redirect to that location. 
    if (data.data.newLocation) { 
     // Go to the new location. 
     document.location.href = data.data.newLocation; 

     // Get out. 
     return; 
    } 

    // There are errors, pass them to the validator 
    // for display. 
    validator.showErrors(data.data.errors); 
} 

Todo lo que hace es comprobar para ver si se define la propiedad newLocation. Si está definido, redirige el documento actual a la ubicación (que normalmente sería la url del recurso recientemente guardado).

Si no se define, entonces toma el mapa y la pasa al showErrors en el validador devuelto por una llamada a validate(options), el establecimiento de los mensajes de error utilizando el posicionamiento y estilo especificado por la llamada a validate(options).

Cuestiones relacionadas