Mostrando entradas con la etiqueta Ajax. Mostrar todas las entradas
Mostrando entradas con la etiqueta Ajax. Mostrar todas las entradas

miércoles, 8 de junio de 2011

Menú desplegable con AJAX

Vamos a mostrar un interesante menú desplegable hecho con la técnica AJAX, y como construirlo paso a paso. Debo advertir que quizás se requiere de conocimientos básicos de programación y en especial, algo de programación en ambiente Web.
Necesitaremos los siguientes elementos:
  1. Base de datos: Usaremos MySQL como SMBD y, para este ejemplo tendremos una tabla cargada con un listado de ciudades
  2. Un script PHP que capture los datos de la base de datos según el parámetro enviado.
  3. Una Página Receptora de los resultados, en la que colocaremos la zona para mostrarlos. Además esta misma enviará la solicitud de los datos que necesita mostrar.
Veamos como será el resultado esperado. Solo comience a escribir un nombre en el campo de texto indicado. Al escribir las 3 primeras letras aparecerá un listado de los nombre en los que se encuentren estas. Por favor, intente escribir "mar..."

Nombre

Id
Documento


Paso 1. Empezamos construyendo la página donde se desencadenan todos los eventos. En nuestro ejemplo usaremos lo siguiente:
<html>
  <head>
    <title>Menu desplegable con AJAX</title>
  </head>
  <body>
    <div style="float:left;width:80px;">Nombre</div>
      <div style="float:left; width:220px;">
        <input type="text" style="width:200px;" name="nom" id="nom" value="" />
      </div>
      <div style="float:left; width:130px;">
        Id <input type="text" style="width:90px;" name="id" id="id" value="" />
      </div>
      <div style="float:left; width:190px;">
         Documento <input type="text" style="width:90px;" name="cid" id="cid" value="" />
      </div>
  </body>
</html>

Paso 2. Desarrollamos los elementos básicos para que AJAX funcione. Primero la función para crear instancias del objeto XMLHTTPRequest. En el post AJAX para principiantes - 2 encontraremos mas detalles acerca de este tema.
function nuevoAjax(){
var ajax;
  if (window.XMLHttpRequest) { // codigo para IE7+, Firefox, Chrome, Opera, Safari
    ajax=new XMLHttpRequest();
  } else { // codigo para IE6, IE5
    ajax=new ActiveXObject("Microsoft.XMLHTTP");
  }
  return ajax;
}

Paso 3. Crearemos el archivo php que se conectará a la base de datos para sacar de ella lo que necesitamos. A este archivo lo llamaremos array_listado.php, luego lo veremos mencionado en el proceso de captura de datos con Ajax en el paso 4.
<?php
$hostname = "localhost";
$database = "my_database";
$username = "my_username";
$password = "my_password";
$conexion = mysql_pconnect($hostname, $username, $password) or trigger_error(mysql_error(), E_USER_ERROR);

mysql_select_db($database, $conexion);
$sql_query = "SELECT * FROM clientes";
$cliData = mysql_query($sql_query, $conexion) or die(mysql_error());
$cliCount = mysql_num_rows($cliData);
  if ($cliCount>0) {
      $cli = mysql_fetch_assoc($cliData);
      $k = 0;
      do {
          echo $cli['id']."~".$cli['cli_nombre']."~".$cli['cli_cid']."--\n";
      } while ($cli = mysql_fetch_assoc($cliData));
  }
?>

