Campos SELECT dinámicos con jQuery, Ajax, PHP y MySQL

Un script para generar dos campos de formulario SELECT dinámicos y combinados, con programación cliente Javascript y Ajax con jQuery y programación servidor por medio de PHP y MySQL.
La creación de los campos SELECT combinados es una de las tareas clásicas que algún desarrollador va a tener que solucionar algún día. Existen muchas maneras de llevarla a cabo, pero sin duda, cuando se utiliza Ajax el resultado de cara al usuario es mucho mejor. En este artículo queremos mostrar una manera de hacer que las opciones de un SELECT dependan de lo que se haya escogido en otro, lo que conocemos como "selects dinámicos" o "selects combinados".

Para ello vamos a relatar un caso práctico completo. Un sistema que nos permitirá escoger provincias en un select y luego una población en otro select, que dependerá de la provincia seleccionada en el promer select. Veremos todo el sistema de manera global, desde la programación del cliente con Javascript y Ajax, pasando por el desarrollo en el servidor por medio de PHP y una base de datos MySQL donde están todas las provincias y poblaciones. Además, utilizaremos el el framework Javascript jQuery, para facilitarnos la vida gracias a sus funciones para hacer Ajax y modificar el DOM de la página.

Nota: Recordar que en DesarrolloWeb.com podréis aprender sobre todas las tecnologías utilizadas, como Javascript, Ajax, jQuery, PHP, MySQL...
Así mismo, podemos consultar otros artículos que también tratan sobre hacer este tipo de interfaces de usuario, como Elementos de formulario select asociados con Javascript http://www.desarrolloweb.com/articulos/1281.php o bien Selects combinados con Ajax y PHP.

En el ejercicio utilizaremos en total 3 tablas: provincias, poblaciones y clientes. En este tutorial vamos a insertar y modificar la base de datos, para ello necesitaremos crear 3 documentos: insertar.php, modificar.php y buscar.php.

Para los documentos insertar.php y modificar.php iniciamos el documento poniendo la conexión a base de datos y el enlace con la librería jQuery.

Nota: Si te interesa el código fuente de los archivos de este ejemplo te recomiendo que no copies y pegues el código que aparece en este artículo. Es mucho mejor que descargues todo el código para hacer los selects dinámicos de la la página de GitHub: http://github.com/desarrollowebcom/SELECT-dinamicos-jQuery-Ajax-PHP-MySQL/downloads

<?
function Conectarse(){
if (!($link=mysql_connect("localhost","root","")))
{echo "Error conectando a la base de datos.";
exit();
}
if (!mysql_select_db("desarrolloweb",$link))
{
echo "Error seleccionando la base de datos.";
exit();
}
return $link;
}
$link=Conectarse();

echo "<!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\" />
<script src=\"http://code.jquery.com/jquery-latest.js\"></script>
</head>

<body>";
?>

Y para su finalización :

Ahora creamos el formulario de insertar. Como podemos ver, en el select RE_Prov he puesto un atributo que lo utilizaremos para modificarlo. Si esta vacío al insertar no pasa nada.

<?
echo "<FORM action=\"".$_SERVER["PHP_SELF"]."\" method=\"POST\" style='margin:30px 5px 30px 5px;'>
<table width=\"500px\">
<tbody>
<tr>
<td>Nombre</td>
<td><input type=\"text\" name=\"nombre\" /></td>
</tr>
<tr>
<td>Provinvia</td>
<td><select name='RE_Prov' id=\"provincia\" poblacioattri=''>
<option value=''>Seleccione provincia</option>";
$B_BUSCAR= mysql_query ("SELECT * FROM provincias order by provincia asc",$link);
$R_BUSCAR=mysql_fetch_assoc($B_BUSCAR);
$C_BUSCAR=mysql_num_rows($B_BUSCAR);
$suma=0;
do{ ++$suma;
echo "<option value='".$R_BUSCAR['id']."'>".$R_BUSCAR['provincia']."</option>";
}while($R_BUSCAR=mysql_fetch_assoc($B_BUSCAR));
echo "</select> <span id='Buscando'></span></td>
</tr>
<tr>
<td>Población</td>
<td><select name='RE_pobla' id=\"poblacionList\">
<option value='' selected='selected'>Seleccionar población</option>
</select></td>
</tr>
<tr>
<td></td>
<td><input type=\"submit\" /></td>
</tr>
</tbody>
</table>
</form>";
?>

