Selector combo dinámico en Ajax: localidades y provincias de España

En diversos proyectos he tenido la necesidad de trabajar con un formulario en el que uno de los campos es un selector de provincias y localidades de España. Tal vez usted también haya tenido esta misma necesidad durante el desarrollo de un proyecto.

En un enfoque tradicional sería necesario cargar en memoria todas las provincias y localidades, o dividir el proceso en dos fases: en la primera el usuario elegiría su provincia para luego seleccionar su localidad en un segundo paso. Un ejemplo de este enfoque tradicional es la web de páginas amarillas. Observe que el tiempo de carga de la página es considerablemente elevado.

Las nuevas técnicas de desarrollo web 2.0 nos ofrecen ahora la posibilidad de resolver este tipo de  funcionalidades de una manera mucho más elegante y eficiente.

Ejemplo de combo dinámico en Ajax 

Combo de localidades

En un enfoque 2.0 he desarrollado este ejemplo en el que puede ver un  formulario que permite al usuario seleccionar su localidad de manera muy rápida y eficiente. Ajax nos permite  trabajar con un documento XML de más de 2Mb que contiene todas las localidades de España, cargando en memoria únicamente la información que necesitemos en cada momento.

En el siguiente esquema se explica el funcionamiento de la aplicación Ajax:

Arquitectura de la aplicación provincias y localidades en Ajax

Esta funcionalidad consta de los siguientes archivos:

  • default.php: página incial dónde se generan dinámicamente el combo de provincias a partir del XML general.
  • xml_data_provider.php: recorre el XML general y devuelve otro XML que contiene sólo las localidades de la provincia escogida.
  • AjaxCode.js:  funcionalidad Ajax que lee el XML con las localidades elegidas y crea dinámicamente el combo de localidades.
  • provinciasypoblaciones.xml: Archivo XML que contiene todas las localidades y provincias de España.

Esta misma funcionalidad puede utilizarla para manejar cualquier XML de gran tamaño que de otra forma se mostraría inmanejable y ralentizaría mucho el tiempo de carga de su Site: fichas de clientes, un catalogo de productos, etc.

El tiempo de carga de una página y el consiguiente tiempo de espera de un usuario es uno de los factores más importantes en el rendimiento de una web. Tal y como se desprende del estudio sobre usabilidad realizado por Peter Sevcik en Julio de 2002, el tiempo de carga de una página no debe dilatarse más de 10 segundos para mantener el nivel de satisfación del usuario dentro de los límites óptimos. A partir de este límite el usuario empieza a percibir que la página está tardando en cargar y cuando se rebasa los 40 segundos la fustración y pérdida de interes del usuario por la página aumenta de manera muy acusada.

El código.

En el siguiente archivo zip dispone de todos los ficheros y recursos que conforman la aplicación. Siéntase libre de utilizarlo en su página web. Si le resultó de utilidad  o encontró cualquier problema le agradecería mucho conocer su feedback.

