Ajax, principios básicos


Todo el mundo habla de Ajax, pero... ¿qué es esta nueva y revolucionaria teconología?

Realmente es una técnica para sustituir una parte de nuestra página web por datos obtenidos del servidor. Conviene no equivocarse: sustituir una parte de nuestra página web por otros datos es JavaScript; lo que incorpora Ajax es la posibilidad de que esos datos se obtengan del servidor.

Palabrotas básicas

Cuando hablamos de una página HTML entendemos un archivo con extensión HTML y un montón de "tags". Al hablar de Ajax no queda más remedio que referirnos al DOM, que consiste en la representación interna que tiene el Browser del archivo HTML que estamos mostrando.

La diferencia fundamental es que un archivo HTML es muy probable que no cambie en circunstancias normales. El DOM puede evolucionar dinámicamente. Además, cuando el resultado lo genera un servlet o servicio, es probable que el archivo HTML ni siquiera exista como tal, sino que se ha construido de forma dinámica.

Sustitución de objetos en el DOM

Sustituir unos datos en el DOM por otros es algo muy sencillo:

<html>
  <head>
    <script>
      function sustituye(param) {
        var mensaje = "Ha elegido: " + param.options[param.selectedIndex].value;
        document.getElementById("mensaje").innerHTML = mensaje;
      };

    </script>

</head>
<body>

Como véis, basta con obtener el elemento ("document.getElementById") y asignar un valor a su propiedad innerHTML. Y ya está :D

Esto es un poquitín de JavaScript, pero nada de Ajax.

Herramientas proporcionadas por AJAX

Ajax incorpora una clase a nuestro repertorio JavaScript. Esta clase es XMLHttpRequest, que tiene 2 métodos principales: * open(método, ruta, asíncrono), que abre una conexión * send(), que envía una petición

También tiene tres atributos muy interesantes, que son:

  • onreadystatechange, que permite establecer la acción asíncrona a realizar (luego lo vemos)
  • readyState, que nos permite comprobar en qué estado se encuentra nuestra petición.
  • responseText, donde se devolverá la respuesta del servidor

Y eso es casi todo Ajax. Es probable que no necesitéis nada más.

Creando un objeto XMLHttpRequest

Para crear un objeto XMLHttpRequest basta con hacer:

xmlhttp=new XMLHttpRequest();

Pero nuestros "amigos" de Microsoft, siempre innovadores, nos complican un poquito la creación de un objeto XMLHttpRequest, ya que en IE5 y 6 la cosa cambia mucho. Por eso recomiendo el uso de una función como ésta:

function getAjaxObject() {
      var xmlhttp;
      if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
         xmlhttp=new XMLHttpRequest();
      }
      else
      {// code for IE6, IE5
         xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
      return xmlhttp;
};

De esta manera tendremos un constructor adecuado a nuestro navegador.

Ejemplo básico

Ya sabemos todo lo que necesitamos. Vamos a construir un ejemplo.

Va a ser muy sencillo: un combobox que, al seleccionar una provincia, mostrará algunos pueblos. Por no liarlo, tendremos dos provincias y 4 pueblos cada una.

Vamos primero con el HTML con el que sustituiremos una zona de nuestro DOM:

Archivo ciudadreal.html:

Seleccione población:
<select id="poblacion">
  <option>Ciudad Real</option>
  <option>Miguelturra</option>
  <option>Malagón</option>
  <option>Tomelloso</option>
</select>

Archivo toledo.html:

Seleccione población:
<select id="poblacion">
  <option>Toledo</option>
  <option>Sonseca</option>
  <option>Torrijos</option>
  <option>Talavera</option>
</select>

Y ahora vamos con el principal (index.html, por ejemplo):

<html>
  <head>
    <title>Ejemplo Ajax</title>

    <script>
      function getAjaxObject() {
      var xmlhttp;
      if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
         xmlhttp=new XMLHttpRequest();
      }
      else
      {// code for IE6, IE5
         xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
      return xmlhttp;
      };

      function provinciaModificada(param) {
        var address =  param.options[param.selectedIndex].value;
        conn = getAjaxObject();
        conn.open("GET", address, false);
        conn.send();
        document.getElementById("lugar").innerHTML = conn.responseText;
      };

    </script>

</head>
<body>

Un poquito de por favor!!!

Vale, no os asustéis, que tampoco es tanto :D

Olvidemos el JavaScript por un momento. Los puntos calientes son la operación "onChange" del "select" y también el "div" de nombre "provincia". Todo lo demás es HTML estándar y no hay mucho que contar.

Con esas instrucciones sabemos que cuando cambie el "select" se debe llamar a la función "provinciaModificada". El identificador del "div" es para poder seleccionarlo después mediante "document.getElementById".

Vamos con el javascript. Lo primero es una función que nos permite obtener el objeto XMLHttpRequest independientemente del browser utilizado. Ya lo explicamos antes.

Después es donde está la chicha. Lo copio de nuevo:

function provinciaModificada(param) {
        var address =  param.options[param.selectedIndex].value;
        conn = getAjaxObject();
        conn.open("GET", address, false);
        conn.send();
        document.getElementById("lugar").innerHTML = conn.responseText;
      };

En la línea 2 obtenemos el valor seleccionado. Si miramos las opciones, veremos que los valores indican el HTML a cargar. Eso es un truco que he utilizado para facilitarme la vida.

En la línea 3, obtenemos el objeto Request.

En la línea 4, abrimos una conexión mediante GET (en este caso nos daba igual POST) que no es asíncrona.

En la línea 5 realizamos la comunicación propiamente dicha.

Finalmente, en la línea 6 sustituimos el HTML por el obtenido.

Comunicaciones asíncronas

En las comunicaciones asíncronas basta con utilizar el atributo onreadystatechange:

function provinciaModificada(param) {
        var address =  param.options[param.selectedIndex].value;
        conn = getAjaxObject();
        conn.onreadystatechange = function () {
          if (xmlhttp.readyState==4 && xmlhttp.status==200)
          {
             document.getElementById("lugar").innerHTML = conn.responseText;
          }
        };
        conn.open("GET", address, true);
        conn.send();
      };

No os olvidéis de cambiar el tercer parámetro del open, que ahora vale true.

En este caso, la función se ejecutará cuando el objeto ya se haya obtenido. En nuestro caso, que es una tontería, da igual asíncrono que síncrono, pero si hay que acceder a BBDD entre medias, la diferencia puede ser crucial.

Enlaces:

La propia W3C proporciona un montón de ejemplos de Ajax, así como un buen tutorial.

A disfrutar!!!


Comentarios

Comments powered by Disqus