Este es el Script que utilizaremos para hacer la búsqueda a la base de datos.

<script>
jQuery('#provincia').change(function () {
var numero =document.getElementById("provincia").value;
var poblacio = jQuery(this).attr("poblacioattri");
var to=document.getElementById("Buscando");
to.innerHTML="buscando....";
jQuery.ajax({
type: "POST",
url: "busqueda.php",
data: 'idnumero='+numero+'&idpobla='+poblacio,
success: function(a) {
jQuery('#poblacionList').html(a);
var to=document.getElementById("Buscando");
to.innerHTML="";
}
});
})
.change();
</script>

Detalles del script:
Para saber el valor de la provincia: var numero =document.getElementById("provincia").value;
Cuando movemos este select escribimos en buscando.... esto está puesto aquí:
var to=document.getElementById("Buscando");
to.innerHTML="buscando....";

Enviamos la información deseada al documento busqueda.php en post y enviado estos datos:

data: 'idnumero='+numero+'&idpobla='+poblacio,
idnumero es el valor del select de la provincia y idpobla es el atributo pero que ahora esta vació.
Cuando se realice la busqueda lo mostraremos aquí:

jQuery('#poblacionList').html(a);

y el borraremos buscando.... así:

var to=document.getElementById("Buscando");
to.innerHTML="";

Ponemos lla inserción a la base de datos.

<?
if($_POST["nombre"]){
$nombre=addslashes($_POST["nombre"]);
$RE_Prov=addslashes($_POST["RE_Prov"]);
$RE_pobla=addslashes($_POST["RE_pobla"]);

$insertar=mysql_query("INSERT clientes (nombre,provincia,poblacion) VALUES ('$nombre','$RE_Prov','$RE_pobla')",$link);
if ($insertar==1){echo "<script>alert(\"Se ha insertado.\");</script>";}else{echo "<script>alert(\"Error!!!!.\");</script>";}
}
?>

y cerramos :

</body>
</html>
?>

Ahora vamos a explicar que hay en buscar.php:
Primero ponemos la conexión y su búsqueda a la base de datos i mostramos los resultados.
Recordar que desde insertar.php y modificar.php se envían dos variables por POST que son $_POST["idnumero"] que es el valor de la provincia y después $_POST["idpobla"] que es el valor de la población.

<?
function Conectarse()
{
if (!($link=mysql_connect("localhost","root","")))
{
echo "Error conectando a la base de datos.";
exit();
}
if (!mysql_select_db("desarrolloweb",$link))
{
echo "Error seleccionando la base de datos.";
exit();
}
return $link;
}
$link=Conectarse();

$B_BUSCAR= mysql_query ("SELECT * FROM poblaciones where idprovincia='".$_POST["idnumero"]."' order by poblacio asc",$link);
$R_BUSCAR=mysql_fetch_assoc($B_BUSCAR);
$C_BUSCAR=mysql_num_rows($B_BUSCAR);
if($C_BUSCAR){
do{
if($_POST["idpobla"]==$R_BUSCAR['id']){$TRUE=" selected='TRUE'";}else{$TRUE="";}
echo "<option value='".$R_BUSCAR['id']."' $TRUE>".htmlentities($R_BUSCAR['poblacio'])."</option>";

}while($R_BUSCAR=mysql_fetch_assoc($B_BUSCAR));
}else{
echo "<option value=''>".htmlentities("Seleccionar población")."</option>";
}
mysql_close($link);
?>
?>

Ahora vamos a crear el formulario de modificar, pero promero vamos a crear el listado con los resultados que hay en la tala de clientes y después iremos al formulario mediante un link.