86 thoughts on “Selector combo dinámico en Ajax: localidades y provincias de España”

  1. Pingback: meneame.net
  2. Pingback: www.enchilame.com
  3. alguien tendra alguno con las ciudades del mundo?
    se que es mucho pedir, pero necesitaré un para vuelos de todas las principales ciudades que tienen aeropuerto del mundo.
    gracias
    Driss

  4. Hola.

    Un xml con todas las ciudades del mundo, seguro que puedes conseguirlo. Otra cuestión es, si gratuitamente…

    En cualquier caso prueba a buscar «XML DATA REPOSITORY» en Google, verás que existen montones de documentos XML en la red. Casí seguro que encontrarás lo que buscas.

    Un saludo.

  5. Me ha encantado el artículo y el código facilitado. Te lo agradezco mucho, sirve de verdadera ayuda a mucha gente.

    En cuanto a que si es para PHP5, o si se podría hacer con otras bases de datos (ciudades del mundo…). Que lo haga cada uno a partir de lo que aquí se cede. Ignacio ha dejado una muy buena base, pero no puede solucionar el problema concreto de cada uno de principio a fin.

    Muchas gracias. Un saludo.

  6. Hola Antonio,

    Efectivamente mi idea es que este código puede servir de base para que cualquiera pueda realizar un desarrollo más personalizado.

    Muchas gracias por tu comentario.

  7. Hola muy interesante pero una pregunta como lleno un combo con la informacion de una tabla catalogo (soy nuevo en esto)
    agradecere mucho la ayuda ya que pues si quiero y necesito aprender gracias

  8. Muy buen material. Gracias al autor… Con ganas de modificarlo para Argentina. Si hay alguien que busca lo mismo me avisa (cittadini@gmail.com), hoy voy a estar modificandolo.
    Gracias.
    Leandro.-

  9. Muy buen articulo gracias….Tengo una pregunta haber si alguien me puede ayudar: como lo puedo hacer para sacar los datos de una tabla en una base de datos?…Gracias.

  10. El articulo es muy bueno, gracias.

    Acabo de visitar tu web por primera vez y me parece muy interesante con mucho contenido muy útil.

  11. Ignacio gracias por el articulo, tengo una consulta a ver si me puedes echar una manito…O cualquier usuario que pueda, se agradese. ¿Como lo hago al elegir en el segundo select (localidad) que me de una pequeña descripcion de la localidad elegida?como tomo ese valor elegido por el usuario en el onChange. Uta se agradese Mil…

  12. No tengo bien concreta la idea de hacer uno con 3 combos (Departamento,Provinvia,distrito)si alguien podria brindarme alguna idea de como hacerlo

  13. Hola..

    Quiero leer un XML dinamico generado con php y cuando pongo el archivo php como parametro en la funcion simplexml_load_file en el archivo xml_provider no me salen los datos del segundo combo, se queda en blanco, comparo el archivo xml con la salida del php y me da el mismo formato, asi que no se cual sea el problema

    de antemano gracias

  14. Hola Josue.

    Comprueba que el Content-Type de los datos devueltos por el php sea text/xml. Si el XML está correctamente formado y su formato es el apropiado, el error puede estar relacionado con el Content-Type.

    Un saludo.

  15. Ajax es compatible con todas laa versiones de php, pero en este ejemplo necesitas la última versión de php para utilizar el componente para manejar los XML.

    Un saludo.

  16. Muy bueno el post.. tarde lo descubro. Ya utilizaba algo para esto y te encontre buscando una base de datos que necesito de
    provincias > localidades > distritos

    Igualmente aproveche para publicar tu link en los rss del maug.

    Salu2 y Éxitos

  17. realmente excelente, he aprendido mucho.

    ahora he tenido problemas con los caracteres especiales, como por ejemplo los acentos, ya que al cargarme la lista estan mal escritos, no se bien que puede ser aunque supongo que tiene algo que ver con la conversion de UTF-8 a ISO que realiza en el js, las preguntas serian es muy complicado de solucionar? que deberia cambiar?.

  18. Hola Alan.

    El problema que comentas es muy frecuente en los desarrollos Ajax en castellano y se soluciona trabajando con documentos con codificación UTF-8. Aunque así dicho puede parecer simple, lo cierto es que en la práctica puede ser bastante desesperante, puedes consultar aquí algunos ejemplos que te pueden ser de ayuda:

    http://www.tufuncion.com/acentos-ajax

    http://www.webadictos.com.mx/2007/11/07/tip-para-solucionar-problema-con-acentos-al-utilizar-ajax/

    Suerte.

  19. Muy bueno, pero acabo de probarlo y algunas de las ciudades no me salen. Solo pone el id y no puedo acceder a las poblaciones. Sabe alguien porque peude ser? lo estoy probando con php5.

  20. [quote comment=»740″]No tengo bien concreta la idea de hacer uno con 3 combos (Departamento,Provinvia,distrito)si alguien podria brindarme alguna idea de como hacerlo[/quote]

    Yo necesitaría algo asi, ya que lo estoy intentado, pero no me funciona. ¿Se podría hacer esto? con 3 combos 4 o más ^^

    Gracias.

  21. Solo un comentario… probé el link de página amarillas y lo deben haber mejorado desde que lo miraste… va aun más rápido que el tuyo 😛

  22. Ja! Pues es cierto que funciona más rápido que el mio, pero he revisado el código y siguen metiendo toda la info en arrays js.

    Puedes comprobarlo por ti mismo: http://callejero.paginasamarillas.es/javascript/proyectos.js

    Esto explica que sea más rápido, evitan tener que hacer una consulta al servidor cada vez que el usuario haga una petición, sin embargo, utilizar arrays para este tipo de funcionalidades es un mecanismo un tanto arcaico que implica problemas de mantenimiento, escalabilidad, accesibilidad, etc…

    Yo apuesto por AJAX para estos temas.

  23. Hola ! Quisiera usar tu código pero tengo que usarlo dentro de una pagina que no PHP es JSTL. Como puedo hacerlo?

    Muchas gracias!

  24. Hola JuanMa, el código cliente es el mismo independientemente del lenguaje de servidor que utilices. Ahora bien sería necesario que tradujeras a JSTL o JSP el código que se encarga de recorrer el árbol XML y devolver la información al cliente. Ten en cuenta que AJAX es compatible con cualquier tecnología servidor.

  25. No me explique bien jaja!, yo tengo PHP en mi servidor de aplicaciones, pero el código que da los select, como en el ejemplo de «DEFAULT.php» es:

    xpath(«/lista/provincia/nombre | /lista/provincia/@id»);
    for ($i=0;$i<count($result);$i+=2)
    {
    $e=$i+1;
    $provincia=UTF8_DECODE($result[$e]);
    echo(«$provincia»);
    }
    ?>

    El problema es que como estoy usando una página JSTL no puedo usar ése código. Como puedo hacer?

  26. holas, me a sido muy util tu ejemplo, estoy armando una base de datos (Pais / ciudad / Provincia) de america… si alguien desea la BD (XML) me avisa, ando en busca de los demas paises.
    saludos y grax.

  27. hola a

    ese ejemplo de los combos es presiamente lo que nesesito

    pero en JSP

    no se si alguien me puede dar una idea o pazar el codigo,

    el codigo que tengo solo me funciona en firefox y en IE7 no funciona

  28. excelente,
    pero, alguien ha hecho que, en vez de consultar un xml, la consulta sea sobre una tabla de una base de datos?
    estoy por modificar este codigo, pero si alguien ya lo hizo, sera bueno compartirlo. saludos

  29. Necesitaría sacar la información de una base de datos MySql para llenar los Select, alguien tendrá modificado el código para tal fin???
    Desde ya muchas gracias.
    Saludos.
    Mauricio.

  30. Necesito que me carguen más combos. Tengo pais, ciudad y necesito dos más para escuela y tipo de curso. Como puedo hacerlo???

    Saludos, Juan.

  31. Hola :
    Pregunta si quiero guardar en una base de datos el value del subcombo seleccionado como deberia hacer??

    gracias

    Adrian

  32. El programa en muy interesante … pero como haria para trabajar con base de datos … las provincias en una tabla y las localidades en otra tabla … claro esta que cada tabla debe tener un codigo de provincia y un codigo de localidad … gracias por el apoyo.

  33. Genial. es el primero que encuentro.
    Lo he estado testeando y para poderlo implantar en un formulario existente me encuentro con un problema.

    Tienes dos comnbos 1º de provincias y el segundo de poblaciones.

    ¿como puedo hacer para que me devuelva el value en string de las provincias?

    Actualmente tal como esta:
    devuelve el numero de la provincia y el 2º combo me devuelve el string de la ciudad seleccionada.

    Para poderlo implantar en un alta de usuario que ya esta hecha i insertando datos en la bbdd de mysql necesitaria que la provincia del primer combo fuer string.

    Agradeceria mucho que me dieran una solucion gracias

  34. Hola Daniel,

    El primer combo debe contener el id de la provincia para después poder buscar en el documento XML las localidades de dicha provincia.
    Si necesitas obtener el nombre de la provincia puedes hacer 2 cosas:
    1. Incluir en el value del primer combo el nombre y el id separador por un caracter de control, pejm: value=»1#almeria» y luego manejar la cadena como un stringtokenizer, que no es más que hacer un split de la cadena para obtener uno u otro valor.
    2. La segunda opción es acceder al text del combo box en vez de al value.

    Un saludo.

Deja un comentario

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