domingo, 4 de noviembre de 2012

Cargar un select desde otro select PHP + AJAX + MySQL

Para cargar o llenar un select con datos de la base de datos a partir de otro select utilizamos AJAX y el evento onchange de JavaScript. El siguiente ejemplo consta de una base de datos compuesta por dos tablas una llamada continente y otro pais. Cuando se selecciona un continente aparece unos cuantos paises perteneciente a ese continente, para ello las tablas tienen que estar obligatoriamente relacionadas.


El ejemplo está dividio en cuatro archivos:

El archivo conexion para conectarnos a la base de datos.

conexion.php


<?php

function conexion(){

$con = mysql_connect("localhost","root","");

if (!$con){

die('Could not connect: ' . mysql_error());
}

mysql_select_db("database", $con);

return($con);

}

?>


Este archivo es la vista al usuario. Contiene el primer select donde cargamos en él los continentes almacenados en la base de datos. Tiene como atributo el evento onchange de JavaScript el cual ejecuta la funcion ajax load() cada vez que se hace clic sobre una opcion (continente).

index.php

<?php
include 'conexion.php';
?>
<!DOCTYPE html>

<html>

<head>

<script src="ajax.js"></script>

</head>

<body>

<h2>HTML - PHP - AJAX - MySQL</h2>

<?php

$con=conexion();
$res=mysql_query("select * from continente",$con);

?>

<select id="cont" onchange="load(this.value)">

<option value="">Seleccione</option>

<?php

while($fila=mysql_fetch_array($res)){

?>

<option value="<?php echo $fila[codigo]; ?>"><?php echo $fila[nombre]; ?></option>

<?php } ?>

</select>

<div id="myDiv"></div>

</body>

</html>

El archivo ajax.js es un archivo javascript el cual contiene la funcion load(), esta cáptura el código del continente seleccionado y se lo envía al archivo proc.php a través de la variable q y con el método post para que lo procese.

ajax.js