<?
// Para hacerlo sencillo he puesto una variable que se llama ac y que si no existe se muestra el listado esta variable se envía por GET.
if(!$_GET["ac"]){
echo "<h3>Listado</h3>
<table width=\"500px\" style='margin:30px 5px 30px 5px;'>";
$B_BUSCAR= mysql_query ("SELECT * FROM clientes",$link);
$R_BUSCAR=mysql_fetch_assoc($B_BUSCAR);
$C_BUSCAR=mysql_num_rows($B_BUSCAR);
$suma=0;
do{ ++$suma;
echo "<tr><td><a href='".$_SERVER["PHP_SELF"]."?ac=1&id=".$R_BUSCAR["id"]."'>$suma ".stripslashes($R_BUSCAR["nombre"])." (Modificar)</a></td></tr>";
}while($R_BUSCAR=mysql_fetch_assoc($B_BUSCAR));
echo "</table>";
}else{
// Ahora buscamos los datos seleccionados.


$B_cliente= mysql_query ("SELECT * FROM clientes where id='".$_GET["id"]."'",$link);
$R_cliente=mysql_fetch_assoc($B_cliente);
$C_cliente=mysql_num_rows($B_cliente);

// Recuperamos la información y la ponemos dentro de una variable.
$nombre=stripslashes($R_cliente["nombre"]);
$RE_Prov=stripslashes($R_cliente["provincia"]);
$RE_pobla=stripslashes($R_cliente["poblacion"]);

echo "
<h3>Modificar</h3>
<FORM action=\"".$_SERVER["PHP_SELF"]."\" method=\"POST\" style='margin:30px 5px 30px 5px;'>
<table width=\"500px\">
<tbody>
<tr>
<td>Nombre</td>
<td><input type=\"text\" name=\"nombre\" value='$nombre' /></td>
</tr>
<tr>
<td>Provinvia</td>";
// Ahora si que utilizamos el atributo poblacioattri donde ponemomos dentro la variavle de la población actual
echo "
<td><select name='RE_Prov' id=\"provincia\" poblacioattri='$RE_pobla'>
<option value=''>Seleccione provincia</option>";
$B_BUSCAR= mysql_query ("SELECT * FROM provincias order by provincia asc",$link);
$R_BUSCAR=mysql_fetch_assoc($B_BUSCAR);
$C_BUSCAR=mysql_num_rows($B_BUSCAR);
$suma=0;
do{ ++$suma;
echo "<option value='".$R_BUSCAR['id']."'";if($RE_Prov==$R_BUSCAR['id']){echo " selected='true'";}echo ">".$R_BUSCAR['provincia']."</option>";
}while($R_BUSCAR=mysql_fetch_assoc($B_BUSCAR));
echo "</select> <span id='Buscando'></span></td>
</tr>
<tr>
<td>Población</td>
<td><select name='RE_pobla' id=\"poblacionList\">
<option value='' selected='selected'>Seleccionar población</option>
</select></td>
</tr>
<tr>
<td></td>
<td><input type=\"hidden\" name=\"MOD_ID\" value=\"".$_GET["id"]."\" /><input type=\"submit\" /></td>
</tr>
</tbody>
</table>
</form>";
}
?>
?>

Ponemos el script donde si que recuperamos el atributo poblacioattri y la forma de recuperarlo es así:

var poblacio = jQuery(this).attr("poblacioattri");

<script>
jQuery('#provincia').change(function () {
var numero =document.getElementById("provincia").value;
var poblacio = jQuery(this).attr("poblacioattri");
var to=document.getElementById("Buscando");
to.innerHTML="buscando....";
jQuery.ajax({
type: "POST",
url: "busqueda.php",
data: 'idnumero='+numero+'&idpobla='+poblacio,
success: function(a) {
jQuery('#poblacionList').html(a);
var to=document.getElementById("Buscando");
to.innerHTML="";
}
});
})
.change();
</script>
?>

Y modificamos:

if($_POST["nombre"]){
$nombre=addslashes($_POST["nombre"]);
$RE_Prov=addslashes($_POST["RE_Prov"]);
$RE_pobla=addslashes($_POST["RE_pobla"]);

$mod=mysql_query("UPDATE clientes SET nombre='$nombre',provincia='$RE_Prov',poblacion='$RE_pobla' WHERE id=".$_POST["MOD_ID"]."",$link);
if ($mod==1){echo "<script>alert(\"Se ha Modificado.\");</script>";}else{echo "<script>alert(\"Error!!!!.\");</script>";}
}
?>

y cerramos :

</body>
</html>

Compartir

Comentarios

Drhank

01/6/2010
Excelente!
Excelente tutorial. Muy bien explicado.

Gracias y sigan asi

Xint0

02/6/2010
Alternativa utilizando jQuery y JSON
En mi artículo: <a href="http://blog.xint0.com/2010/04/listas-dependientes-con-jquery.html">Listas dependientes con jQuery</a> describo una alternativa en la que los datos están en archivos de texto codificados en JSON.

israelamorsi

17/6/2010
Algo me salio mal..
Esta muy interesante y es justo lo que estaba buscando.. Pero me surge un detalle al probarlo en el select de Provincia no me muestra su texto.. pero si se ve que estan ahi en blanco..

