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.
esta muy bueno esto, pero como pudiera aplicar esta variante en un formulario Modal bootstrap
De la misma forma pero dentro del body del modal
No es exactamente lo que busco pero tiene mucho merito lo bien explicado que queda. Felicitaciones.
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
Hola,
Una buena idea es utilizar Ajax con Json. Mira el siguiente artículo -> https://www.jose-aguilar.com/blog/ajax-vs-json-respuesta-multiple/
Saludos
¿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.
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 ?
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?
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
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 ?
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
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…
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
Hola, tengo un problema con las variables del ejemplo para adaptarlas a lo que necesito, ¿Me podrías indicar a qué corresponde cada una? 🙁
Hola buenos días,
Para este tipo de ayudas que se salen de lo que hay en el blog debe enviarnos un ticket con todos los detalles al centro de soporte y allí le indicaremos como podemos proceder:
https://www.jose-aguilar.com/soporte/
Saludos
Gracias excelente
Salados.
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.
Hola buenos días,
Para este tipo de ayudas que se salen de lo que hay en el blog debe enviarnos un ticket al centro de soporte y allí le indicaremos como podemos proceder:
https://www.jose-aguilar.com/soporte/
Saludos
ahhh ya entendi
https://www.jose-aguilar.com/soporte/
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.
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.
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!
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! 🙁
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 🙂
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
Todos los ejemplos pueden descargarse de https://www.jose-aguilar.com/scripts/jquery/combos_dependientes/combos_dependientes_todos.zip
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.
Hola que tal,
Para este tipo de ayudas que se salen de lo que hay disponible en el blog lo que podemos hacer es que nos envíes un correo a blog@jose-aguilar.com con todos los detalles para que revisemos como podemos proceder.
Saludos
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
¿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
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
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?
Jose Muy buen aporte! solo qusiera saber como podria lamacenar los datos seleccionados de esos combos en una tabla de base de datos???
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.
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.
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
Bueno sencillo adaptable…
Se agradece
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.
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.
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.
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
Gracias, ese es el problema, como indicarle al select el contenido de la variable para que aparezca seleccionado, en este caso «Bachiller».
un saludo
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.
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 ?
You’ve imressepd us all with that posting!
Hola,
Donde puedo descargar los códigos? O me lo envías por correo por favor.
Saludos y gracias.
MCampos
Hola,
El código está implícito en el tutorial. No hay descarga en este caso.
saludos
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);
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].'»,…)’;
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
‘;
}
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.
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.
Hola,
NO acabamos de entender la solicitud, nos podrías facilitar el ejemplo visual para verlo.
saludos
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
El botón lo puedes poner a continuación de los selects dentro de un formulario claro.
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
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
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 ?
Creo que debe ser un simple fallo al intentar conectar con la base de datos.
Wow! Perfecto! era justo lo que necesitaba…muchas gracias!
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
Gracias me sirvio de mucho para la construcción de mi sitio
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.
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.