Paso 4. Ahora crearemos una función con la que cargaremos en nuestra página un listado de nombre, id y documentos (para nuestro ejemplo).
var listado = new Array();
function cargar_array_listado() {
  var ajaxL = nuevoAjax();
  ajaxL.open("GET", "array_listado.php", true);
  ajaxL.onreadystatechange=function() {
    if (ajaxL.readyState==4) {
       var tabla = ajaxL.responseText;
       var registros = tabla.split("--");
       for (var u in registro) {
          datos = registro[u].split("~");
          listado[u]= new Object();
          listado[u]['id']=datos[0];
          listado[u]['nom']=datos[1];
          listado[u]['cid']=datos[2];
       }
     }
  }
  ajaxL.send(null);
}
Podemos darnos cuenta de que:

  • A través de la función open del objeto Ajax, ejecutamos en el servidor el archivo array_listado.php
  • Usando el método responseText del objeto Ajax, capturamos la respuesta del servidor como texto plano. Este contenido será una serie de registros separados por el doble guion "--", donde cada dato estará separado por el símbolo "~". Obviamente podemos usar el método responseXML, para lo cual deberíamos haber configurado nuestra respuesta del archivo array_listado.php como datos en formato XML.
  • Considerando que tenemos una respuesta en formato de texto plano, hacemos uso de la función split de JavaScript para obtener cada dato y construir la matriz de datos que necesitamos.

Paso 5. Agregaremos algunas funciones que nos ayudarán a que nuestra escritura en el campo de texto de como resultado que se despliegue un listado con los nombres que coincidan en cualquier parte con nuestra escritura.
function teclear(evt,campo){
    if (campo.value.length == 0) {
      if ((evt.keyCode == 9)||(evt.keyCode == 13)) {
      clear();
      }
    } else if ((campo.value.length > 0)&&(campo.value.length < 3)) {
       document.getElementById('selector').innerHTML = "";
       if ((evt.keyCode == 9)||(evt.keyCode == 13)) { // tab o enter
          clear();
       }
    } else {
       if ((evt.keyCode > 47)&&(evt.keyCode < 91)){ // cualquier letra o numero
          autoCompletar(campo);
       }
       if ((evt.keyCode == 37)||(evt.keyCode == 38)) { // flecha hacia arriba o hacia atras
          if (document.getElementById('sel').selectedIndex > 0) {
             document.getElementById('sel').selectedIndex = (document.getElementById('sel').selectedIndex)-1;
             campo.value =     document.getElementById('sel').options[document.getElementById('sel').selectedIndex].text
          }
       }
       if ((evt.keyCode == 39)||(evt.keyCode == 40)) { // flecha hacia abajo o hacia delante
            if (document.getElementById('sel').selectedIndex < (document.getElementById('sel').length-1)) {
                document.getElementById('sel').selectedIndex = (document.getElementById('sel').selectedIndex)+1;
                campo.value = document.getElementById('sel').options[document.getElementById('sel').selectedIndex].text
            }
        }
        if ((evt.keyCode == 9)||(evt.keyCode == 13)) { // tab o enter
            if (document.getElementById('sel').selectedIndex != -1) {
                var idsel = document.getElementById('sel').options[document.getElementById('sel').selectedIndex].value;
                document.getElementById('id').value = idsel;
                look(idsel);
                document.getElementById('selector').innerHTML = "";
                document.getElementById('cid').focus();
            } else {
                 document.getElementById('selector').innerHTML = "";
                 clear();
            }
        }
    }
    return false;
}

function autoCompletar(field) {
// crear selector
    var lista = "";
    var cuent = 0;
    var ubica = 0;
    var selecto = "";
    for (var k=0; k < listado.length; k++) {
        ubica = listado[k].name.toUpperCase().indexOf(field.value.toUpperCase());
        if ((ubica == 0)||(listado[k].name.toUpperCase().charCodeAt(ubica-1)==32)) {
           selecto += "<option value='" + listado[k].code + "' >" + listado[k].name + "</option>\n";
           cuent++;
        }
     }
     lista = "<select style=\"width:200px;\" name=\"sel\" id=\"sel\" onfocus = \"document.getElementById('nom').focus()\" onclick = \"document.getElementById('nom').value = this.options[this.selectedIndex].text\">\n" + selecto + "</select>\n";

// mostrar selector
    if (cuent == 0) {
        document.getElementById('selector').innerHTML = "";
        document.getElementById('re_id').value = 0;
    } else {
        document.getElementById('selector').innerHTML = lista;
        document.getElementById('sel').setAttribute('size',cuent+1);
        document.getElementById('sel').selectedIndex = -1;
    }
}

