Selects dependientes utilizando jQuery, Ajax y PHP

Hemos recibido muchas preguntas acerca de cómo desarrollar elementos selects dependientes con PHP. Para responder a dichas preguntas, vamos a explicar cómo implementar este tipo de elementos selects mediante jQuery, Ajax, PHP y MySQL.

Los elementos selects dependientes dinámicos se suelen utilizar para los desplegables de país y provincia. En este tutorial, vamos a implementar un desplegable para seleccionar un país, relacionado con otro desplegable para seleccionar una provincia. Es decir, cuando se seleccione un país en el desplegable, se cargarán las provincias de dicho país en el desplegable de provincia. Todos los datos los extraeremos mediante Ajax a través de un fichero PHP que consulta a nuestra base de datos MySQL.

Antes que nada, el desplegable para la selección de país debe contener todos los países. Cuando un país sea seleccionado, se extraeran sus respectivos estados de la base de datos y aparecerán en el desplegable de provincia. Al igual que cuando una provincia sea seleccionada, se extraerán todas sus respectivas ciudades de la base de datos MySQL y aparecerán en el desplegable de ciudad.

Base de datos y tablas

Crea una base de datos que contenga tres tablas: countries, states y cities. States estará relacionada con la tabla countries, y cities estará relacionada con la tabla states.

Tabla countries

Esta tabla albergará toda la información sobre los países.

CREATE TABLE IF NOT EXISTS `countries` (
  `country_id` int(11) NOT NULL,
  `country_name` varchar(30) CHARACTER SET utf8 NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0:Blocked, 1:Active'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Tabla states

Esta tabla albergará información sobre las provincias.

CREATE TABLE IF NOT EXISTS `states` (
  `state_id` int(11) NOT NULL,
  `state_name` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `country_id` int(11) NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0:Blocked, 1:Active'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Tabla cities

Esta tabla albergará información sobre las ciudades.

CREATE TABLE IF NOT EXISTS `cities` (
  `city_id` int(11) NOT NULL,
  `city_name` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `state_id` int(11) NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0:Blocked, 1:Active'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Archivo dbconfig.php

Este fichero conectará y seleccionará la base de datos.

<?php
//db details
$dbHost = 'localhost';
$dbUsername = 'root';
$dbPassword = '';
$dbName = 'location_db';

//Connect and select the database
$db = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);

if ($db->connect_error) {
    die("Connection failed: " . $db->connect_error);
}
?>

Fichero index.php

Este fichero contiene la librería jQuery, Javascript, HTML y el código PHP.

El siguiente código Javascript se utiliza para obtener la provincia y la ciudad del fichero ajaxData.php utilizando ajax. También muestra el HTML devuelto del fichero ajaxData.php al respectivo select.

<script src="jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $('#country').on('change',function(){
        var countryID = $(this).val();
        if(countryID){
            $.ajax({
                type:'POST',
                url:'ajaxData.php',
                data:'country_id='+countryID,
                success:function(html){
                    $('#state').html(html);
                    $('#city').html('<option value="">Select state first</option>'); 
                }
            }); 
        }else{
            $('#state').html('<option value="">Select country first</option>');
            $('#city').html('<option value="">Select state first</option>'); 
        }
    });
    
    $('#state').on('change',function(){
        var stateID = $(this).val();
        if(stateID){
            $.ajax({
                type:'POST',
                url:'ajaxData.php',
                data:'state_id='+stateID,
                success:function(html){
                    $('#city').html(html);
                }
            }); 
        }else{
            $('#city').html('<option value="">Select state first</option>'); 
        }
    });
});
</script>

Mediante PHP y HTML se muestra el select del país junto al de la provincia y la ciudad.

<?php
//Include database configuration file
include('dbConfig.php');

//Get all country data
$query = $db->query("SELECT * FROM countries WHERE status = 1 ORDER BY country_name ASC");

//Count total number of rows
$rowCount = $query->num_rows;
?>
<select name="country" id="country">
    <option value="">Select Country</option>
    <?php
    if($rowCount > 0){
        while($row = $query->fetch_assoc()){ 
            echo '<option value="'.$row['country_id'].'">'.$row['country_name'].'</option>';
        }
    }else{
        echo '<option value="">Country not available</option>';
    }
    ?>
</select>

<select name="state" id="state">
    <option value="">Select country first</option>
</select>

<select name="city" id="city">
    <option value="">Select state first</option>
</select>

Fichero ajaxDate.php

Este fichero es llamado por Ajax y sirve para obtener los datos de las provincias o de las ciudades de la base de datos.

<?php
//Include database configuration file
include('dbConfig.php');

if(isset($_POST["country_id"]) && !empty($_POST["country_id"])){
    //Get all state data
    $query = $db->query("SELECT * FROM states WHERE country_id = ".$_POST['country_id']." AND status = 1 ORDER BY state_name ASC");
    
    //Count total number of rows
    $rowCount = $query->num_rows;
    
    //Display states list
    if($rowCount > 0){
        echo '<option value="">Select state</option>';
        while($row = $query->fetch_assoc()){ 
            echo '<option value="'.$row['state_id'].'">'.$row['state_name'].'</option>';
        }
    }else{
        echo '<option value="">State not available</option>';
    }
}

if(isset($_POST["state_id"]) && !empty($_POST["state_id"])){
    //Get all city data
    $query = $db->query("SELECT * FROM cities WHERE state_id = ".$_POST['state_id']." AND status = 1 ORDER BY city_name ASC");
    
    //Count total number of rows
    $rowCount = $query->num_rows;
    
    //Display cities list
    if($rowCount > 0){
        echo '<option value="">Select city</option>';
        while($row = $query->fetch_assoc()){ 
            echo '<option value="'.$row['city_id'].'">'.$row['city_name'].'</option>';
        }
    }else{
        echo '<option value="">City not available</option>';
    }
}
?>

Fuente: codexworld.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP