Combos dependientes con jQuery, Ajax y PHP con base de datos

En este artículo vamos a implementar unos combos dependientes o selectores utilizando jQuery, Ajax, PHP y MySQLi con el objetivo principal de interactuar con una base de datos.

Este artículo va asociado a un artículo anterior en el que explicábamos como realizar combos dependientes con jQuery, Ajax y PHP.

En este caso queremos ampliarlo con un ejemplo de combos dependientes o selectores con jQuery, Ajax y PHP interactuando con los datos de una base de datos trabajando con MySQLi orientado a objetos.

En el ejemplo que vamos a ilustrar vamos  a jugar con una base de datos de una tienda de demostración que tenemos desarrollada con PrestaShop que utiliza su sistema de categorías para contemplar las marcas y modelos de los coches que se venden. Por lo tanto, vamos a tener un primer selector con las marcas (primer nivel de categorías) y un segundo selector será dinámico en función de lo que hayamos escogido en el primero para mostrar el modelo.

Para implementarlo lo primero que tendremos que considerar es la recogida de la información a depositar en el primer selector, en el cuerpo de la página o dentro del <body> añadiremos el formulario:

<form class="row" action="" method="post">
    <div class="form-group col-lg-3">
        <label for="category">Marca</label>
        <select name="category" id="category" class="form-control">
            <?php
            $conexion = new mysqli('localhost', DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
            $result = $conexion->query(
                "SELECT c.id_category, name FROM category c
                LEFT JOIN category_lang cl ON (cl.id_category = c.id_category AND cl.id_lang = 1)
                WHERE id_parent = 2 ORDER BY name ASC"
            );
            if ($result->num_rows > 0) {
                while ($row = $result->fetch_assoc()) {                
                    echo '<option value="'.$row['id_category'].'">'.$row['name'].'</option>';
                }
            }
            ?>
        </select>
    </div>
    <div class="form-group col-lg-3">
        <label for="subcategory">Modelo</label>
        <select name="subcategory" id="subcategory" class="form-control"></select>
    </div>
</form>

Tan solo estamos creando el formulario con 2 selectores. En el primero mostraremos las categorías principales que en el caso del ejemplo son las marcas. Estamos conectando con la base de datos y realizando una consulta para obtener las categorías principales ordenadas por nombre en formato ascendente. En el caso de que haya resultados, recorremos el array resultante para imprimir las opciones del selector de marcas.

También tenemos el selector de modelos presente en la página pero en este caso vacío para rellenarlo con la llamada Ajax según la categoría principal (marca) escogida.

(*) Recuerda cambiar las parámetros de conexión con la base de datos para hacerlo funcionar en tu sitio.

En la misma página tenemos que incorporar dentro de la etiqueta <head> la librería jQuery y el script necesario para capturar el evento:

<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script language="javascript">
$(document).ready(function(){
    $("#category").on('change', function () {
        $("#category option:selected").each(function () {
            var id_category = $(this).val();
            $.post("subcategories.php", { id_category: id_category }, function(data) {
                $("#subcategory").html(data);
            });			
        });
   });
});
</script>

En este caso, se está esperando a que se cambie un valor del selector de marcas para rellenar vía Ajax el segundo combo (modelos) condicionado con el valor elegido de la marca. El selector con identificador «subcategory» se rellenará de las opciones que retorna el archivo «subcategories.php».

El archivo «subcategories.php» retorna en formato html las opciones (modelos) de la marca seleccionada. Este archivo contiene:

<?php
$html = '';
$conexion = new mysqli('localhost', DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
 
$id_category = $_POST['id_category'];
 
$result = $conexion->query(
    "SELECT c.id_category, name FROM category c
    LEFT JOIN category_lang cl ON (cl.id_category = c.id_category AND cl.id_lang = 1)
    WHERE id_parent = ".$id_category." ORDER BY name ASC"
);
if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {                
        $html .= '<option value="'.$row['id_category'].'">'.$row['name'].'</option>';
    }
}
echo $html;
?>

Como puedes observar, conectamos de nuevo con la base de datos, capturamos el identificador de la categoría seleccionada, armamos la consulta que nos retorna un array de los hijos de la categoría seleccionada ordenadas por nombre en formato ascendente y retornamos las opciones del selector de modelos mediante un echo de la variable $html que hemos ido rellenando al recorrer el array de modelos.

Ver demo Descargar

Autor
Escrito por Jose Aguilar - Director ejecutivo y tecnológico en JA Modules. Experto programador PrestaShop y Experto programador WordPress.
Te ha servido? Valora esta entrada!
(18 votos, promedio: 5 de 5)
Comparte en las redes sociales
¿Buscas trabajo de programador?

64 respuestas a “Combos dependientes con jQuery, Ajax y PHP con base de datos”

  1. David dice:

    esta muy bueno esto, pero como pudiera aplicar esta variante en un formulario Modal bootstrap

  2. No es exactamente lo que busco pero tiene mucho merito lo bien explicado que queda. Felicitaciones.

  3. eli dice:

    Como se hace lo mismo pero, con los mismos datos de una tabla?
    por ejemplo:
    tabla cliente: seleccionar el id y que traiga los otros datos en otros input?
    saludos

  4. David dice:

    ¿y para hacer esto te es imprescindible usar jQuery?
    da pena ver que algunos sois incapaces de vivir sin el, pero mas pena vais a dar cuando todas las librerias abandonen esta imnecesaria libreria como ya hizo bootstrap, la cual nunca use pero ahora que abandona este basura se merecera una segunda oportunidad.
    Y para todos los demas! cuando querrais hacer un simple ajax ya sabeis, cargar jQuery en su version ampliada con miles de lineas por ahorrar 1 linea de nada.

  5. Cesar dice:

    Me ha funcionado de maravilla este codigo con la explicacion dada, una pregunta, como podria validar este tipo de combox que no vayan vacios antes del submit ?

  6. Janner dice:

    Hola, espero estés muy bien, gracias por tu script. Lo he usado para Países y estados y ha funcionado muy bien, pero no me funciona para un tercer combo para ciudades. ¿Que debería hacer en tal caso?

    • Jose Aguilar dice:

      Hola,

      Para contemplar 3 niveles quizá se debe pensar de otra forma. Si todavía necesitas ayuda, puedes enviar un ticket al centro de soporte técnico. Allí podremos revisar tu solicitud y darte una respuesta.

      Saludos

  7. raul dice:

    hola, te comento mi problema..
    mi archivo php, es un archivo donde tengo muchas funciones, la pregunta es, como mando a llamar a una función en especifico (donde tengo mi consulta sql) desde el script ?

    • Jose Aguilar dice:

      Hola, Deberás condicionar el código que deseas ejecutar. En la llamada Ajax pasar un parámetro más y tu archivo PHP hacer un if revisando si esa variable viene rellenada, saludos

  8. Andry dice:

    Hola, estoy Usando ajax y php para la carga de un select dependiente de otro… Funciona muy bien, pero al momento de enviar no pasa el valor del segundo select, probe con jquery y nada…

    • Jose Aguilar dice:

      Hola buenas tardes,

      Es un poco difícil darte una respuesta si no nos facilitas la url de tu ejemplo. Quizá de esta forma podamos ver en seguida que ocurre en tu sitio. Revisa también que el ajax retorne la información que deseas depositar en el segundo select.

      Saludos

  9. Coni dice:

    Hola, tengo un problema con las variables del ejemplo para adaptarlas a lo que necesito, ¿Me podrías indicar a qué corresponde cada una? 🙁

  10. Antonio dice:

    Gracias excelente

    Salados.

  11. Armando dice:

    Hola he visto tu ejemplo y da muchas ideas… ayudame como haria para en vez de que se active la lista de otro listbox aparesca un imput text o una tabla incluyendo un texto.

  12. Sebastian dice:

    en principio queria hacer andar el ejemplo asi ya que me pase 2 dias mas..tratando de acomodar este ejemplo con un datepicker,
    ajjaj es que asi no pude imaginate trayendo desde un Datepicker las fechas a seleccionar y mostrar.
    Por favor nada mas quiero que me digas si a vos te funciona asi como te puse arriba a ver si yo estoy loco o que.

  13. Sebastian dice:

    ESTO NO ANDA…NO SE PORQUE.,…..
    te pido que descargues tus propios archivos e intentalo hacerlo con una base de datos diferente , no me funciona.
    inclusive necesito hacerlo con una misma tabla no hay relacion

    evidentemente algo es que falta no se que le di MIL VUELTAS.
    por medio de xxamp acabo de probar, por medio de mi servidor de pago.

    utilizando el mismo ejemplo..no puedo traer una simple consulta.
    es increible, es que seguro no te has olvidado de agregar otro codigo de javascript que falte ?

    te explico el primer combo me trae la tabla…el segundo nunca llega a poder abrirse con datos.
    index_categories.php

    Combos dependientes

    $(document).ready(function(){
    $(«#category»).change(function () {
    $(«#category option:selected»).each(function () {
    id_category = $(this).val();
    $.post(«subcategories.php», { id_category: id_category }, function(data){
    $(«#subcategory»).html(data);
    });
    });
    })
    });

    Marca:
    query(«SELECT id, start, DATE_FORMAT(START , ‘%e-%c-%Y’ ) AS fecha FROM EVENTS GROUP BY START»);
    if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
    echo ».$row[‘fecha’].»;
    }
    }
    ?>

    Modelo:

    subcategories.php

    Combos dependientes

    $(document).ready(function(){
    $(«#category»).change(function () {
    $(«#category option:selected»).each(function () {
    id_category = $(this).val();
    $.post(«subcategories.php», { id_category: id_category }, function(data){
    $(«#subcategory»).html(data);
    });
    });
    })
    });

    Marca:
    query(«SELECT id, start, DATE_FORMAT(START , ‘%e-%c-%Y’ ) AS fecha FROM EVENTS GROUP BY START»);
    if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
    echo ».$row[‘fecha’].»;
    }
    }
    ?>

    Modelo:

    es mas para no errarle me he bajado hasta tu js del query pero ni eso.

    SQL
    la base de datos se llama contactos
    tabla events
    CREATE TABLE IF NOT EXISTS `events` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `start` datetime DEFAULT NULL,
    `end` datetime DEFAULT NULL,
    `title` text,
    `uid` int(4) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=70 ;


    — Volcado de datos para la tabla `events`

    INSERT INTO `events` (`id`, `start`, `end`, `title`, `uid`) VALUES
    (63, ‘2017-07-19 08:30:00’, ‘2017-07-19 09:00:00’, ‘t’, 0),
    (64, ‘2017-07-18 14:00:00’, ‘2017-07-18 14:30:00’, ‘t’, 0),
    (65, ‘2017-07-19 14:30:00’, ‘2017-07-19 15:00:00’, ‘t’, 0),
    (66, ‘2017-07-17 08:30:00’, ‘2017-07-17 09:00:00’, ‘t’, 0),
    (67, ‘2017-07-20 11:00:00’, ‘2017-07-20 11:30:00’, ‘t’, 0),
    (68, ‘2017-07-22 14:00:00’, ‘2017-07-22 14:30:00’, ‘t’, 0),
    (69, ‘2017-07-23 14:00:00’, ‘2017-07-23 14:30:00’, ‘t’, 0);

    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

    ————–
    por mas que este buscando en la misma tabla deberia de funcionar. si pues.

  14. cristian dice:

    Yo tengo una duda aunque no he intentado resolverla, si yo voy a realizar una consulta, como hago para que en el formulario se carguen los datos de los selects dependientes y estén seleccionados según su anterior, ejemplo, pais-estado! Se me ocurre realizar la consulta , cargar el formulario, hacer selelecte en de país que es estático, y al finalizar ejecutar la función de manera automática, pasar el país como parametro y cargar los datos del select dependiente! Debo probar, pero hay alguna otra idea sería de gran ayuda!

    • cristian dice:

      Olvide mencionar que el ejemplo que utilizo es sin conexión a BD, en un archivo PHP están todos los estados de los países, con la base de datos si lo se hacer :-(, y así no! 🙁

    • cristian dice:

      Me auto respondo, pues se me acaba de ocurrir que si el archivo PHP trae un echo de , en la consulta puedo traerlo con un incluye, y al valor que trae la consulta la asigno a una variable con el nombre de la variable del archivo PHP, y cuando compare el valor , deberá generar el echo dentro del selected 🙂

  15. Juan David Gomez valencia dice:

    buenos dias, sucede que no logro organizar el codigo a mi gusto, podrias enviar el codigo funcionando con la base de datos para poder saber con mas certeza sobre el uso del codigo

  16. german dice:

    Hola, podrías hacer un ejemplo y reemplazar la consulta por datos de una tabla mas sencilla. ya que en este ejemplo estas llamando a datos de dos tablas distintas.
    por ejemplo yo tengo una tabla de locales con columnas provincia y localidad y no logro hacer que el segundo select muestre el dato que guardaría en la variable html…
    gracias.

  17. Enrique Peña dice:

    Hola.
    como lleno los combos dependientes: categoria y subcategoria dependiento de un registro seleccionado de la base de datos para su modificacion?
    Ejemplo:
    Marca: FORD
    Modelo: Galaxy

    Muchas gracias por su ayuda

  18. Jose Ramos dice:

    ¿Podrías facilitar el código? O explicar un poquito mas como estan compuestas las columnas de tus tablas para tratar de entender el Query.

    Gracias

    • Jose Aguilar dice:

      Hola buenas tardes,

      Ten en cuenta que con el ejemplo estamos jugando con la tabla de categorías de una base de datos de una tienda PrestaShop. Si tienes una instalación de PrestaShop a mano puedes revisar las tablas ps_category y ps_category_lang.

      Saludos

      • Rodolfo Salas dice:

        Tengo un problema el cual consiste en que no se muestra en el navegador pero en la vista del código fuente esta y creo que es algún problema con el framework Materialize css. Alguien me puede ayudar?

  19. Diana dice:

    Jose Muy buen aporte! solo qusiera saber como podria lamacenar los datos seleccionados de esos combos en una tabla de base de datos???

  20. Diana dice:

    hola Jose! buen aporte me sirvio muchisimo! solo que la cuestion es que no me inserta nada en la base de datos :S podrias ayudarme???
    Gracias.

  21. rodrigo dice:

    hola! una consulta, necesito hacer que dependienta del valor seleccionado en el select me habilite o no un input. con base de datos, la tabla con la que se llena el select tiene los campos id, nombre, mostrar. en mostrar iria «si» o «no» para mostrar el input, dependiendo de ese valor es que me lo mostraria.

    • Jose Aguilar dice:

      Hola,

      Creo que tan solo debes cambiar la query y hacer algo así:

      «SELECT c.id_category, name FROM ps_category c
      LEFT JOIN ps_category_lang cl ON (cl.id_category = c.id_category AND cl.id_lang = 1)
      WHERE id_parent = 2 AND mostrar=»si» ORDER BY name ASC»

      Saludos

  22. Pablo dice:

    Bueno sencillo adaptable…

    Se agradece

  23. JoSE dice:

    Hola, gracias por el código pero tengo un problema circunstancial, uso el combo dependiente para una consulta, el problema es que cuando pulso el boton cosultar es decir envío el formulario el select dependiente se vuelve en blanco.

    espero puedan ayudarme con esto.

  24. Fernando dice:

    Hola, quiero añadir un nuevo selector, que sea dependiente del anterior.
    Entiendo que tengo que crear un segundo archivo para llenar el selector, por ejemplo subcategorias2.php y que tengo que añadirlo en la funcion javascript, pero no se como hacer esta segunda parte.
    No se bien tengo que añadir o modificar en esta parte del script:

    $(document).ready(function(){
    $(«#category»).change(function () {
    $(«#category option:selected»).each(function () {
    id_category = $(this).val();
    $.post(«subcategories.php», { id_category: id_category }, function(data){
    $(«#subcategory»).html(data);
    });
    });
    })
    });

    Muchas gracias por tu tiempo.

  25. MJMartin dice:

    Hola, como están?
    No encuentro la solución a este asunto, el entorno de trabajo es HTML, PHP y MySql.
    No soy novato en estos temas, como se puede apreciar.
    Tenemos una tabla en MySql con campos relacionados con personas, uno de ellos es «estudios», que en este caso contiene «Bachiller».
    Por otro lado tenemos un formulario para mostrar los datos de las personas que tenemos en la tabla, en dicho formulario hay un que muestro a continuación.
    Que tendría que hacer para que cuando mostramos los datos de la base de datos en el combobox, nos aparezca seleccionado el contenido del campo de la base de datos «estudios», contenido en $var_estudios, y en este caso, mostrar «Bachiller» seleccionado, siempre aparece la primera opción, «–Que estudios tienes–» .

    <select tabindex="3" name="estudios" id="estudios" value="»>
    –Que estudios tienes–
    Estudios primarios
    Formación Profesional
    Bachiller/option>
    Licenciado
    Otros

    Perdón por la extensión.
    Gracias por su tiempo.

    • Jose Aguilar dice:

      Hola, me parece que simplemente tienes que indicar que la opción de Bachiller esté seleccionada, algo asi:

      Espero que sea esta la solución,
      SAludos

      • MJMartin dice:

        Gracias, ese es el problema, como indicarle al select el contenido de la variable para que aparezca seleccionado, en este caso «Bachiller».
        un saludo

  26. J. G. Alonso dice:

    Hola Jose , tengo una duda , si quisieramos continuar las lista depentes en vez de solo haber dos , corrigeme si me equivoco , ¿ habria que crear un documento php por cada lista nueva? y ¿como tendria que cambiar la estructura del codigo javascript ? un saludo y gracias.

  27. jose Garrido dice:

    Hola Jose , tengo una duda , si quisieramos continuar las lista depentes en vez de solo haber dos , corrigeme si me equivoco , ¿ habria que crear un documento php por cada lista nueva? y ¿como tendria que cambiar la estructura del codigo javascript ?

  28. Mario Campos dice:

    Hola,

    Donde puedo descargar los códigos? O me lo envías por correo por favor.

    Saludos y gracias.

    MCampos

  29. carlos contreras dice:

    Por favor corrigeme
    $con=mysqli_connect(«localhost»,»usuario»,»contraseña»,»basedatos»);
    // Check connection
    if (mysqli_connect_errno())
    {
    echo «Failed to connect to MySQL: » . mysqli_connect_error();
    }

    $sql=»INSERT INTO tabla (Pais, Divisa, Porcentaje, Gold, Silver, Cambio, Paralelo, Peso)
    VALUES
    (‘$_POST[Pais]’,’$_POST[Divisa]’,’$_POST[Porcentaje]’,’$_POST[Gold]’,’$_POST[Silver]’,’$_POST[Cambio]’,’$_POST[Paralelo]’,’$_POST[Peso]’)»;

    if (!mysqli_query($con,$sql))
    {
    die(‘Error: ‘ . mysqli_error());
    }
    echo «»;

    mysqli_close($con);

    • Jose Aguilar dice:

      En el INSERT diría que hay un error de comillas simples y dobles en los datos tipo string. Creo que deberías hacerlo así:

      $sql=’INSERT INTO tabla (Pais, Divisa, Porcentaje, Gold, Silver, Cambio, Paralelo, Peso)
      VALUES
      («‘.$_POST[Pais].'»,…)’;

  30. carlos contreras dice:

    No logro insertar a mi base de datos. Por favor revisa mi código y corrígeme.

    Selecciona tu país:
    Argentina
    Bolivia
    Brasíl
    Chile
    Colombia
    Costa Rica
    Cuba
    Ecuador
    España
    Estados Unidos
    El Salvador
    Guatemala
    Haití
    Honduras
    México
    Nicaragua
    Panamá
    Paraguay
    Perú
    Puerto Rico
    Republica Dominicana
    Uruguay
    Venezuela

    Selecciona tu divisa:

    $rpta=»»;
    if ($_POST[«elegido»]==»Argentina») {
    $rpta= ‘
    <option value="PESOARS»>PESOARS
    ‘;
    }
    if ($_POST[«elegido»]==»Bolivia») {
    $rpta= ‘
    <option value="BOLIVIANOBOB»>BOLIVIANOBOB
    ‘;
    }
    if ($_POST[«elegido»]==»Brasil») {
    $rpta= ‘
    <option value="RealBRL»>RealBRL
    ‘;
    }

  31. Por mas que intento no logro hacer que funcione, me siento frustrado. Mi base de datos se llama basedatos y la tabla oro, tengo 3 columnas (pais/ciudad/codigo). Agradezco mucho si alguien pudiera ayudarme se lo agradezco mucho.

  32. Edwin Roi Casas Huamanta dice:

    Buenos días. Esta muy bueno el aporte. Soy nuevo en php y tengo en mi base de datos dos tablas relacionadas es la tabla ocupacion y la tabla persona.
    Al momento de registrar una persona tengo que cargar los datos de la tabla ocupación para registrarla. como lo hago desde el php. gracias amigo estare muy agradecido.

    • Jose Aguilar dice:

      Hola,

      NO acabamos de entender la solicitud, nos podrías facilitar el ejemplo visual para verlo.

      saludos

  33. daniela dice:

    hola tengo una pregunta:

    una ves el usuario selecciona las dos opciones donde iría el botón de enviar?

    o como se pondría tengo esa duda gracias

  34. Daniela dice:

    hola tengo una pregunta una vez el usuario selecciona los 2 campos donde se pone o como se pone el botón de enviar y como se haría mi código ya funciona pero tengo ese problema.

    Gracias

  35. Eddy dice:

    y si quisiera que ademas de ser dependientes se pueda agregar mas filas de esos y que sigan siendo dependientes…. es decir agregar otros 2 campos iguales…. algo asi como para agregar items a una factura

  36. ros dice:

    hola yo tengo un problema, cuando tengo mi aplicacion en forma local los combos me cargan perfectamente, pero al momento de cargar mi aplicacion en un hosting no funcionan los combos, a que se debe esto ?

  37. vero4travel dice:

    Wow! Perfecto! era justo lo que necesitaba…muchas gracias!

  38. Rocio dice:

    Buenos dias, queria hace una pregunta, he utilizado este script, y decir antes de nada que muchas gracias por el aporte, me va a la perfeccion, pero tengo el problema que para el entorno que stoy desarrollando hay pc que van a usarlo y tienen ie9, tras hacer piruetas para instalarme el ie9 y probar como funciona resulta que el combo no carga en ie9, alguna ocurrencia que pueda solucionarlo?

    Muchas gracias

  39. Bryan Tejeda dice:

    Gracias me sirvio de mucho para la construcción de mi sitio

  40. pedro dice:

    hola, gracias por el script, pero no me funciono, me podrás enviar el código original en un archivo comprimido para poder revisar completa la sintaxis.

    desde ya muchas gracias.

  41. Javier Rodriguez dice:

    Muchas gracias por tus scripts. La verdad me hacen mucha falta. pero no entiendo todas las lineas en el mismo subcategories.php
    o van en archivos separados.
    Tendrias el ejemplo para bajar o me lo podrias enviar.
    Desde ya muchas gracias.
    Sos un genio.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ver más sobre