Select dependientes con Ajax y PHP

17 03 2009

Aqui va un ejemplo de un select q carga los datos en otro select dependiendo que elija por ejemplo si selecciono Bolivia, en otro select cargara los departamentos solo de ese país, esto sin recargar la página y esto se hace con AJAX como se muestra en el código de cada archivo necesario para esto. los archivos son:

select_dependientes.php

<?
function generaPaises()
{
	include 'conexion.php';
	conectar();
	$consulta=mysql_query("SELECT id, opcion FROM lista_paises");
	desconectar();

	// Voy imprimiendo el primer select compuesto por los paises
	echo "<select name='paises' id='paises' onChange='cargaContenido(this.id)'>";
	echo "<option value='0'>Elige</option>";
	while($registro=mysql_fetch_row($consulta))
	{
		echo "<option value='".$registro[0]."'>".$registro[1]."</option>";
	}
	echo "</select>";
}
?>
<html lang="es">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>AJAX, Combos Dependientes</title>
<link rel="stylesheet" type="text/css" href="select_dependientes.css">
<script type="text/javascript" src="select_dependientes.js"></script>
</head>
<body>
<div id="demo" style="width:600px;">
<div id="demoDer">
  <select disabled="disabled" name="estados" id="estados">
    <option value="0">Selecciona opci&oacute;n...</option>
  </select>
</div>
<div id="demoIzq"><?php generaPaises(); ?></div>
</div>
</body>
</html>

EL CODIGO AJAX

select_dependientes.js
function nuevoAjax()
{
/* Crea el objeto AJAX. Esta funcion es generica para cualquier utilidad de este tipo, por
lo que se puede copiar tal como esta aqui */
var xmlhttp=false;
try
{
// Creacion del objeto AJAX para navegadores no IE
xmlhttp=new ActiveXObject(“Msxml2.XMLHTTP”);
}
catch(e)
{
try
{
// Creacion del objet AJAX para IE
xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
}
catch(E)
{
if (!xmlhttp && typeof XMLHttpRequest!=’undefined’) xmlhttp=new XMLHttpRequest();
}
}
return xmlhttp;
}

// Declaro los selects que componen el documento HTML. Su atributo ID debe figurar aqui.
var listadoSelects=new Array();
listadoSelects[0]=”paises”;
listadoSelects[1]=”estados”;

function buscarEnArray(array, dato)
{
// Retorna el indice de la posicion donde se encuentra el elemento en el array o null si no se encuentra
var x=0;
while(array[x])
{
if(array[x]==dato) return x;
x++;
}
return null;
}

function cargaContenido(idSelectOrigen)
{
// Obtengo la posicion que ocupa el select que debe ser cargado en el array declarado mas arriba
var posicionSelectDestino=buscarEnArray(listadoSelects, idSelectOrigen)+1;
// Obtengo el select que el usuario modifico
var selectOrigen=document.getElementById(idSelectOrigen);
// Obtengo la opcion que el usuario selecciono
var opcionSeleccionada=selectOrigen.options[selectOrigen.selectedIndex].value;
// Si el usuario eligio la opcion “Elige”, no voy al servidor y pongo los selects siguientes en estado “Selecciona opcion…”
if(opcionSeleccionada==0)
{
var x=posicionSelectDestino, selectActual=null;
// Busco todos los selects siguientes al que inicio el evento onChange y les cambio el estado y deshabilito
while(listadoSelects[x])
{
selectActual=document.getElementById(listadoSelects[x]);
selectActual.length=0;

var nuevaOpcion=document.createElement(“option”); nuevaOpcion.value=0; nuevaOpcion.innerHTML=”Selecciona Opción…”;
selectActual.appendChild(nuevaOpcion); selectActual.disabled=true;
x++;
}
}
// Compruebo que el select modificado no sea el ultimo de la cadena
else if(idSelectOrigen!=listadoSelects[listadoSelects.length-1])
{
// Obtengo el elemento del select que debo cargar
var idSelectDestino=listadoSelects[posicionSelectDestino];
var selectDestino=document.getElementById(idSelectDestino);
// Creo el nuevo objeto AJAX y envio al servidor el ID del select a cargar y la opcion seleccionada del select origen
var ajax=nuevoAjax();
ajax.open(“GET”, “select_dependientes_proceso.php?select=”+idSelectDestino+”&opcion=”+opcionSeleccionada, true);
ajax.onreadystatechange=function()
{
if (ajax.readyState==1)
{
// Mientras carga elimino la opcion “Selecciona Opcion…” y pongo una que dice “Cargando…”
selectDestino.length=0;
var nuevaOpcion=document.createElement(“option”); nuevaOpcion.value=0; nuevaOpcion.innerHTML=”Cargando…”;
selectDestino.appendChild(nuevaOpcion); selectDestino.disabled=true;
}
if (ajax.readyState==4)
{
selectDestino.parentNode.innerHTML=ajax.responseText;
}
}
ajax.send(null);
}
}

PARA LA CONEXION A BD
conexion.php

<?

function conectar()
{
mysql_connect(“localhost”, “root”, “”);
mysql_select_db(“ajax”);
}
function desconectar()
{
mysql_close();
}
?>

PARA PROCESAR LOS DATOS
select_dependientes_proceso.php

<?php
// Array que vincula los IDs de los selects declarados en el HTML con el nombre de la tabla donde se encuentra su contenido
$listadoSelects=array(
“paises”=>”lista_paises”,
“estados”=>”lista_estados”
);

