Select dependientes con Ajax jQuery, PHP, vamos a explicar paso a paso como crear select dependientes con ajax, usando jquery y php. Los select dependientes se refieren que un select de un formulario depende del anterior select para mostrar unos u otras opciones.
Para crear nuestra Base de datos ejecutamos el siguiente script para que nos sirva de ejemplo.
CREATE TABLE IF NOT EXISTS `zd_city` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idprovince` int(11) NOT NULL,
`name` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=20 ;
INSERT INTO `zd_city` (`id`, `idprovince`, `name`) VALUES
(1, 1, 'Ciuda 1'),
(2, 1, 'Ciudad 2'),
(3, 2, 'Calamuchita'),
(4, 2, 'Cordoda Centro'),
(5, 3, 'Berazategui'),
(6, 3, 'Quilmes'),
(7, 4, 'Rosario'),
(8, 5, 'Oran'),
(9, 5, 'Aguas Blancas'),
(10, 6, 'Tierra de fuego'),
(11, 7, 'El Alto'),
(12, 7, 'Viacha'),
(13, 8, 'Padcoyo'),
(14, 8, 'Camargo'),
(15, 9, 'Bermejo'),
(16, 9, 'Yacuiba'),
(17, 10, 'Chapare'),
(18, 11, 'Centro Madrid'),
(19, 12, 'Catalunia');
CREATE TABLE IF NOT EXISTS `zd_country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;
INSERT INTO `zd_country` (`id`, `name`) VALUES
(1, 'Zambia'),
(2, 'Argentina'),
(3, 'Bolivia'),
(4, 'España');
CREATE TABLE IF NOT EXISTS `zd_province` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idcountry` int(11) NOT NULL,
`name` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=13 ;
INSERT INTO `zd_province` (`id`, `idcountry`, `name`) VALUES
(1, 1, 'Zuleman'),
(2, 2, 'Cordoba'),
(3, 2, 'Buenos Aires'),
(4, 2, 'Santa Fé'),
(5, 2, 'Salta'),
(6, 2, 'Santa Cruz'),
(7, 3, 'La Paz'),
(8, 3, 'Sucre'),
(9, 3, 'Tarija'),
(10, 3, 'Cochabamba'),
(11, 4, 'Madrid'),
(12, 4, 'Barcelona');
Creamos el archivo de conexion a la Base de Datos.
configuracion.inc.php
//por Abrahan Apaza
$bd_host = “localhost”; // nombre del servidor
$bd_usuario = “root”; //username de la BD
$bd_pwd = “”; // password de la BD
$bd_nombre = “zoedev_demos”; // nombre de la BD
function conectar($host, $username, $pass, $bd) {
$link = mysql_connect($host, $username, $pass);
if ($link) {
if (!mysql_select_db($bd, $link)) {
echo “No se pudo establecer la conexion a la Base de Datos $bd, revise los datos de conexion”;
}
} else {
echo “No se pudo completar la conexion al servidor $servidor, revise los datos de conexion”;
}
return $link;
}
El archivo index.php de donde llamaremos y mostraremos nuestro ejemplo.
index.php
Select Dependiente jQuery Ajax
El archivo javascript que va a realizar la petición al servidor mediante ajax y jquery lo haremos en un archivo separado para que nuestro código sea un poco mas ordenado.
procesar.js
$(function() {
$(“#provincias,#ciudad”).attr(‘disabled’, true);
function ejecutar(obj1, obj2, task) {
$(‘’, {
‘class’: ‘loading’,
src: ‘loading.gif’,
‘style’: ‘display:inline’
}).insertAfter(obj1);
$.ajax({
type: “POST”,
url: “action.php”,
dataType: “html”,
data: “task=” + task + “&id=” + $(obj1).val(),
success: function(msg) {
$(obj1).next(‘img’).remove();
$(obj2).html(msg).attr(“disabled”, false);
},
error: function(jqXHR, textStatus, errorThrown) {
$(obg1).next(‘img’).remove();
alert(“Error al ejecutar => ” + textStatus + ” – ” + errorThrown);
}
});
}
$(“#pais”).change(function(e) {
$(“#ciudad,#provincias”).attr(‘disabled’, true);
if ($(this).val().trim() != “”) {
ejecutar($(this), $(“#provincias”), “getprovincias”);
}
});
$(“#provincias”).change(function(e) {
$(“#ciudad”).attr(‘disabled’, true);
if ($(this).val().trim() != “”) {
ejecutar($(this), $(“#ciudad”), “getciudades”);
}
});
});
El archivo php que va a responder a nuestra petición es el siguiente.
El archivo recibe como parámetro la tarea a realizar y esto luego se encarga de llamar a la función correspondiente.
action.php
//por Abrahan Apaza
include(“configuracion.inc.php”);
$link = conectar($bd_host, $bd_usuario, $bd_pwd, $bd_nombre);
function getProvincias() {
global $link;
$query = “select * from zd_province where idcountry=”.$_POST[‘id’];
mysql_query(‘SET NAMES ‘
utf8 ”);
$result = mysql_query($query, $link);
$resp = “-Seleccione Provincia-”;
while ($value = mysql_fetch_object($result)) {
$resp. = “ id.
“‘>”.$value – > name.
“”;
}
echo $resp;
}
function getCiudades() {
global $link;
$query = “select * from zd_city where idprovince=”.$_POST[‘id’];
mysql_query(‘SET NAMES ‘
utf8 ”);
$result = mysql_query($query, $link);
$resp = “-Seleccione Ciudad-”;
while ($value = mysql_fetch_object($result)) {
$resp. = “ id.
“‘>”.$value – > name.
“”;
}
echo $resp;
}
if ($_POST) {
switch ($_POST[“task”]) {
case “getprovincias”:
getProvincias();
break;
case “getciudades”:
getCiudades();
break;
}
}
EDITADO
Para los que me mandaron mail preguntando como se podria agregar otro nivel mas, aqui va:
Agregar
en index.php
en procesar.js
$(“#ciudad”).change(function(e) {
$(“#barrio”).attr(‘disabled’, true);
if ($(this).val().trim() != “”) {
ejecutar($(this), $(“#barrio”), “getbarrios”);
}
});
});
en action.php
function getBarrios() {
global $link;
$query = “select * from zd_barrio where idbarrio=”.$_POST[‘id’];
mysql_query(‘SET NAMES ‘
utf8 ”);
$result = mysql_query($query, $link);
$resp = “-Seleccione Barrio-“;
while ($value = mysql_fetch_object($result)) {
$resp. = “”.$value – > name.
“”;
}
echo $resp;
}
…..
case “getbarrios”: getBarrios();
break;
Agregado al post mas opciones.
muy bueno
el mismo ejemplo si todo los datos estan en una sola tabla ( pais, provincia, ciudad con sus respectivos id y nombre )
Gracias te o agradezco mucho, saludos.
AMIGO gracias por tu codigo.
Tengo una pregunta: si quiero hacer un encadenamiento entre el valor del primer select y el segundo es decir que cuando yo seleccione el segundo. estos dos valores se envien y se consulten en un query:
select1: id=1
select 2: caracteristica=”rojo”
para que el tercer select despues de un query con esos dos datos me muestre opciones disponibles que cumpla con los dos anteriores valores
select3: objeto=”smartphone”
Hola, para eso al ejecutar el segundo select, tendrias que enviar también el dato del primer select, en el archivo procesar.js tendrias que modificar la function ejecutar(obj1,obj2, task,obj3){
obj3 = obj3 || NULL;
}
donde el obj3 seria opcional asi no afectas el funcionamiento del resto. El id o el valor del obj3 se enviaria solo cuando sea necesario.
slds
Muchas gracias amigo,
ya que son 7 selects hice asi:
function ejecutar(obj1,obj2,task,array)
y llame asi:
ejecutar($(this),$(“#ciudad”),”getciudades”,[n14]);
Una consulta: Existe un forma de asignarle los valores a cada select. Me refiero si tengo el valor del option. ¿Cómo puedo dejarlo en selected? esto al cargar el formulario, ya asignarle los valores a cada uno.
Hola Alex
Para asignarle o que quede seleccionado haria algo asi.
Por ejemplo en action.php y getProvincias()
Tengo una pregunta: si quiero hacer un encadenamiento entre el valor del primer select y el segundo es decir que cuando yo seleccione el segundo. estos dos valores se envien y se consulten en un query:
select1: id=1
select 2: caracteristica=”rojo”
para que el tercer select despues de un query con esos dos datos me muestre opciones disponibles que cumpla con los dos anteriores valores
select3: objeto=”smartphone”
ME PODRIAS AYUDAR TENGO ESTE PROBLEMA CUAL SERIA EL CODIGO
GRACIAS
Hola
En este caso tendrias que crear otra funcion por ejemplo getSmartphone();
mas o menos asi, obviamente del lado del servidor tendras que crear una funcion que procese con esos 2 datos enviados y devolver.
slds
amigo una pregunta como es el script para el efecto de loading
muchas gracias…..
el loading es un simple si es que te refieres a eso, sino mas detalle a q te refieres.
slds
con este codigo tu hace ese fecto de loading pero si puede explicar un poco este codigo te lo agradecería
$(‘<img/>’, {
‘class’: ‘loading’,
src: ‘loading.gif’,
‘style’: ‘display:inline’
}).insertAfter(obj1);
y otra pregunta yo estoy tratando de de adaptar este codigo en vez de dos select depediente. a un select depediente a un texbox. me explico con la entrada de dato de un texbox carge el select con una consulta mysql si tiene una idea como podria hacerlo muchas gracias… slds
$(‘‘,….. genera una imagen que se agrega despues del obj1, obj1 puede ser un select, input:text o cualquier elemento que se envié a la función.
Ahora si quieres que cargue datos a un select a partir de un dato que se introduzca a un textbox, podria hacerlo con un evento en el textbox o con un boton que haga request y cargue los datos a un select
amigo gracias el codigo funciona perfecto !!pero tengo un problema cuando trato de hacer la consulta ejemplo:
$query = “select * from zd_city where idprovince=”.$_POST[‘id’];
en mi caso
no me pasa el valor .$_POST[‘id’] del textbox . con que quiero hacer la consulta no se que estoy haciendo algo mal gracias….
Asegurate en esta linea data: “task=” + task + “&id=” + $(obj1).val(), que este yendo bien los datos por las dudas podrias setear un valor estatico para probar que van los datos.
slds
Buenas tardes, primero queria agradecer por el aporte y quisiera saber si alquien me puede pasar este ejemplo funcionando por favor mil gracias.
buenas tardes no consigo que funcione, selecciono el pais pero no me trae las segundas opciones, lo copie tal cual
Fijate en la consola de tu navegador que error te esta dando para que puedas fixear.
Buenas tarde gracias por el aporte el codigo me funciona pero tengo un problema que no me cargan los datos en el select ??
Asegurate q tu conexión a BD sea la correcta, quiza no conecto x eso no te trae datos, otra cosa que podes hacer es en la consola de tu navegador que error te muestra.
si tengo retorno de respuesta pero no llena el option!
Elvis, este sencillo ejemplo te puede ayudar
https://youtu.be/GYCMkX7Z9rg
este es mi codigo php
function getmodelos() {
$model_ids=$_POST[‘marca_id’];
$resultado = intval(preg_replace(‘/[^0-9]+/’, ”, $model_ids), 10);
$mdlo = ModeloData::getModel($resultado);
$resp = “-Seleccione-“;
foreach($mdlo as $dl) {
$resp.= “modelo_id.”‘>”.$dl->modelo_nombre.””;
}
echo $resp;
}
if ($_POST) {
switch ($_POST[“task”]) {
case “getmodelos”:
getmodelos();
break;
}
}
Optengo los datos en la consola de chrome pero no me lo carga en el select
Hola, como andas?
Te comento estoy muy muy muy hasta las bolas en la facu y no encuentro un ejemplo que funcione bien de 3 combos anidados. Tome el que subiste vos, hice los cambios pero me carga solo el primero, me deja elegir y queda el gif cargando de loading pero no se carga el segundo por ende no puedo pasar al tercero.
Tengo asi procesar.js:
$(function() {
$(“#provincias,#ciudad”).attr(‘disabled’, true);
function ejecutar(obj1, obj2, task) {
$(”, {
‘class’: ‘loading’,
src: ‘loading.gif’,
‘style’: ‘display:inline’
}).insertAfter(obj1);
$.ajax({
type: “POST”,
url: “action.php”,
dataType: “html”,
data: “task=” + task + “&id=” + $(obj1).val(),
success: function(msg) {
$(obj1).next(‘img’).remove();
$(obj2).html(msg).attr(“disabled”, false);
},
error: function(jqXHR, textStatus, errorThrown) {
$(obg1).next(‘img’).remove();
alert(“Error al ejecutar => ” + textStatus + ” – ” + errorThrown);
}
});
}
$(“#pais”).change(function(e) {
$(“#ciudad,#provincias”).attr(‘disabled’, true);
if ($(this).val().trim() != “”) {
ejecutar($(this), $(“#provincias”), “getprovincias”);
}
});
$(“#provincias”).change(function(e) {
$(“#ciudad”).attr(‘disabled’, true);
if ($(this).val().trim() != “”) {
ejecutar($(this), $(“#ciudad”), “getciudades”);
}
});
});
Y asi action:
//por Abrahan Apaza
include(“configuracion.inc.php”);
$link = conectar($bd_host, $bd_usuario, $bd_pwd, $bd_nombre);
function getProvincias() {
global $link;
$query = “select * from zd_province where idcountry=”.$_POST[‘id’];
mysql_query(“SET NAMES utf8”);
$result = mysql_query($query, $link);
$resp = “-Seleccione Provincia-“;
while ($value = mysql_fetch_object($result)) {
$resp. = ” id.
“”>”.$value – > name.
“;
}
echo $resp;
}
function getCiudades() {
global $link;
$query = “select * from zd_city where idprovince=”.$_POST[‘id’];
mysql_query(“SET NAMES utf8”);
$result = mysql_query($query, $link);
$resp = “-Seleccione Ciudad-“;
while ($value = mysql_fetch_object($result)) {
$resp. = ” id.
“>”.$value – > name.
“;
}
echo $resp;
}
if ($_POST) {
switch ($_POST[“task”]) {
case “getprovincias”:
getProvincias();
break;
case “getciudades”:
getCiudades();
break;
}
}
Me das una mano en que falle? Al copiar tu codigo me viene con caracteres cambiados asi que los cambie a todos (calculo) agradeceria mucho tu ayuda.
Hola! Tu post me sirvió mucho, muchas gracias!
Solo una consulta más:
Necesito que de acuerdo a un select, se completen campos input.
No logro hacerlo.
Alguna sugerencia?
Muchas gracias!
Hola, por ejemplo en procesar.js despues de la linea 36 podria llamar a otra funcion.
ejemplo.
getText($(this));
y en la funcion
function getText(el) {
$(‘miinput’).val(el.text());
}
slds
Perdón, pero no puedo lograrlo. Te pido ayuda porque mis intentos ya son vamos.
Tal vez lo puedas ver más facilmente y rápido que yo.
Te lo agradezco mucho!
Mi código actual es el siguiente y debo tomar para incluir en un input llamado “Direccion”.
$(function() {
$(“#sucursales,#internos”).attr(‘disabled’, true);
function ejecutar(obj1, obj2, task) {
$(”, {
‘class’: ‘loading’,
src: ‘images/ajax-loader.gif’,
‘style’: ‘display:inline’
}).insertAfter(obj1);
$.ajax({
type: “POST”,
url: “actioncombos.php”,
dataType: “html”,
data: “task=” + task + “&id=” + $(obj1).val(),
success: function(msg) {
$(obj1).next(‘img’).remove();
$(obj2).html(msg).attr(“disabled”, false);
},
error: function(jqXHR, textStatus, errorThrown) {
$(obj1).next(‘img’).remove();
alert(“Error al ejecutar => ” + textStatus + ” – ” + errorThrown);
}
});
}
$(“#clientes”).change(function(e) {
$(“#internos,#sucursales”).attr(‘disabled’, true);
if ($(this).val().trim() != “”) {
ejecutar($(this), $(“#sucursales”), “getSucursales”);
}
});
$(“#sucursales”).change(function(e) {
$(“#internos”).attr(‘disabled’, true);
if ($(this).val().trim() != “”) {
ejecutar($(this), $(“#internos”), “getInternos”);
}
});
});