BLOG DE DISEÑO WEB CORUÑA

Un poco de todo, recursos, tutoriales, noticias, anuncios...

Combobox o selects dependientes de 3 niveles con PHP y jQuery

23/JUL/2012 103.464 visitas Ver comentarios
Combobox o selects dependientes de 3 niveles con PHP y jQuery

ADVERTENCIA: Este artículo tiene más de 6 meses de antigüedad. Puede que esta información ya se encuentre obsoleta o haya nuevas y mejores opciones.

A menudo nos encontramos con la necesidad de realizar listas o selects dependientes del valor seleccionado en un nivel superior. Lo que comúnmente llamamos combobos o selects dependientes, que al seleccionar una opción de una lista, vamos actualizando las listas de niveles inferiores o, mejor dicho, dependientes del anterior.

Traduciendo, tenemos 3 listas (las llamaremos SELECT PADRE, SELECT HIJO y SELECT NIETO), pues bien, lo que queremos es que PADRE actualice a HIJO y éste a su vez, actualice a NIETO... pero cuidado, que también queremos que si se cambia alguno de estos valores, tanto PADRE, HIJO y NIETO se actualicen sobre la marcha.

Sé que es un poco confuso de explicar, más fácil es mirarse la demo que puse online y decir, siiii esto es lo que necesitaba pero este tío se explica fatal :)

Vamos por partes.
Para empezar, necesitaremos  tener en cuenta los elementos que vamos a utilizar y estos son:

  • Librería jQuery
  • un formulario en html
  • una pizca de javascript
  • PHP para obtener los valores actualizados de nuestros PADRE, HIJO y NIETO.

 

Empecemos.
Muchos ejemplos que vemos por ahí funcionan a la perfección pero les falta el plus de traer datos de una base de datos, con lo que evitamos grandes arrays si tenemos muchos registros en nuestras tablas mysql, pero castigamos al servidor haciendo peticiones cada vez que se cambia una opción de uno de los 3 SELECTS.

Primer paso.
El primer paso consiste en crear nuestros selects para la vista inicial. Podemos crearlos con valores ya cargados o en blanco, poniendo valores únicamente en PADRE... para que HIJO y NIETO se rellenen una vez comenzado el ciclo. En mi caso, ya traigo los selects con datos de la base de datos y con un valor predefinido en cada uno, para lograr evitar comentarios del tipo... vale, ahora quiero que aparezca X valor ya seleccionado :)

Segundo paso.
Metemos un pequeño código javascript que gracias a la potencia de live() en jQuery, podemos asignar funciones a instancias o elementos que aun no existen o que cambiarán su valor en el vuelo. Si bien en mi ejemplo los selects ya existen (sus instancias), el evento LIVE permitirá ejecutar acciones sobre ellos una vez recargados remotamente.

Tercer paso.
El tercer paso es el backend, la llamada remota que harán nuestros selects para ir a buscar los valores que le corresponden a los selects inferiores.

Más pasos.
No hay más pasos, para qué complicar la historia si la podemos hacer sencilla. Vamos a ver los códigos.

Los códigos.
En el código 1, te dejo la estructura de las tablas MYSQL que usé en el ejemplo. En el código 2 te dejo el html formado con javascript y html y, en el código 3, te dejo el PHP remoto que nos traerá la magia.

Cualquier comentario que quieras dejar o propuesta para mejorar este código es bienvenida. Si te gustó, por favor, no olvides compartirlo con los botones sociales que hay por todos lados :)

