PHP:¿Cómo hacer una lista desplegable (select) con valores de una tabla Mysql que dependa del valor seleccionado en la primera?

De Foros del Web

Se trata de hacer una consulta a tu tabla "hija" con la cláusula (confición) que identifique la relación entre ambas tablas. (usando como clave un campo de nuestra tabla hija que nos haga de clave foránea para nuestra consulta). En este caso usaremos el campo id_padre de la tabla_hija como "clave foránea" .. ambos del mismo tipo y relación 1 -> N (1 registro es a muchos registros de la otra tabla ..)

Partiendo de una estructura SQL así: (como ejemplo completo de funcionamiento ..adáptenla a sus necesidades)

Código:

#
# Estructura de tabla para tabla `tabla_hija`
#
 
CREATE TABLE tabla_hija (
  id tinyint(3) unsigned NOT NULL auto_increment,
  id_padre tinyint(3) unsigned NOT NULL default '0',
  item_texto varchar(255) NOT NULL default '',
  PRIMARY KEY  (id)
) TYPE=MyISAM;
 
#
# Volcar la base de datos para la tabla `tabla_hija`
#
 
INSERT INTO tabla_hija VALUES (1, 1, 'tabla_hija - Item grupo 1 bla bla bla');
INSERT INTO tabla_hija VALUES (2, 2, 'tabla_hija - grupo 2 item 1');
INSERT INTO tabla_hija VALUES (3, 2, 'tabla_hija - grupo 2 item 2');
INSERT INTO tabla_hija VALUES (4, 3, 'tabla_hija - grupo 3 item probando');
INSERT INTO tabla_hija VALUES (5, 1, 'tabla_hija - item grupo 1 noseq pner');
# --------------------------------------------------------
 
#
# Estructura de tabla para tabla `tabla_padre`
#
 
CREATE TABLE tabla_padre (
  id tinyint(3) unsigned NOT NULL auto_increment,
  item_texto varchar(255) NOT NULL default '',
  PRIMARY KEY  (id)
) TYPE=MyISAM;
 
#
# Volcar la base de datos para la tabla `tabla_padre`
#
 
INSERT INTO tabla_padre VALUES (1, 'Grupo 1');
INSERT INTO tabla_padre VALUES (2, 'Grupo 2');
INSERT INTO tabla_padre VALUES (3, 'Grupo 3');
INSERT INTO tabla_padre VALUES (4, 'Grupo 4');

Y el código de nuestras consultas a realizar:

Código PHP:

<?php
// datos de conexión a la BD.
$servidor  ="localhost"; // host
$usuario   =""; 
$clave     ="";
$basedatos =""; // Indicar una Base de datos.
 
// si se ha pulsado el botón enviar ($enviado) se procesa el formulario ...
// Sino, se continua con el formulario y los nuevos valores de los Select ...
// OJO si se tienen más varibles (más <input> ) se van a perder sus valores a no ser
// que los obtengamos y se les de como valor inicial en el value= de cada uno según corresponda.
 
if (!empty($_POST['enviado'])){
 
// Procesar el formulario ...
echo "Procesando formulario:<br>";
echo "Recibido id_tabla_padre: ".$_POST['id_padre']."<br>";
echo "Recibido id_tabla_hija: ".$_POST['id_hija'];
 
} else {
 
   // Conexión a la BD
   $conexion = mysql_connect($servidor, $usuario, $clave) or die(mysql_error());
   mysql_select_db($basedatos, $conexion) or die(mysql_error());
 
   // Obtener el $id_padre del envío a sí mismo del formulario ...
   $id_padre=$_POST['id_padre'];
 
   // Inicio Formulario .. PHP_SELF enviamos a sí mismo (a este script).
   echo "<form action=\"".$_SERVER['PHP_SELF']."\" method=\"POST\">\n\n";
 
   // Formar Selec "Padre".
   echo "<select name=\"id_padre\" onChange=\"this.form.submit()\">\n";
   echo "<option value=\"\"> Seleccione un Item </option>\n";
 
   $SQLconsulta_padre="SELECT * FROM tabla_padre";
   $consulta_padre = mysql_query($SQLconsulta_padre,$conexion) or die(mysql_error());
 
   While   ($registro_padre=mysql_fetch_assoc($consulta_padre)){
      // Se mira si el ID del registro es el mismo q el $id_padre q recibimos si hemos cambiado el select hijo.
      // Se selecciona en consecuencia (selected) la opción elegida.
      if ($id_padre == $registro_padre['id']){
         echo "<option value=\"".$registro_padre['id']."\" selected>".$registro_padre['item_texto']."</option>\n";
      } else {
         echo "<option value=\"".$registro_padre['id']."\">".$registro_padre['item_texto']."</option>\n";
      }
    }
   echo "</select>\n\n";
 
   mysql_free_result($consulta_padre); // Liberar memoria usada por consulta.
 
   // Formar Select "Hijo"
   echo "<select name=\"id_hija\">\n";
 
   // Si $id_padre no tiene valor (caso de que no se ha seleccionado ningua opción del select hijo
   // se muestra el mensaje de "seleccine un item" (del select padre).
   if (!empty($id_padre)){
 
       $SQLconsulta_hija="SELECT * FROM tabla_hija WHERE id_padre='$id_padre'";
       $consulta_hija = mysql_query($SQLconsulta_hija,$conexion) or die(mysql_error());
       // se mira el total de registros de la consulta .. si es 0 se muestra mensaje en el select ..
       if (mysql_num_rows($consulta_hija) != 0){
          While   ($registro_hija=mysql_fetch_assoc($consulta_hija)){
            echo "<option value=\"".$registro_hija['id']."\">".$registro_hija['item_texto']."</option>\n";
          }
        } else {
            echo "<option value=\"\"> No hay registros para este Item </option>";
        }
    } else {
        echo "<option value=\"\"> <-- Seleccione un Item  </option>";
    }
 
    mysql_free_result($consulta_hija); // Liberar memoria usada por consulta.
 
    echo "</select>\n\n";
    echo "<input type=\"submit\" name=\"enviado\" value=\" Enviar \" >\n\n";
    echo "</form>\n";
} 

Otras Técnicas que sería interesante ver sobre el tema, sería el denominado "Remote Scripting" que se basa en disponer de iframe/frames ocultos donde se realiza la petición de datos al servidor (petición de nuestro .php que ejecutará la consulta SQL pertinente y obtendrá sus datos), esos datos serán "pasados" a la página principal (frame o "padre" que contenga el iframe oculto) por medio de javascript. De esta forma ... no se verá una recarga "aparente" de la página que estamos visualizando sin que será ese "frame" el que se recarga ante una petición que hagamos vía javascript de mover algún <select> u otro evento javascript que lance dicho proceso de "Remote Scripting".

Puede ver un tutorial sobre el tema con algunos ejemplos en: http://www.ashleyit.com/rs/main.htm


--Cluster 04 May 2004

Este artículo es parte de las FAQs de PHP y el Manual de PHP.

Herramientas personales