Inicio > Ajax, Javascript, Listas desplegables, MySql, Php5, XMLHttpRequest > Ejemplo de 3 Listas Desplegables con PHP y AJAX usando GET

Ejemplo de 3 Listas Desplegables con PHP y AJAX usando GET

martes, 18 de agosto de 2009 Dejar un comentario Ir a comentarios

listasHace un tiempo, recibí un correo de un lector desde México, donde me contaba que estaba haciendo un proyecto y que había leído los casos mostrados de las listas desplegables, necesitaba utilizar 3 listas y todo con AJAX, luego de coordinar el envío de archivos procedí a ayudarlo, los datos estaban en un archivo plano (conocido también como archivo texto o de notepad), luego de migrar a una base de datos, no la normalicé como debía ser, hice todo en una sola tabla, en este caso MySQL, preparé los scripts que paso a hacerlo público y espero sea de utilidad para todos.

La idea es ver los códigos postales de cada sitio, para lo cual hay que llegar hasta ellos, seleccionando primero el Estado a donde pertenece, luego la Delegación Municipal y finalmente la Colonia.

La estructura de la tabla es:

CREATE TABLE 'codigos' (
'id' int(10) NOT NULL auto_increment,
'estado' varchar(30) default NULL,
'cp' varchar(6) default NULL,
'colonia' varchar(50) default NULL,
'delemuni' varchar(30) default NULL,
PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=78322 ;

Como ven en el auto_increment, cuenta la tabla códigos con bastantes registros, y esto nos servirá para ver lo práctico del uso de AJAX, empecemos.

Para poder mostrar los datos en HTML, creamos una tabla

listasejemplo.html

<table border="1" width="40%" bgcolor="#FFFFCC">
<tbody>
<tr>
<td width="20px">Estado:</td>
<td><select id="sEst"></select></td>
</tr>
<tr>
<td>Delemuni:</td>
<td><select id="sDM"></select></td>
</tr>
<tr>
<td>Colonia:</td>
<td><select id="sCol"></select></td>
</tr>
<tr>
<td>Cod.Postal:</td>
<td><select id="sCP" size="10"></select></td>
</tr>
</tbody></table>

Cada select está identificado con si respectivo id para poder acceder a él mediante DOM, las listas están vacías todas las llenaremos con AJAX; seguidamente crearemos el objecto XMLHTTPRequest, como sabemos esto es mediante javascript, y nos permitirá ejecutar el código en cualquier navegador y versión, el código sería:

// 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;
}
}
}

Ahora si tenemos éxito creando el objeto obXHR, necesitamos que cuando hagamos click en cada lista desplegable y escojamos un elemento llene la lista siguiente con datos filtrados de las tablas, para esto creamos una función javascript cargar, esta recibirá dos parámetros, el script php que se ejecutará mediante AJAX y que nos dará los datos y que objeto HTML contendrá los datos siguientes, el script sería:

function cargar(url,obId) {
var obCon = document.getElementById(obId);
obXHR.open("GET", url);
obXHR.onreadystatechange = function() {
if (obXHR.readyState == 4 &amp;amp;&amp;amp; obXHR.status == 200) {
obXML = obXHR.responseXML;
obDes = obXML.getElementsByTagName("descri");
obCon.length=obDes.length;
for (var i=0; i<obdes .length;i++) {
obCon.options[i].value=obDes[i].firstChild.nodeValue;
obCon.options[i].text=obDes[i].firstChild.nodeValue;
}
}
}
obXHR.send(null);
}

Para nuestro caso el script PHP va a ser el mismo cuando hagamos clic en cada lista, en el script llamaremos a una clase que debería estar en otro archivo y llamarla con un include, pero por motivos pedagógicos y de estudio está en el mismo archivo, esta clase contiene 3 propiedades y 3 métodos, las propiedades nos permitirán manejar todo lo relacionado a los datos y los métodos a la conección,  a seleccionar la base de datos, cerrarla, y también las consultas a la tabla.

cargar.php

class cargar {
var $cn;		var $rs;		var $sql;</strong>

<strong>function __construct($sql) {
$this->sql=$sql;
$this->cn = mysql_connect("localhost","usuario","clave");
mysql_select_db("basededatos");
$this->cargar();
}</strong>

<strong>function cargar() {
$this->rs=mysql_query($this->sql);
header('Content-Type: text/xml');
echo "\n";
echo "\n";
echo "Seleccione";
while (list($descri) = mysql_fetch_row($this->rs)){
echo "$descri\n";
}
echo "\n";
}</strong>

<strong>function __destruct() {
mysql_close($this->cn);
}
}
// fin de la clase cargar
extract($_GET);</strong>

<strong>if (isset($est)) {
$sql = "SELECT DISTINCT delemuni FROM codigos WHERE estado='$est' ORDER BY delemuni";
}elseif (isset($dm)) {
$sql = "SELECT DISTINCT colonia FROM codigos WHERE delemuni='$dm' ORDER BY colonia";
}elseif (isset($col)) {
$sql = "SELECT DISTINCT cp FROM codigos WHERE colonia='$col' ORDER BY cp";
}else {
$sql = "SELECT DISTINCT estado FROM codigos";
}</strong>