Código 1 - MYSQL
-- phpMyAdmin SQL Dump
-- version 3.4.5
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 21-07-2012 a las 20:43:20
-- Versión del servidor: 5.5.8
-- Versión de PHP: 5.3.5
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Base de datos: `combobox`
--
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `hijo`
--
CREATE TABLE IF NOT EXISTS `hijo` (
`idhijo` int(255) NOT NULL AUTO_INCREMENT,
`idpadre` int(255) NOT NULL DEFAULT '0',
`hijo` text COLLATE latin1_spanish_ci NOT NULL,
PRIMARY KEY (`idhijo`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=5 ;
--
-- Volcado de datos para la tabla `hijo`
--
INSERT INTO `hijo` (`idhijo`, `idpadre`, `hijo`) VALUES
(1, 1, 'Subfamilia 1 en Familia 1'),
(2, 1, 'Subfamilia 2 en Familia 1'),
(3, 2, 'Subfamilia 1 en Familia 2'),
(4, 2, 'Subfamilia 2 en Familia 2');
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `nieto`
--
CREATE TABLE IF NOT EXISTS `nieto` (
`idnieto` int(255) NOT NULL AUTO_INCREMENT,
`idhijo` int(255) NOT NULL DEFAULT '0',
`nieto` text COLLATE latin1_spanish_ci NOT NULL,
PRIMARY KEY (`idnieto`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=6 ;
--
-- Volcado de datos para la tabla `nieto`
--
INSERT INTO `nieto` (`idnieto`, `idhijo`, `nieto`) VALUES
(2, 1, 'Subsub en sub1'),
(3, 2, 'Subsub en sub2'),
(4, 3, 'Subsub en sub3'),
(5, 4, 'Subsub en sub4');
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `padre`
--
CREATE TABLE IF NOT EXISTS `padre` (
`idpadre` int(255) NOT NULL AUTO_INCREMENT,
`padre` text COLLATE latin1_spanish_ci NOT NULL,
PRIMARY KEY (`idpadre`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=3 ;
--
-- Volcado de datos para la tabla `padre`
--
INSERT INTO `padre` (`idpadre`, `padre`) VALUES
(1, 'Familia 1'),
(2, 'Familia 2');
Código 2 - PHP
<?php
function idpadre($nombre,$valor)
{
include("config.inc.php");
$query = "SELECT * from padre order by padre";
mysql_select_db($dbname);
$result = mysql_query($query);
echo "<select name='$nombre' id='$nombre'>";
echo "<option value=''>Selecciona un Padre...</option>";
while($registro=mysql_fetch_array($result))
{
echo "<option value='".$registro["idpadre"]."'";
if ($registro["idpadre"]==$valor) echo " selected";
echo ">".$registro["padre"]."</option>\r\n";
}
echo "</select>";
}
function idhijo($nombre,$valor)
{
include("config.inc.php");
$query = "SELECT * FROM hijo order by hijo";
mysql_select_db($dbname);
$result = mysql_query($query);
echo "<select name='$nombre' id='$nombre'>";
echo "<option value=''>Selecciona un Hijo...</option>";
while($registro=mysql_fetch_array($result))
{
echo "<option value='".$registro["idhijo"]."'";
if ($registro["idhijo"]==$valor) echo " selected";
echo ">".$registro["hijo"]."</option>\r\n";
}
echo "</select>";
}
function idnieto($nombre,$valor)
{
include("config.inc.php");
$query = "SELECT * FROM nieto order by nieto";
mysql_select_db($dbname);
$result = mysql_query($query);
echo "<select name='$nombre' id='$nombre'>";
echo "<option value=''>Selecciona un Nieto...</option>";
while($registro=mysql_fetch_array($result))
{
echo "<option value='".$registro["idnieto"]."'";
if ($registro["idnieto"]==$valor) echo " selected";
echo ">".$registro["nieto"]."</option>\r\n";
}
echo "</select>";
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
<title>Ejemplo de Combobox o Select Dependientes con PHP y Jquery | Martin Iglesias</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
/* COMBOBOX */
$("#idpadre").change(function(event)
{
var idpadre = $(this).find(':selected').val();
$("#pidhijo").html("<img src='loading.gif' />");
$("#pidhijo").load('combobox.php?buscar=hijos&idpadre='+idpadre);
var idhijo = $("#idhijo").find(':selected').val();
$("#pidnieto").html("<img src='loading.gif' />");
$("#pidnieto").load('combobox.php?buscar=nietos&idhijo='+idhijo);
});
$("#idhijo").live("change",function(event)
{
var id = $(this).find(':selected').val();
$("#pidnieto").html("<img src='loading.gif' />");
$("#pidnieto").load('combobox.php?buscar=nietos&idhijo='+id);
});
});
</script>
<style>
select{padding:5px;border:1px solid #bbb;border-radius:5px;margin:5px 0;display:block;box-shadow:0 0 10px #ddd}
#resultados{margin:20px 0;padding:20px;border:10px solid #ddd;}
</style>
</head>
<body>
<h1>Ejemplo de Combobox o Select Dependientes con PHP y Jquery | Martin Iglesias</h1>
<p>
<strong>Nota:</strong> Para nuestro ejemplo, utilizamos 3 selects. Vamos a preasignar valores. padre=1, hijo=2, nieto=3</p>
</p>
<div id="resultados">
<?php
if (isset($_POST)) print_r($_POST);
?>
</div>
<form method="post" action="<?php echo $_SERVER["PHP_SELF"]; ?>">
<fieldset>
<p><label>Padre:</label><?php idpadre("idpadre","1"); ?></p>
<p id="pidhijo"><label>Hijo:</label><?php idhijo("idhijo","2"); ?></p>
<p id="pidnieto"><label>Nieto:</label><?php idnieto("idnieto","3"); ?></p>
<p><input type="submit" name="submit" value="Mostrar resultados" /></p>
</fieldset>
</form>
</body>
</html>
Código 3 - PHP
/* ARCHIVO CONFIG.PHP */
<?php
$dbhost="localhost";
$dbname="combobox";
$dbuser="root";
$dbpass="";
$db = mysql_connect($dbhost,$dbuser,$dbpass);
?>
/* ARCHIVO COMBOBOX.PHP */
<?php
include 'config.inc.php';
if ($_GET[buscar]=="hijos")
{
$consulta="SELECT * FROM hijo WHERE idpadre='".mysql_real_escape_string(intval($_GET["idpadre"]))."' order by hijo";
mysql_select_db($dbname);
$todos=mysql_query($consulta);
// Comienzo a imprimir el select
echo "<label>Hijo:</label><select name='idhijo' id='idhijo'>";
echo "<option value=''>Selecciona un Hijo...</option>";
while($registro=mysql_fetch_array($todos))
{
// Convierto los caracteres conflictivos a sus entidades HTML correspondientes para su correcta visualizacion
// Imprimo las opciones del select
echo "<option value='".$registro["idhijo"]."'";
if ($registro["idhijo"]==$valoractual) echo " selected";
echo ">".utf8_encode($registro["hijo"])."</option>";
}
echo "</select>";
}
if ($_GET[buscar]=="nietos")
{
$consulta="SELECT * FROM nieto WHERE idhijo='".mysql_real_escape_string(intval($_GET[idhijo]))."' order by nieto";
mysql_select_db($dbname);
$todos=mysql_query($consulta);
// Comienzo a imprimir el select
echo "<label>Nieto:</label><select name='idnieto' id='idnieto'>";
echo "<option value=''>Selecciona un Nieto...</option>";
while($registro=mysql_fetch_array($todos))
{
// Convierto los caracteres conflictivos a sus entidades HTML correspondientes para su correcta visualizacion
// Imprimo las opciones del select
echo "<option value='".$registro["idnieto"]."'";
if ($registro["idnieto"]==$valoractual) echo " selected";
echo ">".utf8_encode($registro["nieto"])."</option>";
}
echo "</select>";
}
?>

Acerca del Autor...

Macadia, es una agencia de Diseño Web Coruña, especializada en maquetación css y desarrollo de páginas web a medida con más de 22 años de experiencia en el desarrollo de páginas web profesionales. Si te ha gustado este artículo, por favor, ayúdanos a difundirlo compartiéndolo con tus amigos y contactos en las distintas redes sociales que utilices. ¡Muchas gracias!

Los comentarios han sido desactivados momentaneamente a la espera de que Disqus adapte su plataforma a la próxima RGPD que entra en vigor desde el 25/05/2018