Inicio > Ajax, Javascript, Listas desplegables, MySql, Php5, XMLHttpRequest > Listas desplegables llenadas dinámicamente (tag select) 3er. Caso con AJAX

Listas desplegables llenadas dinámicamente (tag select) 3er. Caso con AJAX

jueves, 29 de mayo de 2008 Dejar un comentario Ir a comentarios

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:

  1. Crear el objeto AJAX
  2. 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;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.

Ver demostración

Descargar archivos

Saludos desde Cajamarca-Perú.

  1. viernes, 27 de mayo de 2016 a las 21:06 | #1

    @DUDLEY TABARES
    No tiene que ver esté donde esté, el document.getElementById accede a cualquier parte, lo que si mejoro en el código es en la carga de las descripciones debe ir así:

    echo ««.utf8_encode($reg[‘despro’]).»«;

    Tienes mis datos de contacto para cualquier consulta.

    Saludos

  2. DUDLEY TABARES
    viernes, 27 de mayo de 2016 a las 18:54 | #2

    hola Funciona perfecto si el select esta en el Body, pero no funciona si lo pongo en otro contenedor dentro del body, para mi caso esta ubicado asi ; puedes ayudarme a ajustar el codigo ahora??

  3. matias
    domingo, 16 de noviembre de 2014 a las 02:01 | #3

    hola buenos dias , la verdad muy bien explicado y bien armado , el tema es q tengo una consulta si quiero poner mas de 2 campos a cambiar ? osea tengo una tabla en sql llamada aeropuerto , tengo varchar el id (clave) y tengo provincia , ciudad y nombre_aeropuerto .
    como hago para que en los selects pueda mostrar la info de cuando selecciono una ciudad me salte el nombre_aeropuerto ? saludos

  4. Edwing
    domingo, 15 de mayo de 2011 a las 14:07 | #4

    Holas, me llamo Edwing soy de Pativilca, me gusto mucho este ejemplo. Recien me estoy iniciando en el mundo de las aplicaciones web asi que no se mucho de ajax.

    Quisiera saber como podria hacer para tmabien agregarle el DISTRITO, eh creado un archivo Dis.php, cambie los parametros y variables. Agregue un Select mas al archivo anidado.htm, donde tambien use la funcion cargar envie el valor de la provincia al archivo distrito para hacer la consulta.

    Bueno a mi parecer todo esta bien, pero lo malo es que no me filtra los distritos, porfa si puedes darme una mano ahi.

    Tambien soy de Peru !!! 😀 ..

  5. martes, 1 de febrero de 2011 a las 15:27 | #5

    Super bueno! me encanto.. felicitaciones!!! me ayudado mucho sobretodo porque estoy empezando!!.. gracias!! sigue adelante

  6. martes, 1 de febrero de 2011 a las 15:26 | #6

    Excelente!! sobretodo para persona que iniciamos super explicativo..!! muchas gracias

  7. Juan Manuel
    domingo, 6 de junio de 2010 a las 15:09 | #7

    Saludos desde Valencia, Venezuela. Amigo Antonio Rios, te agradezco que hayas publicado ésta valiosa herramienta. Espero que sigas iluminando a muchas personas que nos pasamos en estos menesteres. Exitos…

  8. Juan
    martes, 16 de septiembre de 2008 a las 00:43 | #8

    Hola… lo probe y me funciono con un detalle, al cargar los datos de la base falta el primer registro… porque puede ser?

  9. domingo, 24 de agosto de 2008 a las 18:41 | #9

    Lo que indicas es Javascript, en el ejemplo lo asigno a dos argumentos de la etiqueta select, value que es donde almaceno el código del departamento y text donde se ve el texto a visualizar en la lista, puedes bajar el código y hacer las pruebas que necesitas utilizando funciones de Javascript.

  10. Andres
    jueves, 21 de agosto de 2008 a las 15:56 | #10

    Hola…
    tengo una inquietud, cuando yo cargo los datos de la tabla por ejemplo de la departamentos quiero saber cual es el codigo del departamento seleccionado??? y la de la provincia??? los requiero para poder enviar a guardar en una tabla nueva donde registro casos… Como lo hago…

    gracias.

  11. hookdump
    miércoles, 18 de junio de 2008 a las 02:27 | #11

    Excelente!! es justo lo que necesitaba 🙂
    Ahora mismo voy a probar implementarlo 😀

  1. Sin trackbacks aún.