Selects dependientes con PHP y base de datos

Sistema para que las opciones de un select se vinculen a lo que se ha seleccionado en otro select, manteniendo todas las opciones en una base de datos.
Este es un sistema de "selects dependientes" (es decir, que interactúan el uno con el otro), tomando a la vez los datos desde una base de datos Access.

Referencia: Tenemos otro ejemplo de selects dependientes en el que se trabaja únicamente del lado del cliente con Javascript, para el que le interese más una opción como esa.

En este ejemplo, se trabajará con dos selects:

- Uno de países
- Otro de provincias o comunas

Para empezar, tenemos que tener 2 tablas:

-Países, con un campo id_pais y un campo país con el nombre del mismo (si lo quieren hacer bilingüe le agregan un campo pais_i con el nombre del país en inglés).
-Provincias, con un campo id_prov, otro id_pais donde colocan el id del país al que corresponde esa provincia y un campo prov con el nombre de la misma (idem al anterior si lo quieren hacer en inglés).

Básicamente hay que usar 2 páginas. La pagina1.php en la cual está el formulario, ahí vamos a poner el nombre de quien llena el formulario (sólo a efectos de mostrar como queda el formulario cuando tiene más campos a completar), también vamos a elegir el país. Si es la primera vez que abrimos el formulario el campo del nombre va a quedar vacío y en el combobox del país sólo va a decir: seleccione el país, y el combobox de las provincias ni va a aparecer.

Apenas comienza el script le damos a la variable $paisant el mismo valor que $pais. Ya que la segunda variable no está todavía declarada, el valor de la primera será también nulo.

En el combobox del país, le damos una orden en javascript, que básicamente dice que al cambiar la opción del combobox, se envíe el formulario a la pagina2.php (para que funcione esta orden de javascript, hay que dejar como figura la orden de submit del form).

En la pagina2.php lo primero que vamos a corroborar es que $paisant y $pais sean iguales.
$paisant era nulo, pero $pais tuvo un nuevo valor, el valor del id_ del país que tomó al haber elegido el nuevo país en el combobox.

Al ser distintas las dos variables, volvemos a la pagina1.php enviando todos los valores ya elegidos en el form. Ahí se vuelve a declarar la variable $paisant que esta vez toma el valor del país previamente elegido, ya que $pais no es nulo, sino que vale id_pais.

Esta vez, debido a que $pais tiene un valor diferente a cero, mostramos el combobox de las provincias.


*** PAGINA1.PHP ***


<html>
<html>
<head>
<title>pagina1.php</title>
</head>

<body>
<form method="post" action="pagina2.php">

    <table width="70%" border="0" align="center">
    <?php
// Me conecto a la base de datos
mysql_connect("localhost","root","");
mysql_select_db("nombre_de_la_base");

// Declaro la variable $paisant que es la que me va a indicar si hay que volver a cargar los datos de las provincias
$paisant=$pais;

