2

Sin utilizar jQuery, solamente Javascript.

Deseo agregar las opciones del segundo select dependiendo del valor que tome el primer select. El primer select elige la provincia de la que queremos tratar, y automáticamente dependiendo de la provincia que elijamos, se carga de datos el segundo select (pueblos).

Código HTML:

<tr>
    <td align=right>Provincia:</td>
    <td align=left colspan=3>
        <select name="provincia" id="provincia">
            <option value="cargar_provincias();">Seleccione una Provincia...
        </select>
    </td>
</tr>
<tr>                    
    <!-- Extra: Cargar pueblos a partir de una provincia -->
    <td align=right>Pueblo:</td>
    <td align=left colspan=3>
        <select name="pueblo" id="pueblo">
            <option value="cargar_pueblos();">Seleccione un Pueblo...
        </select>
    </td>
</tr>

Código Javascript:

//Función para cargar las provincias al campo "select".
function cargarProvincias() {
    //Inicializamos el array.
    var array = ["Cantabria", "Asturias", "Galicia", "Andalucia", "Extremadura"];
    //Ordena el array alfabeticamente.
    array.sort();
    //Pasamos a la funcion addOptions(el ID del select, las provincias cargadas en el array).
    addOptions("provincia", array);
}


//Función para agregar opciones a un <select>.
function addOptions(domElement, array) {
    var selector = document.getElementsByName(domElement)[0];
    //Recorremos el array.
    for (provincia in array) {
        var opcion = document.createElement("option");
        opcion.text = array[provincia];
        selector.add(opcion);
    }
}


//Función para cargar los pueblos al campo "select" dependiendo de la provincia elegida.
function cargarPueblos() {
    //Objeto de provincias con los pueblos correspondientes.
    var listaPueblos = {
        cantabria: ["Laredo", "Gama", "Solares", "Castillo", "Santander"],
        asturias: ["Langreo", "Villaviciosa", "Oviedo", "Gijon", "Covadonga"],
        galicia: ["Tui", "Cambados", "Redondella", "Porriño", "Ogrove"],
        andalucia: ["Dos Hermanas", "Écija", "Algeciras", "Marbella", "Sevilla"],
        extremadura: ["Caceres", "Badajoz", "Plasencia", "Zafra", "Merida"]
    }

    //Declaramos un array donde guardamos todos los elementos de tipo id=provincias e id=pueblos.
    var provincias = document.getElementById('provincia');
    var pueblos = document.getElementById('pueblo');
    //Tomamos como provinciaSeleccionada, el valor del id provincia (var provincias).
    var provinciaSeleccionada = provincias.value;

    //Se limpian los pueblos.
    pueblos.innerHTML = '<option value="">Seleccione un Pueblo...</option>'

    //Si existe provinciaSeleccionada...
    if(provinciaSeleccionada !== ""){
        //Se seleccionan los pueblos y se ordenan.
        provinciaSeleccionada = listaPueblos[provinciaSeleccionada];
        provinciaSeleccionada.sort();

        //Insertamos los pueblos mediante un FOR.
        provinciaSeleccionada.forEach(function(pueblo){
            var opcion = document.createElement('option');
            opcion.value = pueblo;
            opcion.text = pueblo;
            pueblos.add(opcion);
        });
    }
 }

¿Cómo puedo hacer para que al elegir una provincia automáticamente se carguen los pueblos de esa provincia?

omaza1990
  • 2,722
  • 32
  • 82
  • 143

2 Answers2

7

Una posible solución seria almacenar en un objeto las provincias como propiedades, con los pueblos en array como valor, y al elegir provincia imprimimos su array como options del select 'pueblo':

function cargarProvincias() {
    var array = ["Cantabria", "Asturias", "Galicia", "Andalucia", "Extremadura"];
    array.sort();
    addOptions("provincia", array);
}


