SelectBox dependientes – ciudades y estados

Retomando los post sobre programación web en esta ocasión les comparto un rápido ejemplo sobre selectbox dependientes, mas concretamente el ejemplo de selectbox de ciudades y estados. Básicamente tenemos 2 selectbox, el primero contendrá los estados de la republica mexicana, cuando seleccionamos alguno el segundo selectbox contendrá ahora las ciudades de ese estado, para hacer esto necesitamos una pequeña base de datos con 2 tablas (ciudades y estados .. obvio), después algo de código php que se encargue de hacer la conexión y otro mas que nos devuelva los datos de las consultas vía JSON y por ultimo nuestro html y javascript que se encargara de mostrar el resultado.

Al terminar el tutorial tendremos algo que se vera así 🙂

Puedes descargar los archivos que se utilizara en la practica a continuación.

Comenzamos pues :).

Comenzamos creando el archivo que hará la conexión a la base de datos, yo acostumbro hacer una clase para eso ya que luego puedo hacer extends de la misma y todo es mas fácil.

<?
  global $ID_BD;
  $ID_BD=mysql_connect("127.0.0.1", "root","");
  mysql_select_db("states_cities", $ID_BD);
  mysql_query("SET NAMES 'utf8'", $ID_BD);  

class mysql {
VAR $ID;
function mysql (){

}
  function _query($sql){

  global $ID_BD;
   

    //echo "$sql\n";
      return mysql_query($sql,$ID_BD);
  }
  
  function _registers($sql){
  
  global $ID_BD;
    [email protected]_query($sql, $ID_BD);
    
    //echo $result;
    //echo $sql;
    if ($row=mysql_fetch_object($result)){
        do{
        
        $registros[]= $row;
        
        }while($row=mysql_fetch_object($result));
    }
    else
      return array();
    return $registros;
  }
  
  function _register ($sql){

  global $ID_BD;
    //echo "$sql";
      $result=mysql_query($sql, $ID_BD);
      if ($row=mysql_fetch_object($result))
        return  $row;
  }
  
  function _close(){
    mysql_close($this->ID);
  }
  
  function _last_id(){
    global $ID_BD;
      return  mysql_insert_id($ID_BD);
  }
}  

?>

Después creamos el archivo que se encargara de hacer las consultas y regresar el JSON correspondiente, realizaremos peticiones a este archivo via ajax por medio de jquery.

<?php
require_once 'mysql.php';

class data extends mysql
{
  function getStates()
  {
    $states = $this->_registers("SELECT * FROM states;");
    return json_encode($states);
  }

  function getCities($idState)
  {
    $idState = (int) $idState;
    $cities = $this->_registers("SELECT * FROM cities WHERE id_state = " . $idState . ";");
    return json_encode($cities);
  }
}

  $data = new data();
  if($_GET['action'] == "getStates")
  {
    echo $data->getStates();
  }
  else if($_GET['action'] == "getCities" && isset($_GET['stateID']))
  {
    echo $data->getCities($_GET['stateID']);
  }

?>

Como podemos ver he empaquetado el código en una clase y casi en la parte final del código reviso si existen algunos parámetros pasados por GET para mandar llamar a las funciones correspondientes :), examinemos por ejemplo la función que nos trae los estados:

  function getStates()
  {
    $states = $this->_registers("SELECT * FROM states;");
    return json_encode($states);
  }

Básicamente hacemos un select y el arreglo asociativo resultante (checar la clase mysql para mas información) lo pasamos por json_encode para ser manipulado con javascript, lo mismo pasa con la función que te arroja las ciudades solo que esa tiene una clausula WHERE que te manda traer solo las ciudades de X estado :).

Finalmente creamos nuestro archivo html donde desplegaremos los 2 selectbox, para eso escribimos el siguiente código.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>SelectBox dependientes</title>
    <script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script language="JavaScript">

    Object.size = function(obj) {
      var size = 0, key;
      for (key in obj) {
          if (obj.hasOwnProperty(key)) size++;
      }
      return size;
    };
    $(document).ready(function() {

      //$.ajax({
      $.ajax({
        url: 'data.php?action=getStates',
        dataType: 'json',
        success: function(data) {
          var size = Object.size(data);
          var items = "";
          for(var i = 0; i < size; i++)
          {
            items = items + '<option value="' + data[i].id_state + '">' + data[i].name + '</option>';
            //console.log(data[i].id_state + " : " + data[i].name);
          }  
          $('#states').append(items);
          $('#states').change();
        }
      });

     $('#states').change(function() {
      $.ajax({
        url: 'data.php?action=getCities&stateID=' + $('#states').val(),
        dataType: 'json',
        success: function(data) {
          var size = Object.size(data);
          var items = "";
          for(var i = 0; i < size; i++)
          {
            items = items + '<option value="' + data[i].id_state + '">' + data[i].name + '</option>';
            //console.log(data[i].id_state + " : " + data[i].name);
          }  
          $('#cities').html("");
          $('#cities').append(items);
          $('#cities').change();
        }
      });      
     });

    });      
    </script>