function clear() {
  document.getElementById('id').value = 0;
  document.getElementById('cid').value = '';
  document.getElementById('nom').value = '';
  document.getElementById('nom').focus();
}

function look(id) {
    for (var k=0; k<listado.length; k++) {
        if (listado[k].code == id){
            document.getElementById('cid').value = listado[k].cid;
            document.getElementById('nom').value = listado[k].name;
        }
    }
}

Paso 6. Finalmente, agregamos un par de detalles al campo de texto nombre, para que se desencadenen las funciones programadas para los eventos onFocus y onKeyUp

<input id="nom" name="nom" onfocus="cargar_array_listado();" onkeyup="teclear(event,this);" style="width: 200px;" type="text" value="" />

onFocus: Al recibir el enfoque, la matriz de datos se recargará con la lista actualizada de clientes, por lo que en un entorno multiusuario se podrán tener siempre los datos actualizados.
onKeyUp: Al soltar la pulsación de una tecla, se desencadenará la función que despliega el listado de nombres coincidentes. Igualmente en esta misma función se encuentran inmersos los procesos de selección de la lista y carga de datos del nombre seleccionado.

Por favor, no olviden comentar sus ideas para mejorar este artilugio.

jueves, 19 de mayo de 2011

AJAX para principiantes - 2

Como explique anteriormente, la técnica AJAX (Asynchronous JavaScript and XML) consiste en enviar solicitudes al servidor a través de un canal silencioso y una vez obtenida la respuesta, colocarla a vista del usuario sin necesidad de recargar la página.

Para que la tecnología AJAX funcione necesita varios elementos, todos indispensables:
1. La página web, por supuesto. En ella más adelante aprenderemos a colocar espacios bien definidos para depositar la respuesta del servidor.
2. Un canal de comunicación silencioso, llamado "objeto XMLHTTPRequest"
3. Un contenido previamente registrado en el servidor, que será la respuesta a nuestra solicitud.

Normalmente cuando queremos "cargar" una página en el navegador, escribimos la URL en la barra de direcciones y listo!

Pues bien, básicamente el objeto AJAX hace lo mismo pero sin que nadie lo vea (esta es una de las formas que tiene para solicitar la información al servidor). Cuando obtiene el resultado, se ejecuta el siguiente paso que consiste en colocar ese resultado a la vista del usuario, en una zona de la página preparada para esto.

Cómo creamos el objeto AJAX?
Lo primero es "declararlo" y ponerle nombre. Todos los navegadores modernos (IE7, Firefox, Safari y Opera) tienen ya incluido el objeto, por lo que se puede declarar así:
variable=new XMLHttpRequest();
Ahora bien, para versiones antiguas de Internet Explorer como IE5 y IE6, se necesita declarar distinto:
variable=new ActiveXObject("Microsoft.XMLHTTP");
En definitiva, para lograr que funcione bien se declara verificando la forma en que funcione bien para cualquier navegador:
var ajax;
if (window.XMLHttpRequest)
  {// codigo para IE7+, Firefox, Chrome, Opera, Safari
  ajax=new XMLHttpRequest();
  }
else
  {// codigo para IE6, IE5
  ajax=new ActiveXObject("Microsoft.XMLHTTP");
  }


Y... donde coloco eso?
Un sitio adecuado para empezar sería la cabecera de la página, para hacer pruebas o cuando no tiene más que una página en su proyecto, es decir entre las etiquetas <head> y </head>, sin embargo yo recomendaría preparar un archivo .js separado, y hacer una llamada a ese archivo en la cabecera de la página.


Creamos un archivo javascript:
function nuevoAjax()
{
 var ajax = false;
 if (window.XMLHttpRequest)
  {// codigo para IE7+, Firefox, Chrome, Opera, Safari
  ajax=new XMLHttpRequest();
  }
 else
  {// codigo para IE6, IE5
  ajax=new ActiveXObject("Microsoft.XMLHTTP");
  }

 return ajax;
}