//Función para agregar opciones a un <select>.
function addOptions(domElement, array) {
    var selector = document.getElementsByName(domElement)[0];
    for (provincia in array) {
        var opcion = document.createElement("option");
        opcion.text = array[provincia];
        // Añadimos un value a los option para hacer mas facil escoger los pueblos
        opcion.value = array[provincia].toLowerCase()
        selector.add(opcion);
    }
}



function cargarPueblos() {
    // Objeto de provincias con pueblos
    var listaPueblos = {
      cantabria: ["Laredo", "Gama", "Solares", "Castillo", "Santander"],
      asturias: ["Langreo", "Villaviciosa", "Oviedo", "Gijon", "Covadonga"],
      galicia: ["Tui", "Cambados", "Redondella", "Porriño", "Ogrove"],
      andalucia: ["Dos Hermanas", "Écija", "Algeciras", "Marbella", "Sevilla"],
      extremadura: ["Caceres", "Badajoz", "Plasencia", "Zafra", "Merida"]
    }
    
    var provincias = document.getElementById('provincia')
    var pueblos = document.getElementById('pueblo')
    var provinciaSeleccionada = provincias.value
    
    // Se limpian los pueblos
    pueblos.innerHTML = '<option value="">Seleccione un Pueblo...</option>'
    
    if(provinciaSeleccionada !== ''){
      // Se seleccionan los pueblos y se ordenan
      provinciaSeleccionada = listaPueblos[provinciaSeleccionada]
      provinciaSeleccionada.sort()
    
      // Insertamos los pueblos
      provinciaSeleccionada.forEach(function(pueblo){
        let opcion = document.createElement('option')
        opcion.value = pueblo
        opcion.text = pueblo
        pueblos.add(opcion)
      });
    }
    
  }
  
 // Iniciar la carga de provincias solo para comprobar que funciona
cargarProvincias();
<table>
   <tr>
      <td align=right>Provincia:</td>
      <td align=left colspan=3>
          <!-- Añadido onchange para cargar los pueblos -->
          <select name="provincia" id="provincia" onchange="cargarPueblos();">
              <!-- Hay que terminar los options -->
              <!-- 
                   Eliminado de value la llamada a la función,
                   si eso funciona lo desconocía, y aunque 
                   lo haga es totalmente innecesario, 
                   lo correcto es usar el evento onchange 
                -->
              <option value="">Seleccione una Provincia...</option>
          </select>
      </td>
  </tr>
  <tr>                    
      <td align=right>Pueblo:</td>
      <td align=left colspan=3>
          <select name="pueblo" id="pueblo">
              <!-- Hay que terminar los options -->
              <!-- 
                   Eliminado de value la llamada a la función,
                   si eso funciona lo desconocía, y aunque 
                   lo haga es totalmente innecesario, 
                   lo correcto es usar el evento onchange 
                -->
              <option value="">Seleccione un Pueblo...</option>
          </select>
      </td>
  </tr>
</table>

He eliminado tus comentarios para que identifiques mejor los mios.

Enrique B.
  • 327
  • 1
  • 7
  • ¿Qué significa "let"? – omaza1990 May 22 '17 at 12:43
  • omaza1990 , solo busca el select seleccionado con var select = document.getElementById('id'); --- var seleccionado = select.options[select.selectedIndex].value; --- mi duda con el código de erlantz es que el arrayseleccionado me devolvera un valor y no un length – Eduardo Sebastian May 22 '17 at 12:47
  • let es un tipo de variable que se usa solo localmente – Eduardo Sebastian May 22 '17 at 12:47
  • A EnriqueB, le funciona el código pero a mi no... Error: funciones.js:258 Uncaught TypeError: Cannot read property 'sort' of undefined at cargarPueblos (funciones.js:258) at HTMLSelectElement.onchange (EXAMEN_Libres_Ejer1_Javascript_2015-16.html:70) – omaza1990 May 22 '17 at 12:53
  • @omaza1990 Eso es que has cambiado algo, he comprobado el código en Mozilla y Chrome y funciona. El HTML también lo he editado, contenía errores y es necesario para que funcione la carga de pueblos. – Enrique B. May 22 '17 at 13:07
  • Edito la pregunta con todo mi cóigo para que puedas ver. – omaza1990 May 22 '17 at 13:14
  • @omaza1990 No has insertado bien el código, el ciclo que utilizas en addOptions para insertar las provincias lo he modificado para que el option tenga un value que funciona para seleccionar los pueblos en el objeto, esta comentado en mi respuesta. – Enrique B. May 22 '17 at 13:17
  • Cierto. Funciona correctamente. Gracias. – omaza1990 May 22 '17 at 13:21
  • @omaza1990 https://es.stackoverflow.com/questions/106042/var-let-const-o-nada-en-javascript/106067#106067 – Pablo Lozano Feb 11 '20 at 11:19
