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. Muy interesante el ejercicio. Pero, que pasaria si quiero actualizar una ciudad mas o mas localidades, etc … creo que seria mejor trabajarlo con base de datos … cosa que si necesitamos realzar alguna actualizacion lo hariamos desde una pagina de ingreso o un formulario de mantenimiento … tienes un codigo que aplique para este caso ? … llevo tiempo intentando sacarlo pero no me sale … espero tu ponta respuesta … gracias

  2. Mis felicitaciones por la aportación de esta utilidad, pero tengo un problema y es el siguiente. Cuando lo ejecuto en el servidor apache que tengo en mi ordenador me funciona correctamente, pero al subirlo al servidor de Arsys solo sale el select de las provincias sin rellenarlo. Gracias, te agradecería mucho cualquier comentario.

  3. Lo únco que necesitas es la versión 5 de PHP y la clase Xpath. Confirma con Arsys que tu hosting dispone de ello.
    Si es así, tal vez lo que pueda estar fallando es la referencia al archivo xml, mira si la ubicación coincide con la ruta.
    Suerte.

  4. El archivo que se descarga con extensión .zip no sirve, por favor me gustaria que me colaboraran dandome el link de la descarga correcta. Muchas gracia…..

  5. Estupendo!!!
    Pero tengo un problema, cuando el form encuentra un algun campo invalido, vuelve a la pagina anterior cargando solamente la provincia y la localidad no, entonces el usuario tiene que elegir otra provincia y localidad y luego eligir su verdadera provincia y localidad….
    Yo llamo los erros desde php asi:

    echo ‘ history.go(-1); alert(«Es necesario rellenar todos los campos obligatorios!»);’;

    Como podrias solucionar eso??

    Saludos cordiales

    Ricardo

  6. Excelente utilidad gracias por compartirla. ¿Como podria modificarse para cargar los datos desde una base de datos de mysql por ejemplo?

  7. Buen artículo … salvo por una cosa … ¿que tiene que ver el uso de AJAX parar recargar un combo con lo de la web 2.0? Yo llevo usando AJAX desde hace más de 8 años (antes incluso de que existiese el término AJAX, nosotros lo llamábamos XMLHTTP). AJAX es una técnica, usada con frecuencia en las webs 2.0, pero NO es ni se inventó con las webs 2.0 (me joden las modas).

  8. Jeje, reconozco que el adjetivo 2.0 lo he incluido com un reclamo…
    Recuerdo que durante la carrera llegamos a utilizar un iframe para realizar peticiones asíncronas al servidor. 🙂 Aquello si que era 1.0…qué tiempos.

  9. necesito introducir en una misma página varios productos y sus colores, por lo que tendria que colocar dos select por cada producto y sus id no pueden ser iguales. ¿Como podría hacerlo funcionar con getelementbyName? He probado haciendo un array pero no lo consigo. ¿Podrías ayudarme?

  10. Muy util el script Ignacio. Podrías decirme como recuperar los valores seleccionados para guardarlos en una base de datos? Al enviar el formulario, en que variables puedo recuperar esos datos? Gracias

  11. Oye si quiero poner un link al segundo combo. ¿como podria hacerlo?
    No encuentro la manera, es decir si sale el combo pero si quiero que me de un link hacia una pagina o directorio como lo hago.

  12. [quote comment=»3411″]a bueno, pero ¿podrias darme una idea de como hacerlo?[/quote]

    Alfinal encontraste la forma de hacerlo? estoy intentandolo y no lo consigo!

    Gracias

  13. Ignacio, bonito trabajo y es EXACTAMENTE lo que necesito, con solo dos ComboBox, PERO tengo un problema, soy viejo en la programación (Cobol, Clipper, Fortran, Basic, y VisualBasic) pero NUEVO en lo de la Web, a penas estoy leyendo HTML y algo de JavaScript. Estoy haciendo un proyecto que necesito de dos Combos tal como lo tienes en el trabajo que hiciste. He tratado viendo lo tuyo, pero me da un Codigo Error : 0, en el primer combo me aparece $provincia o sea, no me esta’ trayendo nada del XML, claro, todo lo estoy corriendo en mi PC con Windows 7. Recuerden SOY NOVATO en esto de la Web. Cualquier ayuda se lo agradeceria muchiiisimo !!! Nota : no me interesa sacar las info desde base de datos, si las puedo hacer desde arrays o algo asi, bienvenido sea…
    Gracias

  14. [quote comment=»2678″]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[/quote]

    Tengo el mismo problema que tu, si has conseguido solucionarlo, te agradecería que me lo comentases. Gracias.

  15. Me gustaría que los municipios enlazaran con una página, que parte del código hay que modificar? Un saludo y enhorabuena por el trabajo.

  16. He probado tu ejemplo y me parece que está muy bien, pero me gustaría saber como puedo manatener, depues de haber realizado una consulta, la provincia para seguir consultando por muncipio.

  17. Hola, me ha sido de bastante utilidad el combo dinámico, para insertar las provincias y localidades. Mi duda es que no se como establecer un valor por defecto, es decir que cuando cargue página se ponga por ejemplo Granada y localidad Granada. He pobado con poner value=»18″, pero no funciona.

    Salu2 y gracias de antemano

  18. Hola!!
    Esta genial tu ejemplo y necesito usarlo, pero al implementarlo en el listado de provincias me carga mas los nombres de las provincias.
    me pone lo siguiente:

    01
    Albacete
    Alicante
    04
    Asturias
    Avila
    06
    …..

    ¿Cómo lo soluciono?¿Qué hago mal?
    Te agradecería muchísimo que me ayudaras.

    Mul gracias de ante mano

    Irene

  19. Muchas gracias por compartir este código. Ha funcionado como la seda y a la primera!
    Para adaptarlo a mis necesidades simplemente tuve que retocar el fichero XML, dejando únicamente las provincias que me interesaban y su listado de municipios, cosa que resultó muy sencilla.
    Gracias de nuevo

  20. Buenas Ignacio,

    Muchas gracias por el aporte, llevo tiempo utilizándolo y hasta hace unos días no me di cuenta que Asturias presenta problemas al cargar los municipios, el resto de provincias carga muy rápido. Desconozco si es por el gran número de municipios que tiene o cualquier otro motivo.

    Espero tu ayuda. Gracias!!!

  21. Gracias por compartir este post, estaba haciendo un script para un formulario y solo de pensar en el listado me puse malo.
    Funciona muy bien.

  22. WOW! Pensé que me iba a tocar hacer esto a mí… muchas gracias!
    Iba a montar esta funcionalidad en un webservice para usarlo vía API y que la gente no tenga que sufrir más para hacer un combobox de estos…

    Esta es sin duda la manera correcta de realizar la tarea. Los sistemas basados en MySQL son más lentos.

    GRACIAS.

Deja un comentario

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