Combos dependientes II

0 - , , - 01/08/2006 12:24:22

Continuando con el tema de combos dependientes veamos ahora un ejemplo con Ajax y PHP. El anterior ejemplo nos puede ser útil siempre y cuando no tengamos mucha información, pero supongamos ahora que tenemos dos tablas relacionadas; una de actividades con 17 registros; y otra de subactividades -relacionada con la anterior por un mismo id de actividad- de más de 100 subactividades. En este caso deberemos recurrir a leer desde una base de datos. Si queremos, además, que no se recargue la página para agilizar el uso de nuestro formulario, deberemos usar AJAX.

Tenemos dos tablas:

  • "t_actividades" con los campos "Id" y "Actividad"
  • "t_subactividades" con los campos "IdActividad", "IdSubactividad", "SubActividad". (Los campos en negrita relacionan ambas tablas)

Ahora necesitamos crear un php que sería en el que tendríamos todo nuestro formulario, incluyendo los desplegables de Actividad y Subactividad. Lo vamos a denominar "combos2.php" y en un primer momento tendríamos:

<p><label for="actividad">Actividad:</label>
<select name="Actividades" id="Actividades">
<?
$servidor = 'servidor.dominio.com';
$usuario = 'usuario';
$contrasena = 'password';
$datos = 'basededatos';
mysql_connect($servidor,$usuario,$contrasena);
@mysql_select_db($datos) or die( "Unable to select database");
$query = "SELECT * FROM t_actividades";
$result=mysql_query($query);
$num=mysql_numrows($result);
mysql_close();
$i=0;
while ($i < $num) {
$Id = mysql_result($result,$i,"Id");
$Actividad = mysql_result($result,$i,"Actividad");
?>
<option value=<? echo $Id; ?>>
<? echo $Actividad ?>
</option>
<?
$i++;
}
?>
</select>
</p>
<p>
<div id="Div_Subactividades">
<label for="SubActividad">SubActividad:</label>
<select name="SubActividades" id="SubActividades" class="select">
</select>
</div>
</p>

Lo que se ha hecho es crear el primer combo a partir de los datos extraidos en la tabla de actividades "t_actividades" y dejar el combo correspondiente a las subactividades vacío, pero dentro de un div llamado Div_Subactividades que será donde se cargue el contenido obtenido tras hacer una petición mediante AJAX.

<div id="Div_Subactividades">
<label for="SubActividad">SubActividad:</label>
<select name="SubActividades" id="SubActividades" class="select">
</select>
</div>

Lo siguiente sería crear una instancia del objeto XMLHttpRequest() y una función que nos permita cargar el contenido del segundo combo en función del primero.

<script type="text/javascript">
var peticion = false;
var testPasado = false;
try {
peticion = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
peticion = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
peticion = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
peticion = false;
}
}
}
if (!peticion)
alert("ERROR AL INICIALIZAR!");
function cargarCombo (url, comboAnterior, element_id) {
//Obtenemos el contenido del div
//donde se cargaran los resultados
var element = document.getElementById(element_id);
//Obtenemos el valor seleccionado del combo anterior
var valordepende = document.getElementById(comboAnterior)
var x = valordepende.value
//construimos la url definitiva
//pasando como parametro el valor seleccionado
var fragment_url = url+'?Id='+x;
element.innerHTML = '<img src="Imagenes/loading.gif" />';
//abrimos la url
peticion.open("GET", fragment_url);
peticion.onreadystatechange = function() {
if (peticion.readyState == 4) {
//escribimos la respuesta
element.innerHTML = peticion.responseText;
}
}
peticion.send(null);
}
</script>

La función "cargarCombo" quizá sea la más interesante. Se le pasan tres parámetros: la url a la que llamamos, el combo del que depende el que vamos a cargar, y el id del div donde se cargará el resultado. El código javascript lo podemos insertar en el mismo "combos2.php" o hacer un include. El valor del segundo combo variará siempre que cambie el contenido del primer combo con lo que deberemos llamar a la función "cargarCombo" al evento onchange del select 'Actividades'. Por lo que finalmente quedaría:

<select name="Actividades"  onchange="javascript:cargarCombo('Subactividades.php', 'Actividades', 'Div_Subactividades')" id="Actividades">

Por último nos queda crear un fichero "Subactividades.php", que en función de la actividad seleccionada, cargará en el desplegable las subactividades correspondientes.

<?
$IdActividad = $_REQUEST['Id'];
?>
<label for="SubActividad">SubActividad:</label>
<select name="SubActividades" id="SubActividades" class="select">
<?
$servidor = 'servidor.dominio.com';
$usuario = 'usuario';
$contrasena = 'password';
$datos = 'basededatos';
mysql_connect($servidor,$usuario,$contrasena);
@mysql_select_db($datos) or die( "Unable to select database");
$query = "SELECT * FROM t_subactividades WHERE IdActividad=$IdActividad";
$result=mysql_query($query);
$num=mysql_numrows($result);
mysql_close();
$i=0;
while ($i < $num) {
$IdSubactividad = mysql_result($result,$i,"IdSubactividad");
$SubActividad = mysql_result($result,$i,"SubActividad");
?>
<option value=<? echo $IdSubactividad; ?>>
<? echo htmlentities($SubActividad) ?>
</option>
<?
$i++;
}
?>
</select>

Combos dependientes I

0 - , , - 01/08/2006 08:13:44

Este es el primero de dos posts dedicados a como gestionar la carga de combos dependientes sin necesidad de recargar la página. En este primero mediante un script en el que mediante una array bidemensional vamos almacenando los distintos valores y al evento onchange del primer combo, recargamos el segundo.

Ver ejemplo en funcionamiento » »

Javascript:
<script language="javascript">
function Combos(x) {
ItDepend=document.getElementById('CombDependiente');
if(!ItDepend){return;}
var mitems=new Array();
mitems['Elige']=[''];
mitems['Informatica']=['Elegir opción','Portatiles','Impresoras','Consumibles','Accesorios'];
mitems['Sonido']=['Elegir opción','Filet Mignon','Porterhouse','Flank','T-Bone'];
mitems['Imagen']=['Elegir opción','DVD','Cámaras','Home Cinema',];
mitems['Fotografia']=['Select Item','Cámaras','Memorias','Accesorios'];
ItDepend.options.length=0;
ItActual=mitems[x.options[x.selectedIndex].value];
if(!ItActual){return;}
ItDepend.options.length=ItActual.length;
for(var i=0;i<ItActual.length;i++) {
ItDepend.options[i].text=ItActual[i];
ItDepend.options[i].value=ItActual[i];
}
}
</script>
HTML:
<form action="">
<label for="or">Área:</label>
<select name="or" id="or" onchange="Combos(this)">
<option value="Elige">Elige</option>
<option value="Informatica">Informática</option>
<option value="Sonido">Sonido</option>
<option value="Imagen">Imagen</option>
<option value="Fotografia">Fotografía</option>
</select>
<label for="CombDependiente">Productos:</label>
<select name="CombDependiente" id="CombDependiente"></select>
<input type="submit" value="Ir" />
</form>
1