1

Lo primero, no sé si la función de cargar la primera select con las provincias te funciona, el método cargarProvincias() yo lo pondría para que se ejecutase nada más cargar la página:

    <body onload="cargarProvincias()">
...
</body>

Ahora, para que se carguen los pueblos de esa provincia, añade un evento onchange a la select:

select name="provincia" id="provincia" onchange="cargarPueblos(this.value)">
            <option value="cargar_provincias();">Seleccione una Provincia...
        </select>

Así lo que he hecho es, cada vez que cambies de provincia, llamas al método cargarPueblos y le pasas el value de la opción elegida.

function cargarPueblos(cargarProvincias) {
    //Inicializamos el array.
   //vacías la select cada vez que elijas una provincia
    document.getElementById("pueblo").innerHTML="";

    var pro_cantabria = ["Laredo", "Gama", "Solares", "Castillo", "Santander"];
    var pro_asturias = ["Langreo", "Villaviciosa", "Oviedo", "Gijon", "Covadonga"];
    var pro_galicia = ["Tui", "Cambados", "Redondella", "Porriño", "Ogrove"];
    var pro_andalucia = ["Dos Hermanas", "Écija", "Algeciras", "Marbella", "Sevilla"];
    var pro_extremadura = ["Caceres", "Badajoz", "Plasencia", "Zafra", "Merida"];
    //Ordena el array alfabeticamente.
    pro_cantabria.sort();
    pro_asturias.sort();
    pro_galicia.sort();
    pro_andalucia.sort();
    pro_extremadura.sort();

   for(var i=0; i<arraySeleccionado; i++){
        var option=document.createElement("OPTION");
        option.innerHTML=arraySeleccionado[i];
        document.getElementById("pueblo").appendChild(option);



    }

  }

Y sería algo así. En arraySeleccionado pon la Array que escojas, tienes que basarte en el valor que le pasas al método.

Erlantz Calvo
  • 831
  • 6
  • 16
  • Así es, el método cargarProvincias() sí me funciona y lo tengo para cuando se recargue la página en el body onload; pero lo tengo puesto mejor en el "window.addEventListener("load", function() {" para no tocar el diseño del HTML. – omaza1990 May 22 '17 at 11:45
  • ésta parte es la que no entiendo... "Y sería algo así. En arraySeleccionado pon la Array que escojas, tienes que basarte en el valor que le pasas al método." ¿Cómo se yo si tiene que buscar en pro_cantabria o en pro_extremadura? En tu código pone "arraySeleccionado". – omaza1990 May 22 '17 at 11:53
  • omaza1990 , solo busca el select seleccionado con var seleccionado = document.getElementById('id'); – Eduardo Sebastian May 22 '17 at 12:41
  • @EnriqueB. Suponía que una vez he hecho la estructura sería capaz de escribir la array por su cuenta, como he explicado debajo. SO sirve para ayudar y enseñar a la gente, no para resolver sus deberes, eso me dijo un moderador. – Erlantz Calvo May 22 '17 at 13:15