Pregunta

He estado haciendo algo de desarrollo usando el xval Framework para .NET para vincular algunas de las reglas de validación para los modelos en el lado del servidor junto con alguna validación del lado del cliente utilizando el complemento de validación jQuery junto con complemento de formulario jQuery para enviar el formulario.

Sin embargo, tengo problemas para vincularlos todos juntos.

Estoy tratando de lograr los siguientes:

  1. Permitir que el cliente realice una validación básica utilizando reglas definidas llamando rules("add", options") Plugin para la validación de jQuery (esto es lo que XVAL usa para obtener reglas definidas en el lado del servidor en el modelo).

  2. Si la validación del cliente tiene éxito, haga que la llamada al servidor ingrese los datos del formulario que realizan validación nuevamente (en elementos que fueron validados en el cliente, así como cualquier otra validación que no pudiera 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 establezca la pantalla de error para los campos.

He configurado los metadatos para el complemento 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 se traduce en una serie de llamadas a rules("add", options) que el complemento de validador jQuery luego procesa.

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 presenta, pero los valores no se validan en absoluto.

¿Cómo puedo enviar el formulario utilizando el complemento de formulario jQuery mientras el complemento de validación de jQuery a través de una llamada a ajax?

¿Fue útil?

Solución

los lo más importante Lo que debe tener en cuenta al armar todo esto es la pequeña documentación (que no es realmente evidente en la documentación de XVAL, lo que abstrae la llamada rules("add", options) en la llamada a xVal.AttachValidator) por rules("add", options) (énfasis mío):

Agrega las reglas especificadas y devuelve todas las reglas para el primer elemento coincidente. Requiere que el formulario principal sea validado, es decir, $ ("forma"). Validate () se llama primero.

Esto es especialmente importante cuando el complemento de formulario jQuery entra en juego, y desea enviar el formulario a través de AJAX, ya que tiene que configurar un submitHandler opción en la llamada a validate(options), al igual que:

<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 con respecto a las llamadas a rules("add", options), la llamada a validate(options) debe venir antes de las llamadas a rules("add", options).

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

Al final, esto significa que el código del lado del cliente debe verse así al armarlo todo:

<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 conectado, lo último que debe hacer es qué hacer cuando regresa el método del lado del servidor.

Querrá que el JSON que se devuelva de estas llamadas sea algo así como un caparazón estandarizado ViewModel donde tiene el contenido específico de respuesta envuelto en una pieza más estandarizada que expone la información que necesita 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, devuelva lo mismo que el anterior, pero con una ubicación que tiene la URL a la que el usuario debe ser redirigido al éxito (o nulo si no fue exitoso) y un mapa que se puede pasar directamente al showErrors(errors) Método 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."
        }
    }
}

Dado eso, el success campo de la options parámetro pasó a ajaxSubmit debe ser 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 verificar si el newLocation La propiedad está definida. Si se define, entonces redirige el documento actual a la ubicación (que generalmente sería la URL del recurso recién guardado).

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top