Lo guardamos con el nombre que mas nos guste, en mi caso lo llamaré (por pura originalidad) ajax.js
Luego, cargamos el archivo ajax.js en la cabecera de la página donde deseamos usar la técnica AJAX.
Para este ejemplo crearé una página html nueva y la nombraré principal.html.
<html>
<head>
<title>Mi pagina con AJAX</title>
<script type="text/javascript" src="ajax.js"></script>
</head>
<body>
</body>

Listo! ya estará disponible la función que crea "instancias" del objeto AJAX para que lo usemos cada vez que lo necesitemos.

Que datos voy a capturar del servidor?
Si bien la técnica AJAX hace referencia al uso del XML como lenguaje de transporte de datos, no se limita a este lenguaje. AJAX devolverá el contenido tal como lo consiga en el servidor, salvo pequeñas limitaciones relacionadas con el idioma y la codificación del contenido.

Lo lógico es que se trate de datos que varíen constantemente, o cuyo origen se quiera mantener en secreto, o resultados de fórmulas complejas con muchas variables en juego, o cosas por el estilo.

Por ahora solo necesitaremos algún contenido para hacer nuestras pruebas. En mi caso escribiré un archivo con la palabra Neeos y lo guardaré como dato.html en el servidor.


Luego haremos una llamada con AJAX para que el servidor nos devuelva el contenido del archivo dato.html. En la zona <head> de nuestra página principal.html, después de la linea donde llamamos al archivo ajax.js escribimos:
<script language="JavaScript" type="text/JavaScript">
function cargarDatos()
{
  var respuesta;
  var objeto_ajax=nuevoAjax();
  objeto_ajax.open("GET", "dato.html", true);
  objeto_ajax.onreadystatechange=function() {
    if (objeto_ajax.readyState==4) 
   {
    respuesta = objeto_ajax.responseText;
    }
  }
  objeto_ajax.send(null);
}
</script>


Expliquemos esto: la función tiene como objetivo capturar el contenido del archivo dato.html en silencio, sin que el usuario lo note.
- Creamos una variable vacía para la respuesta:
var respuesta;
- Creamos una instancia del objeto XMLHTTPRequest del que hablamos al principio, usando la función nuevoAjax() que preparamos en el archivo ajax.js
var objeto_ajax=nuevoAjax();
- Abrimos el archivo dato.html usando el método GET, es decir, enviando la información al servidor por URL. 
objeto_ajax.open("GET", "dato.html", true);
Debo mencionar un par de cosas con respecto a esta línea. Con el método GET podemos enviar al servidor datos para que este sepa que respuesta darnos. por ejemplo:
objeto_ajax.open("GET", "dato.php?id=325&date=22/10/2000", true);
En este caso le diríamos al servidor que necesitamos un contenido relacionado con el ítem número 325 para la fecha 22/10/2000. Hemos llamado al archivo que procesa esta solicitud dato.php porque en nuestro ejemplo imaginario se hace uso del PHP para consultar la base de datos y obtener una respuesta.


Otra cosa a tomar en cuenta es la palabra "true", que significa que la consulta se hará de manera Asíncrona. Eso quiere decir que si existen otras cosas que necesiten realizarse en la página, estas se harán sin esperar la respuesta del servidor. Eso le da tiempo al servidor a "pensar bien su respuesta antes de hablar" ;-)
- Le indicamos al objeto AJAX que debe esperar una respuesta, en este caso el estado 4 significa "respuesta recibida":

objeto_ajax.onreadystatechange=function() {
    if (objeto_ajax.readyState==4) 
   {
    respuesta = objeto_ajax.responseText;
    }
  }

Ponemos esa respuesta en la variable "respuesta".
- Desencadenamos toda la funcion con la orden objeto_ajax.send(null); Aquí es donde realmente empieza a trabajar el objeto AJAX.
Si decidimos usar el método POST en lugar de GET, los datos adicionales que se le envían al servidor se colocarían en lugar de null.