<strong>$clCar = new cargar($sql);

Luego de la clase tenemos la sentencia extract, lo que hace es convertir a variables todo lo que mandemos como método GET, según la lista iremos usando diferentes consultas SQL a la tabla.

Finalmente agregamos eventos onchange a las listas quedaría así cada una:

<select id="sEst" onchange="cargar('cargar.php?est='+this.value,'sDM')"></select>
<select id="sDM" onchange="cargar('cargar.php?dm='+this.value,'sCol')"></select>
<select id="sCol" onchange="cargar('cargar.php?col='+this.value,'sCP')"></select>

y por último necesitamos que la primera lista se cargue junto con la página, por lo que usaremos el evento onload de la etiqueta body

<body onload="cargar('cargar.php','sEst')">

Estúdienlo, no he entrado en detalles teóricos, pues está simple y espero se entienda y les sirva….

El demo está aquí.

Ya vimos anteriormente todas las formas de cargar listas desplegables, incluyendo con AJAX.

Puedes ver el ejemplo enviando datos mediante el método POST aquí

Para descargar los archivos del ejemplo pulsa aquí.

hasta pronto

Saludos

  1. jueves, 3 de febrero de 2011 a las 15:06 | #1

    Nice site ….)

  2. sábado, 29 de enero de 2011 a las 20:38 | #2

    Hey, I am checking this blog using the phone and this appears to be kind of odd. Thought you’d wish to know. This is a great write-up nevertheless, did not mess that up.

    – David

  3. Eric L González
    domingo, 11 de julio de 2010 a las 11:11 | #3

    Hola he utilizado este codigo y hace las consultas ok….pero a la hora de utilizar estos datos para hacer envio no puedo, ya que utilizado el metodo «action» para cargar los datos ahora como hago para enviarlos?

  4. jueves, 8 de julio de 2010 a las 07:53 | #4

    I want to quote your post in my blog. It can?
    And you et an account on Twitter?

  5. sábado, 19 de junio de 2010 a las 02:47 | #5

    Glad to share your articles, let me learn more knowledge

  6. Juan Manuel
    miércoles, 9 de junio de 2010 a las 23:35 | #6

    Tengo un error y es que quiero que al pulsar un select llamado estado, seleccione una empresa, y al pulsar la empresa me liste en un select sus productos, y en otro select el nombre del vendedor de esa zona. Podría alguno ayudarme, por favor. Gracias..!!

  7. NESS
    lunes, 31 de agosto de 2009 a las 23:48 | #7

    Amigo he analizado ke una depuración del codigo sería… seleccionar específicamente el código para esa ciudad de ese estado…

    Lo que hace tu codigo (un error por asi decirlo)… es que TOMA CUALQUIER COLONIA QUE SE LLAME «X» y saca TODOS LOS CODIGOS POSTALES POSIBLES…

    Ejemplo: La colonia Framboyanes existe en más de un Estado de la Republica.

    Tu código saca todos los códigos postales de la Col. Framboyanes en todos los estados… Y ESO NO NOS INTERESA…

    Nos interesa nadamas LA COLONIA DEL ESTADO INDICADO DE LA CIUDAD INDICADA.

    Esto pasa porque al enviar la consulta PIERDES LOS PARAMETROS DEL ESTADO Y LA CIUDAD AL QUE PERTENECE LA COLONIA QUE ESTAS INDICANDO EN LAS LISTAS.

    Habría que pasar en la última consulta… el parámetro del Estado y la Ciudad al AJAX, para poder hacer la consulta en PHP más específica:

    Por ejemplo la consulta la tienes así en la línea 36:

    $sql = «SELECT DISTINCT cp FROM codigos WHERE colonia=’$col’ ORDER BY cp «;

    Esto nos extrae TODOS LOS CODIGOS DE TODAS LAS COLONIAS CON ESE NOMBRE. COSA INCORRECTA!

    Lo Correcto sería que nuestra consulta final fuera algo así:

    $sql = «SELECT DISTINCT cp FROM codigos WHERE colonia=’$col’ AND ciudad=’$ciudad’ AND estado=’$estado’ ORDER BY cp «;

    O sea, pasándole el parámetro de ESTADO y CIUDAD, para hacerla más específica.

    Pero aún no se como hacerlo, lo estoy analizando…

  8. NESS
    lunes, 31 de agosto de 2009 a las 23:32 | #8

    Muchas gracias amigo por los archivos… aunque creo que la base de datos de los codigos postales no esta muy bien capturada…

    Yo estoy depurando la tabla… en cuanto la finalize la comparto…

    Gracias !

  9. NESS
    domingo, 30 de agosto de 2009 a las 12:12 | #9

    Oie amigo.. gracias por el aporta esta super bueno el ejemplo…

    Me gustaria saber si podrias facilitarme los archivos de ejemplo con los codigos postales…

    Gracias !…

  1. Sin trackbacks aún.