Selects combinados con Ajax y PHP
Usando la librería xajax veremos como construir fácilmente un sistema de select combinados con PHP y Ajax.
07/6/07 - Un ejemplo típico de las prestaciones de Ajax es la creación de selects combinados, es decir, una estructura de dos selects, donde uno tiene las posibles opciones en función de lo que se haya elegido en el otro. Veremos como hacer este sistema en PHP y Ajax, con la ayuda de la librería xajax, que nos facilitará bastante las cosas.
Este artículo viene a continuar una serie de artículos sobre el uso de xajax, que comenzamos en el artículo Xajax: Ajax para PHP.
Veamos el ejemplo que vamos a desarrollar en este artículo.
|
Nota: en este artículo presentamos una manera de hacer los selects
combinados con Ajax y PHP utilizando Xajax versión 0.2.5. Hemos publicado
unas notas para actualizar este código a la versión 0.5, por lo que os
recomendamos leer el artículo Actualizar a Xajax 0.5.
|
Para empezar veremos el formulario inicial con el primer select y el segundo sin opciones.
<form name="formulario">
Provincia:
<br>
<select name="provincia" onchange="xajax_generar_select(document.formulario.provincia.options[document.formulario.provincia.selectedIndex].value)">
<option value="999">Selecciona provincia</option>
<option value=0>Madrid</option>
<option value=1>Valencia</option>
<option value=2>Barcelona</option>
<option value=3>León</option>
</select>
<br>
<br>
Población: <div id="seleccombinado">
<select name="poblaciones">
<option value=0>Elegir provincia</option>
</select>
</div>
</form>
Vemos que se tiene dos campos select, el primero para las provincias y el segundo para las poblaciones. El primer campo tiene todas las opciones posibles. El segundo select inicialmente no tiene ninguna opción, porque estas se deben incluir en función de la provincia escogida en el primer campo. Vemos que el segundo select está metido en una capa con id="selectcombinado", que actualizaremos luego con Ajax.
Además, hay que fijarse en el atributo onchange del primer select, que llama con Ajax, por medio de xajax, a la función PHP que se encargará de generar las opciones del segundo select.
Ahora vamos a ver una función PHP que generaría el código de un select en función de un parámetro que recibirá: la provincia. Con ese identificador de provincia generará el código del select con todas las poblaciones de esa provincia.
function select_combinado($id_provincia){
//función para crear el select combinado
//debe extraer las opciones de un select a partir de un parámetro
//generamos unos arrays con distintas poblaciones de varias provincias
//estos valores en un caso práctico seguramente se extraerán de base de datos
//no habría que cargar todos en memoria, sólo hacer el select de las poblaciones de la provincia deseada
$madrid = array("Madrid", "Las Rozas", "Móstoles", "San Sebastián de los Reyes");
$valencia = array("Valencia", "La Eliana", "Paterna", "Cullera");
$barcelona = array("Barcelona", "Badalona");
$leon = array ("León", "Astorga", "Villamejil");
$poblaciones = array($madrid, $valencia, $barcelona, $leon);
//creo las distintas opciones del select
$nuevo_select = "<select name='poblaciones'>";
for ($i=0; $i<count($poblaciones[$id_provincia]); $i++){
$nuevo_select .= '<option value="' . $i . '">' . $poblaciones[$id_provincia][$i] . '</option>';
}
$nuevo_select .= "</select>";
return $nuevo_select;
}
La función anterior tiene poco de interés para lo que es el manejo de Ajax. Aquí hemos creado unos arrays para almacenar las poblaciones de las distintas provincias, pero en nuestras aplicaciones posiblemente tengamos las poblaciones en una base de datos. En ese caso lo que tendríamos que hacer es simplemente es una consulta y recorrer un conjunto de registros.
En definitiva, la función recibe un identificador de provincia, que se utiliza para recorrer el array asociado a la provincia y generar un campo select con una opción por cada población.
Ahora vamos a ver la función que hace uso de xajax para procesar y actualizar la página con Ajax para cambiar las opciones del segundo select.
function generar_select($cod_provincia){
//instanciamos el objeto para generar la respuesta con ajax
$respuesta = new xajaxResponse('ISO-8859-1');
if ($cod_provincia==999){
//escribimos el select de poblaciones vacío
$nuevo_select = '<select name="poblaciones">
<option value=0>Elegir provincia</option>
</select>
';
}else{
$nuevo_select = select_combinado($cod_provincia);
}
//escribimos en la capa con id="seleccombinado"
$respuesta->addAssign("seleccombinado","innerHTML",$nuevo_select);
//tenemos que devolver la instancia del objeto xajaxResponse
return $respuesta;
}
Lo primero es instanciar un objeto de la clase xajaxResponse para generar la respuesta. Como se puede ver, recibimos el código de la provincia como parámetro. Comprobamos si ese código de la provincia es 999, porque es un caso especial (no se ha seleccionado ninguna provincia) y tenemos que generar el select de provincias vacío. En caso que el código de la provincia sea otra cosa entonces se lo pasamos a la función select_combinado(), vista anteriormente, para generar el select con las poblaciones de la provincia dada.
Para acabar, escribimos en la capa con id="selectcombinado" la cadena con el select que hemos generado. Para escribirlo utilizamos el método addAssign() del objeto de la clase xajaxResponse que ya conocíamos de anteriores ejercicios.
El código completo es el siguiente:
<?
//incluímos la clase ajax
require ('xajax/xajax.inc.php');
//instanciamos el objeto de la clase xajax
$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->decodeUTF8InputOn();
function select_combinado($id_provincia){
//función para crear el select combinado
//debe extraer las opciones de un select a partir de un parámetro
//generamos unos arrays con distintas poblaciones de varias provincias
//estos valores en un caso práctico seguramente se extraerán de base de datos
//no habría que cargar todos en memoria, sólo hacer el select de las poblaciones de la provincia deseada
$madrid = array("Madrid", "Las Rozas", "Móstoles", "San Sebastián de los Reyes");
$valencia = array("Valencia", "La Eliana", "Paterna", "Cullera");
$barcelona = array("Barcelona", "Badalona");
$leon = array ("León", "Astorga", "Villamejil");
$poblaciones = array($madrid, $valencia, $barcelona, $leon);
//creo las distintas opciones del select
$nuevo_select = "<select name='poblaciones'>";
for ($i=0; $i<count($poblaciones[$id_provincia]); $i++){
//for ($i=0; $i<2; $i++){
$nuevo_select .= '<option value="' . $i . '">' . $poblaciones[$id_provincia][$i] . '</option>';
}
$nuevo_select .= "</select>";
return $nuevo_select;
}
function generar_select($cod_provincia){
//instanciamos el objeto para generar la respuesta con ajax
$respuesta = new xajaxResponse('ISO-8859-1');
if ($cod_provincia==999){
//escribimos el select de poblaciones vacío
$nuevo_select = '<select name="poblaciones">
<option value=0>Elegir provincia</option>
</select>
';
}else{
$nuevo_select = select_combinado($cod_provincia);
}
//escribimos en la capa con id="seleccombinado"
$respuesta->addAssign("seleccombinado","innerHTML",$nuevo_select);
//tenemos que devolver la instanciación del objeto xajaxResponse
return $respuesta;
}
//asociamos la función creada anteriormente al objeto xajax
$xajax->registerFunction("generar_select");
//El objeto xajax tiene que procesar cualquier petición
$xajax->processRequests();
?>
<html>
<head>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=ISO-8859-1">
<title>Validar usuario en Ajax</title>
<?
//En el <head> indicamos al objeto xajax se encargue de generar el javascript necesario
$xajax->printJavascript("xajax/");
?>
</head>
<body>
<form name="formulario">
Provincia:
<br>
<select name="provincia" onchange="xajax_generar_select(document.formulario.provincia.options[document.formulario.provincia.selectedIndex].value)">
<option value="999">Selecciona provincia</option>
<option value=0>Madrid</option>
<option value=1>Valencia</option>
<option value=2>Barcelona</option>
<option value=3>León</option>
</select>
<br>
<br>
Población: <div id="seleccombinado">
<select name="poblaciones">
<option value=0>Elegir provincia</option>
</select>
</div>
</form>
</body>
</html>
Finalmente, podemos
ver ejemplo en marcha aquí.
Seguir navegando a partir aquí:
+ 1 manual relacionado
+ 1 categoria relacionada
+ 11 comentarios (Añadir)
| Autoría, licencia y acciones sobre este artículo |
|
|
Manuales relacionados con este artículo
Categorias relacionadas
A través de las categorías de nuestro directorio se pueden encontrar otro tipo de recursos relacionados con este artículo:
+ Entrar en
Ajax
Comentarios de los visitantes
|
Los comentarios de los visitantes son para ampliar la información del artículo. Cualquiera puede participar.
|
| Se muestran 11 comentarios revisados |
Comentario de Xombra
19/6/07
Excelente artículo, además fácil de entender
Comentario de Freddy Mejia
19/6/07
Esta buenisimo este tutorial, pero me gustaría hacer lo mismo con datos obtenidos través de una base de datos, como sería el codigo?
UN vez lo intente y me mostraba a veces los datso y otrsa veces me salio un error, no si era que la lista dependiente resultaba un poco extensa o que pero a ve ces salia y otras no.
Comentario de oskar
20/7/07
porque no publicar el código y vemos si hay errores?
Comentario de Mauricio Gonzalez
21/8/07
Alguien tiene un ejemplo como este pero con 3 combos dependientes?
Comentario de Marcoss
07/10/07
Hola, he probado el código que aparece en este ejemplo y no me funciona, cuando selecciono una ciudad en el 1 select no ocurre nada en el 2, no hace nada ¿por qué puede ser?
Comentario de Gil
12/10/07
Que tal. Bueno quiero aportar un poco y responder a la pregunta de Marcoss ya que me ocurria lo mismo, lo resolvi de la siguiente manera dentro de:
function generar_select($cod_provincia)
sustitui
$respuesta = new xajaxResponse('ISO-8859-1');
por la siguiente linea
$respuesta = new xajaxResponse();
y comenzo a mostrar los datos en el segundo combo
si ahi otra forma me gustaria saberlo.
Tambien les basado en este mismo código pero manejando base de datos y (OJO) con las modificaciones para el xaJax 0.5 ya que cambiaron un poco el codigo.
<?php
require('xajax/xajax_core/xajax.inc.php');
$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->configure('decodeUTF8Input',true);
function motor()
{
include 'conexion.php';
conectar();
$consulta = mysql_query ("SELECT ID_MOTOR,MOTOR FROM MOTOR");
desconectar();
?>
<select name='motor' id='motor' onChange="xajax_generar_select(document.formulario.motor.options[document.formulario.motor.selectedIndex].value)">";
<option value='0'>Elige</option>
<?
while($registro=mysql_fetch_row($consulta))
{ echo "<option value='".$registro[0]."'>".$registro[1]."</option>"; }
?> </select>
<?
}
function select_combinado($id_motor){
include 'conexion.php';
conectar();
$consulta_mod=mysql_query("SELECT ID_MOD_MOTOR,MODELO_MOTOR FROM MODELO_MOTOR WHERE ID_MOTOR='$id_motor'");
desconectar();
$nuevo_select = "<select name='modelos'>";
$nuevo_select .= '<option value="'. 0 .'">'.Elige.'</option>';
while($registro_mod=mysql_fetch_row($consulta_mod)){
$nuevo_select .= '<option value="' . $registro_mod[0] . '">' . $registro_mod[1] . '</option>';
}
$nuevo_select .= "</select>";
return $nuevo_select;
}
function generar_select($cod_motor){
$respuesta = new xajaxResponse();
if ($cod_motor==0){
$nuevo_select = '<select name="modelos">
<option value=0>Elige Modelo</option>
</select>
';
}else{
$nuevo_select = select_combinado($cod_motor);
}
$respuesta->assign("seleccombinado","innerHTML",$nuevo_select);
return $respuesta;
}
$xajax->registerFunction("generar_select");
$xajax->processRequest();
?>
<html>
<head>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=ISO-8859-1">
<title>Select Dimamicos con XAJAX</title>
<?
//En el <head> indicamos al objeto xajax se encargue de generar el javascript necesario
$xajax->printJavascript("xajax/");
?>
</head>
<body>
<form name="formulario">
Motor:
<br>
<? motor(); ?>
<br>
<br>
Modelos: <div id="seleccombinado">
<select name="modelos">
<option value=0>Elegir motor</option>
</select>
</div>
</form>
</body>
</html>
Comentario de cachi
12/11/07
hola, estoy intentando usar este codigo para mi pagina pero no hay forma de que ande. ninguno de los 2 codigos, ni el simple ni el que busca los datos en la base. tenes idea si puede estar relacionado con alguna limitacion de mi servidor? el mismo tiene corriendo apache.
saludos y gracias.
Comentario de Alonso
12/12/07
hola muy bueno el articulo, aunque valdria la pena una actualizada, ya que como dijo Gil, el codigo de esta libreria ha cambiado, con el codigo de Gil si me funciona, pero tengo una duda, solo me funciona de manera local !!, cuando lo pongo en el servidor solo lee el primer select de la BD, el segundo no se carga :S
Comentario de Dani
28/12/07
Pues sí, seria recomendable un ejemplo con bases de datos que funcionase porque no consigo hacer funcionar el segundo select (ni con el ejemplo que ha puesto Gil ni con uno hecho por mi)
Comentario de Ricardo
10/1/08
Muy buen tuttorial para los que nos iniciamos en ajax descargue la version del ejemplo y al querer modificarla para que la informacion la saque de una base de datos al elegir en primer combo si merefresca el siguiente pero extrañamente solo pone la primera opcion siendo que existen mas y solo funciona con el id inpar donde puedo postear el codigo para saber si estoy haciendo algo mal
Comentario de sobrao
22/2/08
saludos, ejecute este mismo con una modificaciones, y funciono pero en explorer pero en mozilla no me registra el dato seleccionado, cualquier ayuda para solucionarlo o porque sucede esto.
<?php
require('xajax/xajax_core/xajax.inc.php');
$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->configure('decodeUTF8Input',true);
function motor()
{
include 'conexion.php';
conectar();
$consulta = mysql_query ("SELECT ID_MOTOR,MOTOR FROM MOTOR");
desconectar();
?>
<select name='motor' id='motor' onChange="xajax_generar_select(document.formulario.motor.options[document.formulario.motor.selectedIndex].value)">";
<option value='0'>Elige</option>
<?
while($registro=mysql_fetch_row($consulta))
{ echo "<option value='".$registro[0]."'>".$registro[1]."</option>"; }
?> </select>
<?
}
function select_combinado($id_motor){
include 'conexion.php';
conectar();
$consulta_mod=mysql_query("SELECT ID_MOD_MOTOR,MODELO_MOTOR FROM MODELO_MOTOR WHERE ID_MOTOR='$id_motor'");
desconectar();
$nuevo_select = "<select name='modelos'>";
$nuevo_select .= '<option value="'. 0 .'">'.Elige.'</option>';
while($registro_mod=mysql_fetch_row($consulta_mod)){
$nuevo_select .= '<option value="' . $registro_mod[0] . '">' . $registro_mod[1] . '</option>';
}
$nuevo_select .= "</select>";
return $nuevo_select;
}
function generar_select($cod_motor){
$respuesta = new xajaxResponse();
if ($cod_motor==0){
$nuevo_select = '<select name="modelos">
<option value=0>Elige Modelo</option>
</select>
';
}else{
$nuevo_select = select_combinado($cod_motor);
}
$respuesta->assign("seleccombinado","innerHTML",$nuevo_select);
return $respuesta;
}
$xajax->registerFunction("generar_select");
$xajax->processRequest();
?>
<html>
<head>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=ISO-8859-1">
<title>Select Dimamicos con XAJAX</title>
<?
//En el <head> indicamos al objeto xajax se encargue de generar el javascript necesario
$xajax->printJavascript("xajax/");
?>
</head>
<body>
<form name="formulario">
Motor:
<br>
<? motor(); ?>
<br>
<br>
Modelos: <div id="seleccombinado">
<select name="modelos">
<option value=0>Elegir motor</option>
</select>
</div>
</form>
</body>
</html>
Ir arriba