y ahora que hago con la respuesta?
Para demostrar como funciona la técnica AJAX, vamos a usar dos ejemplos:
Ejemplo 1: campo de texto
En la zona <body> de la página principal.html colocamos un campo de texto vacío y un botón para ejecutar la función cargarDatos()
<body>
<input type="button" name="cargar" onclic="cargarDatos();" value=" Cargar Datos " />
<br />
<input type="text" name="resultado" id="resultado" value="" />
</body>
Luego hacemos una pequeña modificación a la función cargarDatos() para que ponga los resultados en el campo de texto resultado:

function cargarDatos()
{
  var respuesta;
  var objeto_ajax=nuevoAjax();
  objeto_ajax.open("GET", "dato.html", true);
  objeto_ajax.onreadystatechange=function() {
    if (objeto_ajax.readyState==4) 
   {
     respuesta = objeto_ajax.responseText;
     document.getElementById('resultado').value = respuesta;
   }
  }
  objeto_ajax.send(null);
}


Ejemplo 2: Zona DIV contenedora
La otra forma de hacerlo es similar, pero en lugar de un campo de texto, usaremos una zona contenedora para la respuesta:

<body>
<input type="button" name="cargar" onclic="cargarDatos();" value=" Cargar Datos " />
<div id="resultado"></div>
</body>



Y nuevamente hacemos una pequeña modificación a la función cargarDatos() para que ponga los resultados en la zona DIV resultado:
function cargarDatos()
{
  var respuesta;
  var objeto_ajax=nuevoAjax();
  objeto_ajax.open("GET", "dato.html", true);
  objeto_ajax.onreadystatechange=function() {
    if (objeto_ajax.readyState==4) 
   {
     respuesta = objeto_ajax.responseText;
     document.getElementById('resultado').innerHTML = respuesta;
   }
  }
  objeto_ajax.send(null);
}


Has tus propias pruebas y coméntanos que tal te fue, si dieron los resultados esperados. Aun nos queda mucho que aprender de esta simpática tecnología.

miércoles, 18 de mayo de 2011

AJAX para principiantes


Ajax es, a mi modo de ver, una técnica de desarrollo Web que ha revolucionado la forma en que hacemos las páginas web.

Básicamente, consiste en enviar "solicitudes" al servidor y mostrar la "respuesta" sin que sea necesario que se recargue completamente la página para mostrar esa respuesta.

A la manera tradicional:
1 - El usuario hace clic en un enlace y envía una solicitud al servidor
3 - El servidor prepara un "paquete" de respuesta con la página completa: cabecera, logotipos, barras de navegación, hoja de estilo, pie de página, etc. y lo envía a la PC del usuario, al tiempo que atiende a unos cuantos usuario más que están haciendo otras solicitudes.
4 - Cuando la respuesta al fin llega a la PC de usuario, el navegador se encarga de construir la página completa, poniendo cada cosa en su lugar.
Con Ajax:
1 - El usuario hace clic en un enlace y envía una solicitud al servidor
2 - Esta solicitud es enviada al servidor a través de un "canal" exclusivo de Ajax que trabaja en silencio.
3 - El servidor prepara un "paquete" con SOLO los datos necesario para dar respuesta al usuario, el resto de los componentes de la página siguen ahí a la vista del usuario.
4 - El canal Ajax permanece alerta a la respuesta del servidor.
5 - La respuesta obtenida es preparada y colocada en el sitio adecuado de la página sin que esta tenga que reconstruir ningún otro elemento.

Con Ajax el servidor prepara paquetes de respuesta mucho más pequeños, por lo que las páginas cargan más rápido. La presentación y "maquillaje" de esa respuesta está a cargo del navegador de usuario, por lo que se acelera aun la navegación.

En mi próxima publicación Ajax para principiantes 2, les comentaré como crear el canal de comunicación Ajax entre la página y el servidor.