print ("
    <tr>
       <td><div align=\"right\"><strong>Nombre y Apellido:</strong></div></td>
       <td> <input type=\"text\" name=\"nombre\" value=\"$nombre\"></td>
    </tr>

    <input type=\"hidden\" name=\"paisant\" value=\"$paisant\">

    <tr>
       <td><div align=\"right\"><strong>Pais:</strong></div></td>
       <td><select name=\"pais\" onchange=\"submit();\">
       ");
//Muestra el combobox de las provincias una vez que se haya elegido el país, no antes
if (!isset($pais)){
    print ("<option selected>Seleccione el pais</option>");
    $pais="0";
}

$sql="select * from paises order by 2";
$res=mysql_query($sql);

while($fila=mysql_fetch_array($res)){
print("<option value=\"$fila[id_pais]\"");
if ($fila[id_pais] == $pais) {
print ("selected");
}
print(">$fila[pais]</option>\n");
}
print("</select></td></tr>");

if ($pais!="0"){
print("
<tr>
    <td><div align=\"right\"><strong>Provincia:</strong></div></td>
<td><select name=\"prov\">
");

$sqlprov="select * from provincias where id_pais='$pais' order by 2";
$resprov=mysql_query($sqlprov);

while($filaprov=mysql_fetch_array($resprov)){
print("<option value=\"$filaprov[id_prov]\">$filaprov[prov]</option>");
}
print("
    </select>
    </td>
       </tr>
");
}
       ?>
<tr>
       <td><div align="right"><input name="button" type="submit" value="Enviar"></div></td>
       <td><input name="reset" type="reset" value="Borrar"></td>
    </tr>
    </table>

</form>

</body>
</html>


*** PAGINA2.PHP ***


<?php

if ($paisant!=$pais) {
    header("location:pagina1.php?nombre=$nombre&pais=$pais");
    }
else {
    // Ingreso de datos a la base de datos
    }
?>

Comentarios

alexander

26/2/2006
el unico combobox que funciona es el de paises porq' al tratar de mostrar las provincias no lo hace...
trabajando en php 5, mysql 5, apache 2

claudio

08/5/2006
alexander no te funciona el segundo box porque estas en global Off,cambialo a global On.
Me gustaria saber,como utilizar este script pero con global OFF.

Victor Alarcon

06/6/2006
estuve observando el ejemplo del articulo, y es adaptable, para trabajar, con oracle y las listas dependientes. lo comprobe fue un exito.
include('adodb/adodb.inc.php');
$db = ADONewConnection('oci8');
$db->Connect('db','login','pasw',false);

Will

19/1/2008
El combo de pais funciona perfectamente pero cuando eligo uno de los paises; no se muestra las provincias sale un pantalla en blanco

fabricio

02/2/2008
Logre adaptar este código para trabajar con GLOBALS OFF aqui les adjunto el código, ademas esta hecho para 3 select, adáptenlo según sus necesidades ok??


TABLA PROVICIAS
cdprovincia
provincia

TABLA CANTON
cdprovincia
cdcanton
canton

TABLA PARROQUIA
cdprovincia
cdcanton
cdparroquia
parroquia

aqui empieza el código**************************

<html>
<html>
<head>
<title>combos2.php</title>
</head>

<body>

<?php
$pais=$_GET['pais'];
$canton=$_GET['canton'];
// Me conecto a la base de datos
mysql_connect("localhost","root","");
mysql_select_db("ubicacion");

// Declaro la variable $paisant que es la que me va a indicar si hay que volver a cargar los datos de las provincias
$paisant=$pais;
$cantonant=$canton;

// if para verificar si se ha presionado el boton enviar
if (!empty($_GET['button'])){
// en caso de que se ha presionado el boton enviar, procesar el formulario
echo "Ingreso de datos a la base de datos...";
$pais=$_GET['pais'];
$canton=$_GET['canton'];
$parroquia=$_GET['parroquia'];

if (strlen($pais)>2) {
$pais='';
}
if (strlen($canton)>2) {
$canton='';
}
if (strlen($parroquia)>2) {
$parroquia='';
}

echo $pais ;
echo $canton;
echo $parroquia ;


}
else
{
// caso contrario volver a general el formulario
// echo "<form action=\"".$_SERVER['PHP_SELF']."\" method=\"POST\">\n\n";
?>
<form method="get" action="combo2.php">
<table width="70%" border="0" align="center">
<?php



print ("
<input type=\"hidden\" name=\"paisant\" value=\"$paisant\">
<input type=\"hidden\" name=\"cantonant\" value=\"$cantonant\">

<tr>
<td><div align=\"right\"><strong>Provincia:</strong></div></td>

<td><select name=\"pais\" onchange=\"submit();\">
");
//Muestra el combobox de las provincias una vez que se haya elegido el país, no antes
if (!isset($pais)){
print ("<option selected>Seleccione la provincia</option>");
$pais="0";
}

$sql="select * from provincia order by 2";
$res=mysql_query($sql);

while($fila=mysql_fetch_array($res)){
print("<option value=\"$fila[cdprovincia]\"");
if ($fila[cdprovincia] == $pais) {
print ("selected");
}
print(">$fila[provincia]</option>\n");
}
print("</select></td></tr>");
// combo cantones
// if para mostrar los cantones
// if ($pais!="0"){
print ("

<tr>
<td><div align=\"right\"><strong>Canton:</strong></div></td>
<td><select name=\"canton\" onchange=\"submit();\">
");
print ("<option selected>Seleccione el canton</option>");
//Muestra el combobox de las parroquias una vez que se haya elegido el canton, no antes
if (!isset($canton)){
$canton="0";
}

$sqlcan="select * from canton where cdprovincia='$pais' order by 2";
$res=mysql_query($sqlcan);

while($fila=mysql_fetch_array($res)){
print("<option value=\"$fila[cdcanton]\"");
if ($fila[cdcanton] == $canton) {
print ("selected");
}
print(">$fila[canton]</option>\n");
}
print("</select></td></tr>");

// combo parroquias
// if para mostrar las parroquias
//if ($canton!="0"){
print("
<tr>
<td><div align=\"right\"><strong>Parroquia:</strong></div></td>
<td><select name=\"parroquia\">
");

print ("<option selected>Seleccione la parroquia</option>");
if (!isset($parroquia)){

$parroquia="0";
}
$sqlparr="select * from parroquia where cdprovincia='$pais' and cdcanton='$canton' order by 2";
$resparr=mysql_query($sqlparr);

while($filaprov=mysql_fetch_array($resparr)){
print("<option value=\"$filaprov[cdparroquia]\">$filaprov[parroquia]</option>");
}
print("
</select>
</td>
</tr>
");
// } // if canton
// } // if pais
?>
<tr>
<td><div align="right"><input name="button" type="submit" value="Enviar"></div></td>
<td><input name="reset" type="reset" value="Borrar"></td>
</tr>
</table>

</form>
<?php
} // cierro if principal del boton enviar
?>
</body>
</html>
****************************

graben el script como combo2.php
espero les sirva a mi me funciona ok...!!!



mark

13/2/2008
amigo justo buscaba un script para 3 select, pero cuando lo pego todo tu script me sale error!!!. :( crees q puedes facilitarmelo en un archivo que ya tienes creado porfa.. eh estado buscando esto. ya hace dias. gracias

mark

13/2/2008
mira el error q me sale es este

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\wamp\www\bitacora\prueba.php on line 10

Warning: Unexpected character in input: ''' (ASCII=39) state=1 in C:\wamp\www\bitacora\prueba.php on line 10

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\wamp\www\bitacora\prueba.php on line 10

Warning: Unexpected character in input: ''' (ASCII=39) state=1 in C:\wamp\www\bitacora\prueba.php on line 10

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\wamp\www\bitacora\prueba.php on line 11

Warning: Unexpected character in input: ''' (ASCII=39) state=1 in C:\wamp\www\bitacora\prueba.php on line 11

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\wamp\www\bitacora\prueba.php on line 11

Warning: Unexpected character in input: ''' (ASCII=39) state=1 in C:\wamp\www\bitacora\prueba.php on line 11

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\wamp\www\bitacora\prueba.php on line 13

Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in C:\wamp\www\bitacora\prueba.php on line 21

manu

23/11/2008
hola tengo una pregunta que pasaria si quiero agregar otro combo al escoger la ciudad que me salga por ejemplo su codigo postal en un texto dependiendo la ciudad que eh escogido ? gracias

Setcito

17/12/2008
Muy buen ejercicio, pero que tendria que hace para agragar un select mas??
Saludos

Dnnstone

14/3/2009
donde se hace ese cambio de los global off a on????

Oscar Emanuel

22/5/2009
NO FUNCIONA
Tengo el mismo problema, he probado todo el codigo utilizando mysql apache y en paises me sale la lista de paises quehe hecho pero no me sale el combo box con las provicias al seleccionar un pais, solo me deriva a pagina2.php como si fuese un enlace...

Se que esta pregunta y repuesta fue hecha hace 3 años... pero seria excelente saber como solucionarla o SI HUBIESE OTRO FORO EN DONDE SE HAGAN EN PHP COMBO BOX ANIDADOS O SELECT DEPENDIENTES para poder solucionar mi pregunta

GRACIAS de antemano

Eulogio Toribio Medina

05/6/2009
excelente ejemplo
solo hay que tener cuidado con los nombres de los campos de las tablas que se relacionan. Por ejemplo: Si los campos de la tabla Paises son IdPaises,NombrePaises. Los Campos de la tabla Provincias sería IdProvincia, NombrePais, CodPais(ojo).Para cualquier cosa mi correo: e.d.sonuribe@hotmail.com...Suerte

31/7/2009
HELP
Yo estoy trabajando en PHP 5 globals off (traté de ponerlas on, pero mi servidor no me deja cambiarlo) quisiera saber como sería el código de conexion2.php para 3 selects con globals off por favor. Gracias!

roman

10/7/2010
tengo el mismo problema
hola me gustaria saber como puedo hacerle en un caso como ese pero sin bases de datos, es decir las opciones de las listas son muy pocas y no veo necesario crear una tabla para cada una, por su apoyo gracias

moño inacap

30/7/2010
trololo
oye re quliao, como se teocurre dejar el php al ultimo y no mostrar el include estupido aweonao :) amanerao... dice mi compañero, longhi

anyyta

29/11/2010
no funcionan
ola ya copie y pegue todo el codigo y tambirn cree las tablas q dices al principio, pero los combos no muestran nada.

karina

21/7/2011
se pierde los valores anteriores
lo adapte a mi codigo y funciona bien justo lo que necesitaba pero al ingresar valores a los input que estan antes y no dentro de la funcion q los paises al cargar m borra todos los datos. un detalle que veo es q se pongo en la pagina2.php los valores que ya se cargaron no se borra pero si hago eso ya no es fiable mi formulario porq muestra los valores. Alguna solucion para ello por favor!!!

Estoy desesperada gracias!!

carlos

06/8/2011
no funciona
Benas , me parece muy interesanta y gusto lo que andaba buscando, pero solo se habra el combox de paisesy se pasa a la pagina2.php por que sucede eso, l aqui mismo que hay poerlo en on pero como es eso no entiendo

Compartir