</head>
<body>

<a href="#">Selecciona un estado</a>
<br/>
<select id="states">
</select>
<br/>
<a href="#">Selecciona una ciudad</a>
<br/>
<select id="cities">
</select>
<br/>

<div id="map">
</div>

</body>
</html>

Como pueden ver, al inicio cargamos la librería de JQuery desde google, después hacemos la primera petición al script data.php via ajax para que nos traiga los estados y poder “rellenar el primer selectbox”, después tenemos el siguiente código javascript.

     $('#states').change(function() {
      $.ajax({
        url: 'data.php?action=getCities&stateID=' + $('#states').val(),
        dataType: 'json',
        success: function(data) {
          var size = Object.size(data);
          var items = "";
          for(var i = 0; i < size; i++)
          {
            items = items + '<option value="' + data[i].id_state + '">' + data[i].name + '</option>';
            //console.log(data[i].id_state + " : " + data[i].name);
          }  
          $('#cities').html("");
          $('#cities').append(items);
          $('#cities').change();
        }
      });      
     });


change() nos permite detectar el cambio de selección de un selectbox, entonces utilizamos ese evento para “refrescar” las opción del segundo selectbox, vemos cual es el estado que esta seleccionado, extraemos su valor (es el mismo id que le corresponde en la tabla de estados) y armamos la petición para mandar traer las ciudades :).

Y listo con esto tenemos listo un mini ejemplo de selectbox dependientes, espero les sirva este pequeño snippet :), ya saben cualquier duda pónganla en comentarios.

La verdad es un código bastante sencillo y fácil de implementar (unos 10 mins a lo mucho), con un poco mas de código se podría mostrar la ubicación de la ciudad en google maps o utilizar esto en algún formulario de registro o cualquier otra cosa.

salu2

Si te gusto comparte ...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

8 pensamientos en “SelectBox dependientes – ciudades y estados

  1. Fernando
    Google Chrome 23.0.1271.97 Windows 8

    Alevsk, gracias por tu post me sirvio mucho, tengo una pregunta ya seleccionado los campos como le puedo hacer para que ejecute una accion

    ej.
    Estado: Jalisco
    Ciudad: Zapopan
    Accion: que se valla a una liga en especifico o url

    Responder
  2. Alevsk Autor
    Google Chrome 23.0.1271.97 Windows 7

    Hola, gracias por visitar el sitio, se me ocurre que podrías agregar las url a la cual quieres redirigir el usuario en cada uno de los valores de los elementos options, algo así.

    <select id="dynamic_select">
        <option value="" selected>Pick a Website</option>
        <option value="http://www.google.com/">Google</option>
        <option value="http://www.youtube.com/">YouTube</option>
        <option value="http://www.stackoverflow.com/">Stack Overflow</option>
    </select>
    

    Entonces ya solo tienes que agregar un método que detecte el cambio en el select box de ciudades, tomar el valor y hacer un redirect, sencillo.

         $('#cities').change(function() {
               var url = $(this).val(); //obtenemos el valor actual del select box de ciudades
               window.location = url //redireccionamos a dicha url
         });
    

    Más informacion aca: http://stackoverflow.com/questions/5150363/onchange-open-url-via-select-jquery

    salu2

    Responder
  3. qzl
    Google Chrome 29.0.1547.66 Windows 8

    Se ve bastante interesante, apenas lo voy a hacer, pero me interesa iniciar la combinación de JSON y AJAX ya que no los he manejado, si conoces algún sitio donde se pueda encontrar mas practicas básicas, te agradeceria que me hicieras el favor de publicarlas para revisarlas.

    Responder
  4. Luis Luna
    Firefox 30.0 Windows 7

    Esta genial muchas gracias1!!!! eres la ley, solo que tengo un problema, mm me gustaria tener la base de datos que usaste pero la liga de descarga no funcina y donde se descarga el ejemplo completo no esta la bd. podrias pasarla por favor muchas gracias nuevamente

    Responder
  5. Luis Luna
    Firefox 30.0 Windows 7

    JAJAJA bueno amigo muchas gracias, consegui una base de datos de estados y municipio y se pudo adaptar a las necesidades de lo que necesitaba muchas gracias por el ejemplo mucho exito

    Responder
  6. José Castro
    Firefox 50.0 Windows 7

    Buenos días Alevsk, soy novato en esto de la programación, sin embargo deseo conocer la estructura de la base de dsatos que utilizaste para los estados y municipios, asimismo me puedes indicar una vez construída la base de datos en dónde debo colocarla? Me puedes proporcionar la base que utilizaste o al menos indicarme como debo construirla. Gracias por tu atención, saludos.

    Responder

Deja un comentario

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