function validaSelect($selectDestino)
{
// Se valida que el select enviado via GET exista
global $listadoSelects;
if(isset($listadoSelects[$selectDestino])) return true;
else return false;
}

function validaOpcion($opcionSeleccionada)
{
// Se valida que la opcion seleccionada por el usuario en el select tenga un valor numerico
if(is_numeric($opcionSeleccionada)) return true;
else return false;
}

$selectDestino=$_GET["select"]; $opcionSeleccionada=$_GET["opcion"];

if(validaSelect($selectDestino) && validaOpcion($opcionSeleccionada))
{
$tabla=$listadoSelects[$selectDestino];
include ‘conexion.php’;
conectar();
$consulta=mysql_query(“SELECT id, opcion FROM $tabla WHERE relacion=’$opcionSeleccionada’”) or die(mysql_error());
desconectar();

// Comienzo a imprimir el select
echo “<select name=’”.$selectDestino.”‘ id=’”.$selectDestino.”‘ onChange=’cargaContenido(this.id)’>”;
echo “<option value=’0′>Elige</option>”;
while($registro=mysql_fetch_row($consulta))
{
// Convierto los caracteres conflictivos a sus entidades HTML correspondientes para su correcta visualizacion
$registro[1]=htmlentities($registro[1]);
// Imprimo las opciones del select
echo “<option value=’”.$registro[0].”‘>”.$registro[1].”</option>”;
}
echo “</select>”;
}
?>

para darle un poco de estilo
select_dependientes.css
#demoIzq, #demoDer {
border:1px dashed;
width:296px;
background-color:#EAEAEA;
text-align:center;
}
#demoDer {
float:right;
}
select {
width:220px;
}

para q funcione correctamente necesitaras descargar este script de sql
descargar
Descargar Script


Acciones

Información

8 respuestas

2 11 2009
juan

hola amigo, sabes esta buenisimo tu ejemplo funciona bien, me funciona muy bien en windows en todos los navegadores pero sabes en linux tengo un problemilla ya que funciona en firefox y en ie7 pero no funciona en ie6 y por cosas del trabajo es necesario que funcione en ie6 tambien, hay que acerle algun cambio a este codigo para eso, por favor si me pudieras ayudar seria genial muchas gracias

3 11 2009
aabramovichq

Hola funciona normal en todos los navegadores revisa alguna part de tu código, y con respecto al de Linux acuerdate que linux diferencia entre mayusculas y minusculas, me refiero por ejmplo a tu consultas en la BD y código php. Saludos.

3 11 2009
Erik

Saludos.
Esta muy bueno el codigo y funciona a la perfeccion, pero lo implemente en un codigo que tengo en el cual la primera opcion de un registro es si es “registro individual” o “registro grupal”, lo tengo mediante “divs” (capas), las cuales dependiendo de la seleccion del registro (individual o grupal) se ocultan las capas del registro individual o las capas del registro grupal, entonces el problema es que tengo que repetir 2 veces el combo dependiente de paises y estados, en el primer caso (individual) me lo muestra y funciona sin problemas, pero en el caso de “registro grupal” me muestra el combo de paises (con sus opciones, Argentina, Cuba, Mexico, etc etc) pero a la hora de seleccionar algo no cambia nada en el combo de estados y lo peor es que no marca errores de javascript ni de php…. Ayuda por favor, como le puedo hacer para meter este codigo que publicas en el mismo archivo php y que funcionen los 4 combos.

3 11 2009
aabramovichq

Hola.. no se entiende muy bien…explicate mejor…asi t ayudo, lo poco q te entendi..parece estar sencillo el problema de resolver, pero explicate mejor, sino el mismo puede desarrollarlo con Jquery ahi tenes un monton de documentación que con eso te ahorraras monton de código, por cierto mañana lo subire el mismo ejemplo con jquery hasta pronto.
saludos.

13 11 2009
Daniel Fatico

Hola

Utilize el codigo y funciona a la perfeccion ya adaptado a mis bases de datos, lo que me saca de onda es que:

Funciona al %100 en Internet Explorer 8
Funciona al %70 en Internet Explorer 7 ( No muestra en el segundo combo algunas selecciones , no todas solo como 5)
No funciona en Mozilla 3.5.5

Muchas Gracias, espero me puedan orientan

saludos

DF

13 11 2009
aabramovichq

Hola, ya tenia que subir una solución hecho con jquery, por razones de tiempo, no lo pude hacer, pero este fin de lo hago y los subire en cuanto este listo. saludos.

23 11 2009
OPENLOGIC

Hola esta bueno tu aporte man pero sabes algunas partes estan copiadas mal del tuto ke leiste pero a mi parecer lo mas rapido,escalable y multiplataforma (a parte se puede aplicar MVC que es mas limpio) esta hacerlo con XML les dejo la url http://www.librosweb.es ahi existe manuales libres de descarga baja el de ajax esta hecho a base de teoria y ejemplos ademas de otros ke ya les estare comentando y postenado como simfony (aunque prefiero cakephp) jeje es otro Tema bueno saludos tecuidas toti.

23 11 2009
aabramovichq

muy buena la web q pusiste, pero seria bueno tb q pongas tu nombre no?aah me parece interesante q trabajes con los frameworks, cada uno tiene sus gustos y formas de trabajo. Saludos.

Deja un comentario