Listas desplegables llenadas dinámicamente (tag select) 3er. Caso con AJAX
Hoy veremos el tercer y último caso, para llenar dinámicamente una etiqueta select (html), como es con AJAX debes conocerlo o tener al menos la idea de como trabaja, más adelante en futuras entradas haré ejemplos básicos de esta tecnología para entenderlo mejor, para los que ya saben les caerá a pelo y espero les guste.
Utilizaremos la misma base datos y tablas del primer caso, primeramente crearemos un script o página llamada anidado.html y ¿porqué ya no php?, sencillamente porque AJAX nos permite eso, como lo expliqué anteriormente, esto es lo que me agrada, el presentar páginas html con contenido dinámico gracias a la magia del AJAX.
El script es:
anidado.html
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Anidado 3</title> </head> <body> <b>Departamentos : Provincias</b><br /> <select name="sDep" id="sDep" size="8"></select> <select name='sPro' id="sPro" size="8"></select> </body>
Como vemos hemos creado las listas desplegables para los departamentos y las provincias en blanco y con tamaño 8 para poder observar mejor el trabajo de AJAX, quitarían el size para ver el select como queremos normalmente.
Siguiente paso es crear el objeto AJAX, utilizaré esta forma estándar para el ejemplo, normalmente uso una librería en JS que está con clases; este código sirve y se entenderá mejor para los que empiezan en AJAX.
¿Cómo funciona AJAX?, Los pasos son:
- Crear el objeto AJAX
- Procesar el objeto AJAX, para ello es necesario:
- Indicar la página que hará el proceso en el servidor (debe ser un lenguaje del lado del servidor PHP. ASP, JSP, etc)
- Indicar la función que procesará el resultado, en ella necesitaremos el objeto contenedor de la página html donde almacenaremos el resultado.
- La forma que será la consulta asíncrona o síncrona, en nuestro ejemplo no lo escribo, ya que por defecto es asíncrona.
Paso 1. Creamos el objeto AJAX
<title>Anidado 3</title> <script language="JavaScript" type="text/javascript"> // creando objeto XMLHttpRequest de Ajax var obXHR; try { obXHR=new XMLHttpRequest(); } catch(err) { try { obXHR=new ActiveXObject("Msxml2.XMLHTTP"); } catch(err) { try { obXHR=new ActiveXObject("Microsoft.XMLHTTP"); } catch(err) { obXHR=false; } } } </script>
La variable obXHR almacena el objeto AJAX, con ella realizaremos todo, con este código toma todos los navegadores de la forma estándar (Mozilla, IE7, Safari, Opera, etc) y la anterior (anteriores a IE7), por lo que nuestro ejemplo funcionará normalmente en un navegador no muy antiguo.
2. En este punto crearemos una función (cargar) en JS donde realizaremos todo el proceso AJAX, dentro de ella trabajaremos con el resultado.
function cargar(url,obId) { var obCon = document.getElementById(obId); obXHR.open("GET", url); obXHR.onreadystatechange = function() { if (obXHR.readyState == 4 &amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp; obXHR.status == 200) { obXML = obXHR.responseXML; obCod = obXML.getElementsByTagName("codigo"); obDes = obXML.getElementsByTagName("descri"); obCon.length=obCod.length; for (var i=0; i<obcod .length;i++) { obCon.options[i].value=obCod[i].firstChild.nodeValue; obCon.options[i].text=obDes[i].firstChild.nodeValue; } } } obXHR.send(null); } </script>
Que dice esta función, primero recogemos el objeto contenedor (variable obCon), la variable obId es el parámetro que almacena el nombre del objeto contenedor enviado.
var obCon = document.getElementById(obId);
Luego abrimos la petición, para ello utilizamos el otro parámetro de la función, este es el script que trabajará del lado del servidor, en nuestro seguiremos usando PHP, más adelante veremos estos scripts.
obXHR.open(«GET», url);
Luego viene la función de resultado, esta forma no es la única para trabajarlo, en ejemplos posteriores veremos otras maneras, que dice la función, pues que si la respuesta es readystate=4 (página del servidor está procesada completamente) y el status=4 (Ok o petición es correcta)
if (obXHR.readyState == 4 && obXHR.status == 200) {
Entonces recogemos el objeto XML (var obXML) procesada y preparado en la página PHP, utilizo XML porque en sus siglas la «X» en AJAX es de XML (en eso se basa AJAX mezcla de tecnologías)
obXML = obXHR.responseXML;
Luego creamos el arreglo JS obCod donde almacenamos todos los códigos procesados de la tabla departamento, y el arreglo JS obDes, para la descripción de los departamentos.
obCod = obXML.getElementsByTagName(«codigo»);
obDes = obXML.getElementsByTagName(«descri»);
Luego viene el llenado de la primera lista, primero la inicializamos con el número de elementos que contendrá.
obCon.length=obCod.length;
Luego recorremos con un bucle for y llenamos una a una la lista, esta es la forma de JS procesa el llenado ya lo vimos en el caso anterior también, existe otra forma con DOM, es un poco más larga.
for (var i=0; i<obCod.length;i++) {
obCon.options[i].value=obCod[i].firstChild.nodeValue;
obCon.options[i].text=obDes[i].firstChild.nodeValue;
}
Y finalmente enviamos la petición AJAX
obXHR.send(null);
Hasta acá se preguntará y ¿cuándo carga la primera lista?, para ello necesitamos que lo haga apenas carga la página, utilizaremos el evento onload de la etiqueta body.
<body onload="cargar('dpto.php','sDep')"> <b>Departamentos : Provincias</b><br />
Como vemos acá utilizamos la función cargar y mandamos como parámetros el script php y el nombre del objeto contenedor para los departamentos en este caso el id de la primera lista.
Este es el script php:
dpto.php
< ?php $cn = mysql_connect("localhost","usuario","clave"); mysql_select_db("bd_anidados"); $sql="SELECT * FROM departamento"; $rs=mysql_query($sql); header('Content-Type: text/xml'); echo "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>\n"; echo "<departamentos>\n"; while ($reg=mysql_fetch_array($rs)){ echo "<departamento>"; echo "<codigo>".$reg['coddep']."</codigo>"; echo "<descri>".$reg['desdep']."</descri>"; echo "</departamento>\n"; } echo "</departamentos>"; ?>
<p style=»text-align:justify;»>Utilizo esta forma de detallar el resultado XML, PHP tiene extensiones para mejorar, acá sencillamente no la uso para no complicar más este caso, la explicaré igualmente en futuras entradas; la forma en la que está se puede estudiar mejor, si ejecutan este script PHP debe arrojar datos en formato XML.</p>
<p style=»text-align:justify;»>Ahora si ejecutamos el script anidado.html debería de cargar la página con los departamentos en la primera lista.</p>
<p style=»text-align:justify;»>Grandioso ¿no creen?.</p>
<p style=»text-align:justify;»>Como último paso, cada vez que seleccionemos un departamento tendremos que llenar la segunda lista sólo con las provincias que le corresponde, en la etiqueta de la primera lista agregamos:</p>
<select name='sDep' id='sDep' size='8' onchange="cargar('prov.php?dep='+this.value,'sPro');"> </select>
El evento onchange nos permite enviará nuevamente a la función cargar y como parámetros enviamos un nuevo script php para las provincias (prov.php), este script necesita enviar como parámetro el código del departamento (this.value).
El código es:
prov.php
< ?php $dep=$_GET['dep']; $cn = mysql_connect("localhost","usuario","clave"); mysql_select_db("bd_anidados"); $sql="SELECT codpro,despro FROM provincia WHERE coddep=$dep"; $rs=mysql_query($sql); header('Content-Type: text/xml'); echo "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>\n"; echo "<provincias>\n"; while ($reg=mysql_fetch_array($rs)){ echo "<provincia>"; echo "<codigo>".$reg['codpro']."</codigo>"; echo "<descri>".$reg['despro']."</descri>"; echo "</provincia>\n"; } echo "</provincias>"; ?>
Esto es todo, ¿largo no?, les recomendaría como todo buen programador imprimir este caso y estudiarlo, no he explicado muy al detalle porque sería más largo ya, a mi modesto entender al AJAX es la solución a obtener un mejor rendimiento de nuestras aplicaciones y paginas web, bueno hasta pronto con más novedades en programación.
Saludos desde Cajamarca-Perú.