Ademas en el select de Poblacion me manda este Warning

Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in C:AppServwwwotrosselect_dinamicousqueda.php on line 19

Espero su respuesta...Saludos

Mario At

17/6/2010
Excelente!
HOLA QUE TAL AMIGO, ES UN EXECENTE EJEMPLO DE LA COMBINACION DE ESTAS TECNOLOGIAS DE PROGRAMACION, SALUDOS.....GRACIAS POR EL APORTE

EduardNebot

21/6/2010
Hola israela
Si no te funciona puedes contactar conmigo a enebot aquiala@ chromalife.com

sandra

10/7/2011
hacer aparecer select en html
Hola, este código me ha sido muy útil para generar un select a partir de una base de datos en que se hace una slección conforme a un valor pasado por ajax. El problema es que ahora necesitaria hacer aparecer el select generado en php en mi documento html i no lo consigo. Si me podeis hechar una mano.
Esta el lafunción, en la que el _msg optenido es el select del php. En funcion me gustaria conseguir hacerlo aparecer en un div. gracias.

function get_link(){

$.ajax({
url: "get_link.php",
type: "GET",
data: ({
"placename": placename
}),
dataType: "html",
success: function(_msg){

alert(_msg);
}

Lollo

03/8/2011
Muchas gracias por el aporte.
Muchas gracias por el aporte.

ciclao22

04/8/2011
Este script no funciona
El script no funciona, esta mal codificado, no sigues ningun estandar de codificacion en PHP, metes HTML dentro de echos y luego acabas de montar la pagina con HTML.

Creo que deberiais revisar bien los scripts que envia la gente, para garantizar un minimo de calidad tanto de funcionalidad como de sintaxis y estandares de codificacion.

maximiles

01/9/2011
MUY BUENO
GRACIAS

gener

18/9/2011
a mi me funciona
Pero lo que quiero es que en ves de mostrar el resultado en un combo lo muestre en una caja de teto osea mas o menos asi

succesu: function (a){
$('#id del input').val(a);
});
Pero este codigo muestra toda la pagina en el input ejemplo <html><body>...

eglis2010

28/10/2011
Campos SELECT dinámicos con jQuery, Ajax, PHP y MySQL
Esto es una buena idea, el mesclar estos lenguajes y las bases de datos.

PipeRodriguez

17/11/2011
PEGUNTA
Hey muy buen post, el codigo me esta funcionando de maravilla, pero como somos humanos, por ende ambiciosos y siempre queremos mas, queria preguntarte si sabes como hacerlo para tres selects, creeria que es de manera similar pero no funciona el tercer select no carga, lo que hago en mi codigo es que apenas seleccione algo en el primer select , me carge el segundo, pero a la vez, al cargarme le segundo necesito que empiece a cargar el tercero y hay es donde se queda?????
Porfavor ayudenme................................
Gracias

Cesar Amezcua

16/11/2012
como puedo hacer algo como esto
como puedo hacer algo como esto
http://sportfitness.com/casa

donde los slects son independientes pero dinamicos

Jorge

27/12/2012
Excelente ejemplo!
Hola!

Excelente ejemplo! Me sirvió mucho! Muchas gracias al autor!

Solo tengo una pregunta..

En la línea:

echo "<option value='".$R_BUSCAR['id']."' $TRUE>".htmlentities($R_BUSCAR['poblacio'])."</option>";

Veo que $TRUE no está dentro del string (con sus comillas y puntos correspontientes. .. ¿Por qué es eso?

Gracias!
Saludos!

Victor

06/7/2013
Actualizarse es necesario
Ya deberian trabajar la programacion con php con el paradigma Orientado a Objeto

gerardo simancas

24/6/2015
codigo
al instante de ver el codigo, busque si el autor era miguel alvarez y vi que no! porque el no explicaria asi, eso esta muy enredado y la explicacion no es rica, ademas no da un ejemplo en una pagina aparte como lo hace el otro...

fernando

02/4/2016
Mala Practica
Muy mala practica mesclar código, sobre todo si tiene consultas directas a la base de dato...
Les recomiendo que investiguen todo sobre el mvc en PHP.
Saludos.

Ivan Arrua

10/12/2016
Pregunta
Muy buen trabajo me ha servido mucho!!!

tengo una duda si quisiera agregar por ejemplo el país donde tendría que ponerlo??