Ajax y jQuery 1/6

Introducción a la librería jQuery para Ajax

Dejando por un tiempo los artículos sobre PHP y Symfony, pasemos a hablar sobre uno de los frameworks JavaScript que más me gusta. jQuery es según wikipedia:

… una biblioteca o framework de JavaScript, …, que permite simplificar
la manera de interactuar con los documentos HTML, manipular el árbol
DOM, manejar eventos, desarrollar animaciones y agregar interacción
con la tecnología AJAX a páginas web…
… jQuery, al igual que otras
bibliotecas, ofrece una serie de funcionalidades basadas en JavaScript
que de otra manera requerirían de mucho más código, es decir, con las
funciones propias de esta biblioteca se logran grandes resultados en
menos tiempo y espacio.

Dicho con otras palabras, jQuery es un archivo .js que contiene un montón de código JavaScript programado para hacernos la vida más fácil, abreviandonos el trabajo escribiendo menor cantidad de código. Para dar un ejemplo claro, si quiero obtener un elemento de la página con javascript lo haríamos usando el método getElementById() del objeto document, pasandole como parámetro el nombre del ID del elemento, mientras que con jQuery lo haríamos usando selectores CSS escribiendo jQuery(‘#ELEMENT_ID’). Veamos un ejemplo con el HTML que vamos a usar para el ejemplo.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="jquery-1.5.min.js"></script>
        <script type="text/javascript">
            jQuery('document').ready(function(){
                console.log(jQuery('#test1'));
            });
        </script>
    </head>
    <body>
 
        <form id="test1" action="procesar_form.php" method="post">
            <input type="text" name="user" id="user" />
            <input type="password" name="password" id="password" />
            <input type="submit" value="Submit" id="btnEnviar" />
        </form>
 
    </body>
</html>
<?php
print_r($_POST);
?>

Explicando un poco el código podemos ver dentro del body del primer documento un formulario que usaremos para los ejemplos y dentro del head vemos la importación de la librería jQuery y un bloque de código JavaScript que hace lo siguiente:

  1. Por medio de jQuery(‘document’) obtenemos la referencia al elemento ‘document’,

  2. jQuery nos devuelve el objeto document y accedemos a un evento llamado ready (onDomReady) parecido al onload pero que indica cuando todo el código de la página fue cargado (no así las imágenes) y asignamos una función anónima para que se ejecute en ese momento

  3. La función a ejecutarse contiene simplemente el código para que imprima en la consola del FireBug la referencia al formulario con id: test1.

Al abrir la página con el navegador, Firefox por supuesto :-P, veremos en la consola [form#test1 procesar_form.php] los que nos indica que la referencia fue obtenida.

Una vez que damos click al botón Submit (hay que notar que el type del botón también es submit y no button), los datos contenidos en el formulario son enviados a la página definida en el atributo action (procesar_form.php) y al ejecutarse veremos los datos enviados impresos en la página procesar_form.php por medio de la función print_r: Array ( [user] => myuser [password] => secret). Vemos que es un array que contiene todos los datos enviados. Hasta aquí es todo normal y por supuesto no hay nada de ajax.

Usando Ajax con jQuery

El objeto jQuery tiene un método post que permite enviar datos asíncronamente por medio post. Este método puede ser utilizado de varias maneras tal como se describe en la guía oficial:

Inicialmente pasaremos dos argumentos al método jQuery.post(),

  1. La página que va a procesar los datos enviados
  2. Los datos en sí en formato JSON o un string que los represente
jQuery.post('procesar_form.php', {user: "myuser", password: "secret"});

Para ejecutar este código podemos hacerlo directamente en la consola JavaScript del FireBug o reemplazar el código JavaScript escrito en la página test1.php dentro de la función que se ejecuta cuando el evento ready se ejecuta:

jQuery.post('procesar_form.php', {user: "myuser", password: "secret"}, function(datos_devueltos){
    console.log(datos_devueltos);
});

Este tercer argumento sería una función anónima que se ejecutará cuando la petición Ajax haya finalizado y recibe como argumento los datos que fueron devueltos, es decir que fueron escritos en la salida estándar.

Ahora veremos en la consola del FireBug el texto que fue escrito en la página procesadora. Cuando usamos POST estamos diciendo que queremos actualizar datos a diferencia del método GET que usamos cuando queremos obtener información del servidor. Perfectamente podríamos hacer que simplemente se escriba true o false en la página procesadora para poder validar obteniendo la respuesta si los datos fueron procesados o no.

<?php
//-- Abro conexión a la base de datos, escribo datos en archivos, envío emails, etc
if($todo_bien)
    echo true;
else
    echo false;
?>
jQuery.post('procesar_form.php', {user: "myuser", password: "secret"}, function(datos_devueltos){
    if(datos_devueltos)
        alert('Datos procesados correctamente');
    else
        alert('Ha ocurrido un error');
});

Rompamos la idea errónea de Ajax

Señores, esto que vimos “es Ajax”, no es que los elementos de la página cambien, aparezcan y desaparezcan tras una petición asíncrona al servidor sino simplemente “esa petición asíncrona”, lo que significa que enviamos y recibimos datos hacia y desde el servidor sin tener que recargar la página; que hagamos que los elementos aparezcan y desaparezcan tras la petición es simplemente JavaScript ejecutándose y manipulando el DOM del documento como por ejemplo utilizando innerHTML. Esto lo podremos ver en otro artículo.

Enviando el formulario con Ajax

Para los que hayan olvidado el formulario que teníamos en el ejemplo les hago darse cuenta que ejecutamos Ajax sin usarlo y es ahora donde, habiendo entendido el uso con jQuery, enviaremos nuestro formulario asíncronamente, pero hagamoslo primero desde la consola de FireBug ejecutando directamente ahí el código. Recordemos como quedó el último código que hicimos:

jQuery.post('procesar_form.php', {user: "myuser", password: "secret"}, function(datos_devueltos){
    if(datos_devueltos)
        alert('Datos procesados correctamente');
    else
        alert('Ha ocurrido un error');
});

La diferencia es que los datos enviados como segundo argumento no deben estar directamente así sino que se tienen que obtener del formulario. Para obtenerlos es muy sencillo a través de jQuery('#test1') tenemos la referencia al formulario pero tenemos que pasarlo como un string para eso utilizamos un método del formulario devuelto por jQuery llamado serialize() que hace exactamente eso jQuery('#test1').serialize(). Pueden ejecutar esto directamente en el FireBug y obtendrán la siguiente cadena: "user=myuser&password=secret" (Ojo: hay que escribir los datos primero en el form :-P). De esta manera nuestro código quedaría así:

jQuery.post('procesar_form.php', jQuery('#test1').serialize(), function(datos_devueltos){
    if(datos_devueltos)
        alert('Datos procesados correctamente');
    else
        alert('Ha ocurrido un error');
});

Por último, en el action del form ya está el nombre de la página que va a procesar los datos por lo que sería buena idea reutilizarlo y no escribirlo de nuevo en el primer argumento, para esto podemos obtener la referencia al formulario y obtener el valor del atributo “action” con jQuery(‘#test1’).attr(‘action’) quedando nuestro script más portable así:

jQuery.post(jQuery('#test1').attr('action'), jQuery('#test1').serialize(), function(datos_devueltos){
    if(datos_devueltos)
        alert('Datos procesados correctamente');
    else
        alert('Ha ocurrido un error');
});

Ahora que lo fuimos probando en el FireBug solo nos queda asignar este código al evento onlick del botón pero antes quiero cambiar el type del input a button para que no realice el submit sino que solo ejecute la llamada Ajax por medio de JavaScript (en el siguiente artículo volveremos a tocar este tema).

Para asignar esta función al evento onclick del botón obtendremos la referencia al botón por medio del “id” y sobrescribiremos el evento dentro de la página

<script type="text/javascript">
jQuery('document').ready(function(){
    jQuery('#btnEnviar').click(function(){
        jQuery.post(jQuery('#test1').attr('action'), jQuery('#test1').serialize(), function(datos_devueltos){
            if(datos_devueltos)
                alert('Datos procesados correctamente');
            else
                alert('Ha ocurrido un error');
        });
    })
});
</script>

De esta manera hicimos lo siguiente:

  1. Con el evento ready del objeto document hacemos que se ejecute cuanto sigue cuando el DOM este completamente cargado

  2. En ese momento se agregará una función a ejecutarse cuando se presione sobre el botón btnEnviar

  3. Una vez que el usuario presiona el botón se ejecutará nuestra llamada Ajax al servidor y tendremos nuestro ejemplo terminado.
    Espero que hayan entendido en especial el concepto del Ajax que es lo más importante y como segundo objetivo para el artículo que hayan aprendido a usar el Ajax para enviar datos de un formulario. Como tarea les dejo la idea de meter todo eso en una función genérica para reutilizarlo con solo una línea 🙂

Nos vemos en la próxima.

Los archivos de este artículos los puedes descargar aquí

Puedes ver el siguiente artículo sobre esta serie aquí.

11 comentarios en “Ajax y jQuery 1/6”

  1. Micayael. Gracias me ha servido muchísimo esta guía.

    Cuando mezclo en un formulario validación y Ajax como por ejemplo:

    $(“#forma”).validate({
    rules: {
    prueba: {
    required: true
    }
    },
    messages: {
    prueba: {
    required: “Por favor ingrese la descripción del comprobante”
    }
    }
    });

    label.error {
    background: no-repeat;
    }

    $(document).ready(function(){
    $(“#boton”).click(function(evento) {
    evento.preventDefault();
    $.post($(‘#forma’).attr(‘action’), $(‘#forma’).serialize(), function(data){
    if(data) {
    $(‘#nuevaimputacion’).html(“Han devuelto: ” + data);
    alert(‘Datos procesados correctamente’);
    } else alert(‘Ha ocurrido un error’);
    });
    });
    });


    ejecuta correctamente la acción del formulario () con o sin -evento.preventDefault();- pero no hace la pausa en el submit para corregir según la respectiva validación.
    ¿Que solución propones?
    Gracias de antemano.

    1. cbeltranv, en primer lugar gracias por el comentario.

      Dejame ver si entiendo. Tu necesidad es que antes de hacer el submit de los datos de tu formulario, ya sea en forma sincrónica o asincrónica, se ejecute antes una validación por medio de JavaScript para el formulario?

      Si es así, yo lo pensaría de esta manera. Si el navegador tiene soporte para JavaScript entonces tanto tu validación del lado del cliente como la llamada Ajax se ejecutarán. Mientras que si no lo tiene ni siquiera la validación JavaScript se ejecutaría y simplemente haría submit del formulario. Por eso es siempre importante recordar que las validaciones del lado del servidor deberían ser obligatorias y las programadas en el lado del cliente podrían llegar a ser opcionales para darle una rápida respuesta a las personas que tienen soporte para JavaScript.

      Partiendo de esta base. Un ejemplo sencillo para hacer esa validación JavaScript sería el siguiente.

      1. Creas tu listener en el evento onsubmit del form con jQuery(‘#FORM_ID’).live(‘submit’, function(){})
      2. En la función que pasas por parámetro programas la validación y si hay errores mostrás tus mensajes y no olvides el return false para que no ejecute el submit
      3. Si no hay errores ejecuta tu código Ajax

      Decime si es algo así lo que necesitas o es otra cosa. De todas maneras esto me parece un tema interesante para el próximo artículo de Ajax y jQuery.

      1. Juan. Gracias por la respuesta.

        En efecto las validaciones en cliente son deseables pero también las hago en el servidor.
        He logrado una solución con submitHandler así:

        label.error {
        background: no-repeat;
        }

        $(document).ready(function() {
        $(“#forma”).validate({
        rules: {
        prueba: {
        required: true
        }
        },
        messages: {
        prueba: {
        required: “Por favor ingrese la descripción del comprobante”
        }
        },
        submitHandler: function(form) {
        $(“#boton”).click(function() {
        $.post($(‘#forma’).attr(‘action’), $(‘#forma’).serialize(), function(data) {
        if(data) $(‘#nuevaimputacion’).html(data);
        else $(‘#nuevaimputacion’).html(“Error”);
        });
        });
        }
        });
        });

        Y ya permite corregir cuando se activan las reglas de validación. Sin embargo cuando no hay errores de validación debo dar dos clicks (uno adicional) para que vaya al servidor via ajax. Alguna sugerencia. Gracias.

        1. Por fin la solución es en el submitHandler: eliminar la invocación al submit $(“#boton”).click(function() { )} y por su puesto no se necesita el id=”boton”.
          Queda asi:
          submitHandler: function(form) {
          $.post($(‘#forma’).attr(‘action’), $(‘#forma’).serialize(), function(data) {
          if(data) $(‘#nuevaimputacion’).html(data);
          else $(‘#nuevaimputacion’).html(“Error”);
          });
          }
          En resumen con jQuery se cumple el ideal validar un formulario en cliente e invocar su respectiva validación y procesamiento en server. Usé jQuery JavaScript Library v1.4.4 y jQuery validation plug-in pre-1.5.2.

  2. hola amigo muchas gracias por compartir tus conocimientos, te queria hacer una consulta, lo que pasa que estoy usando jquery para validar los campos de mi formulario pero a la hora que doy enviar el formulario ignora las reglas del jquery y lo envia normal es este el codigo del boton enviar , no se como capturarlo con el jquery, ayudaaaaaa, graciasss

    1. kedin. Disculpa la demora de mi respuesta.

      La verdad es que no trabajo con validaciones del lado del cliente desde ya hace mucho tiempo por cuestiones de seguridad sino que siempre las hago en el lado del servidor. Por este motivo no conozco muy bien como funciona ese validator que usas.

  3. este es el codigo del botton , lo intente asi:

    $(document).ready(function() {
    $(“#Grabar”).click(function(event){
    $(“#FrmPersona”).validator({
    rules:{
    “ruc”: “required”,
    “apepat”: “required”,
    “apemat”: “required”,
    “nombres”:”required”

    },
    messages:{
    “ruc” : “introdusca Ruc”,
    “apepat” : “introdusca Apellido”,
    “apemat” : “introdusca Apellido Mterno”,
    “nombres” : “introdusca Nombres”
    },

Comenta este artículo