function load(str)
{
var xmlhttp;

if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("POST","proc.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("q="+str);
}


Finalmente este archivo captura el código del continente para hacer una consulta a la base de datos y mostrar en otro select los paises del continente seleccionado. El resultado se visualiza en el div con id igual a myDiv ubicado en el archivo index.php

proc.js


<?php
include 'conexion.php';

$q=$_POST['q'];
$con=conexion();

$res=mysql_query("select * from pais where cod_cont=".$q."",$con);

?>

<select>

<?php while($fila=mysql_fetch_array($res)){ ?>
<option><?php echo $fila[nombre]; ?></option>
<?php } ?>

</select>


Demo/Código fuente

53 comentarios:

  1. Esta muy bueno, gracias.

    Una duda, que pasa si necesito que el segundo haga lo mismo con un tercer y ultimo Select?

    ResponderEliminar
  2. Es realmente claro y muy útil, pero ahora me enfrento al problema de cargar, mediante este último select otro select y resulta que no carga scripts en la página cargada (la proc.php). Cargo los scripts en el archivo principal y si me funcionan pero no en el Internet Explorer, diantres!!1

    ResponderEliminar
  3. Yo tengo la misma duda y el mismo problema que ustedes quiero cargar un tercer select mediante el segundo, ademas como obtengo el valor de cada uno?? si este se carga en un div con un id y no con un name para poder mandar los datos mediante post o get

    ResponderEliminar
  4. El código con tres selects se puede descargar de aqui:

    https://github.com/jerrycode/selectajax

    ResponderEliminar
  5. buenas les agradezco ayuda....yo tengo 2select pero necesito imprimir un datos que depende de la opción seleccionada del 2do. select

    ResponderEliminar
  6. Saludos Jerry. Yo tengo algo como lo que has descrito arriba pero necesito guardar los datos seleccionados en una base de datos.
    La primera lista muestra las provincias y la segunda lista muestra las localidaddes de la provincia seleccionada.
    Ambas forman parte de un formulario para registrar un nuevo contacto y quiero guardar la opción seleccionada de ambas listas en una base de datos.
    Si puedes ponerte en contacto conmigo pino_bx88@hotmail.com y ya te pasaría el código para que lo veas tú mismo.

    Un saludo y muchas gracias

    ResponderEliminar
  7. se nombra como titulo proc.js y debería llamarse proc.php, por lo menos así está en los archivos de ejemplo, muchas gracias por su aporte.
    saludos.

    ResponderEliminar
  8. Yo tengo un problema, tengo los mismos archivos pero en diferentes carpetas y no funciona. Al ponerlos todos en el mismo lugar si me funciona, pero necesito aplicar arquitectura. Como podria hacer para arreglar este problema y dejarlos en diferentes carpetas funcionando.

    ResponderEliminar
  9. Lo que yo necesito es que envés de que me cargue en otro combobox necesito que me cargue en una tabla de mi formulario; los valores relacionados con el combobox seleccionado..
    Si alguien me puede ayudar o conoce una fuente.... por favor ayuda....

    ResponderEliminar
  10. Como guardo los datos del 2do o 3er combo a la BD... como esta en el div intente pero no le leyo.... cuando le agregue un name a los selects de los divs de los otros archivos igual

    ResponderEliminar
  11. Tengo varios select dependientes en un fromulario, las funciones ajax funcionan correctamente, el problema se presenta a la hora de enviar el formulario para que los datos se guarden en la BD. No se envia el valor de los select, aun teniendo asignados en valor id y name. Si alguien pudiera ayudar se lo agradezco mucho.

    ResponderEliminar
  12. Me paso lo mismo que Anonimo =S no puedo insertar, porque los datos del div no lo manda en el form =S

    ResponderEliminar
  13. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  14. Oye ¡¡¡Gracias!!! utilicé el código para tres select y funcionó sin problemas, fácil de entender y de modificar, uffff me salvaron la vida
    Gracias por su libre contribución al conocimiento :)

    ResponderEliminar
  15. Gracias jerry, me sacaste de un apuro, muy bien explicado :D

    ResponderEliminar
  16. Muchas gracias Jerry, fue de gran ayuda, solo que ahora no veo como recoger los valores seleccionados para guardarlos en la BD, ya que al parecer estan fuera del alcance, me podrías ayudar?

    ResponderEliminar
  17. Tengo el mismo problema! como tomo el value de los select?? Gracias!

    ResponderEliminar
  18. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  19. ¡¡¡RESUELTO!!!
    Estimados con un colega lo resolvimos de la siguiente forma:
    proc.php
    al select además del id le seteamos la propiedad "name" con el mismo atributo que el "id" es decir:
    select id="pais" name="pais"

    y en el index.php le pusimos el mismo nombre al div y agregamos el select para que aparezca desde el principio, quedando de la siguiente manera:

    < d iv id="pais"> < !--div donde aparecen los paises-->
    < s elect name="pais">
    < o ption value="">Seleccione
    (No olviden en la función de ajax arriba del index, cambiar el nombre "myDiv" por "pais" sino no les va a llamar al div por el onchange del otro select es decir:
    document.getElementById("pais").innerHTML=xmlhttp.responseText;)

    Luego para tomar los valores y persistir en la BD desde otro .php usamos la siguiente linea:
    $pais = $_REQUEST['pais'];

    Espero que les sirva, a nosotros nos funcionó.

    Saludos.

    ResponderEliminar
    Respuestas
    1. Crii serias tan hamable de enviar el codigo completo para revisarlo estoy apretando en esa seccion y lo necesito urgente te lo agradeceria mi correo es e.j.l.r@hotmail.com

      Eliminar
    2. Crii ya lo hice y no me funciona serias tan amable de ayudarnos, no me funciono no me carga el select pais si hago esos pasos pordrias mostrar como lo hace y ayudarnos.

      Eliminar
    3. Me ha servido demasiado, mira que estuve batallando bastante para guardar los datos, casualmente llegue a tu comentario, aplique lo que mencionas y funciono a la perfección, GRACIAS!.

      Eliminar
    4. Me ha servido demasiado, mira que estuve batallando bastante para guardar los datos, casualmente llegue a tu comentario, aplique lo que mencionas y funciono a la perfección, GRACIAS!.

      Eliminar
    5. De que manera puedo enviar los datos a traves de un formulario, el proceso con ajax , con el div.. no envia los datos del formulario para que puedan ser validados ... ????? como puedo asiganarle un name .. para que lo reconosca!!

      Eliminar
    6. Me podrías mandar los archivos completos de la forma que a ti te funcionó ... yo lo intenté de mil maneras pero no obtuve un resultado aceptable

      Eliminar
    7. jimmy_eduardo_@hotmail.com

      Eliminar
    8. Muy buena resolución, funciona excelente en mi aplicación.

      Eliminar
    9. Execelente, gran aporte. Funciona muy bien.

      Eliminar
    10. alguien pudo mandar el div en el form

      Eliminar
    11. Gracias camarada, se ve que el que hizo el post es un tonto que ni prueba lo sube pero tu si eres chingon Crii

      Eliminar
    12. si alguno lo tiene me lo pasa? me muestra el select de entrada pero lo manda en blanco - davidgrippo95@gmail.com-

      Eliminar
  20. Hola esta muy bueno el ejemplo, Funciona bien pero necesito insertar los datos en mi DB y no lo he logrado. Hice esto pero nada:

    ResponderEliminar
  21. Crii ya hice todo como dices pero no entendi muy bien lo del $pais = $_REQUEST['pais']; es decir "pais " ¿es la variable? ¿se debe definir la variable asi antes de enviar los datos?

    ResponderEliminar
  22. Muchísimas Gracias me sirvió de mucha ayuda gracias EXELENTE código y fácil de entender !!!!

    ResponderEliminar
  23. Muy bueno, me costo encontrar algo así y que fuese mas entendible. Hay algunos errores o detalles en el código para programadores novatos como yo, hay que agregar algunos (') apostrofes por allí y listo.

    ResponderEliminar
  24. Te pasaste lo mejor que pude encontrar en la web respecto de este tema, mil gracias

    ResponderEliminar
  25. que codigo mas malo !!

    ResponderEliminar
  26. Me sirvió el código para llenar los combos pero no lo puedo guardar en la base de datos.

    ResponderEliminar
  27. Amigo muy bueno el codigo de 3 select, pero tengo problemas para el de dos select el link creo que esta caido despues de addfly no carga nada más..

    ResponderEliminar
  28. donde coloco el $pais = $_REQUEST['pais'];

    ResponderEliminar
  29. Tengo una duda, Si quisiera enviar más variables por aquí:
    xmlhttp.send("q="+str);
    ¿Cómo se haría?

    ResponderEliminar
  30. muy buen aporte, yo ya pude cargar un select anidado, el problema que tengo es que en la misma pagina necesito cargar un segundo select anidado totalmente aparte de los dos primero, pero al registrar en la pagina el segundo archivo .js , el primero me deja de funcionar
    por favor si tienes alguna sugerencia te gradezco mi correo es wilsonsistem@hotmail.com

    ResponderEliminar
  31. Muy buen aporte me esta sirviendo de mucho pero
    Alguien me puede decir como hacer para que en vez de colocarlo en un div lo coloque en un input text

    ResponderEliminar
  32. Hola! yo tengo el mismo problema que el ultimo An ónimo que posteo, tengo 4 select que depende de otros 4 select totalmente aislados, es decir, cada select depende de otro select. El tema es que al cambiar cualquier linea de la funcion load, esta no funciona o bien trabaja unicamente con el primer select. Espero encontrar la solución. Gracias

    ResponderEliminar
  33. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  34. funciona el codigo para 3 select?..por mas que lo pongo y reviso.....no me funciona...a alguien le ha funcionado?

    gracias de de antemano

    ResponderEliminar
  35. buen aporte, así queda

    < s elect name="pais">
    < o ption value="">Seleccione


    ResponderEliminar
  36. Muy bueno, llevaba mucho tiempo buscando eso, muchas gracias muy buen aporte

    ResponderEliminar
  37. Muy buen aporte gracias, de pronto alguien podría explicarme como puedo obtener el valor del segundo select que sale de proc.php, y desde el index.php capturar todos los valores y guardarlos en mysql

    ResponderEliminar