> Manuales > Desarrollo en Javascript del lado del cliente

Ejemplo de selects combinados, o selects dependientes, usando solamente Javascript, de modo que al cambiar un select cambie cambie otro elemento select de la página.

Elementos de formulario select asociados (selects dependientes)

Vamos a conocer uno de los trucos más solicitados de Javascript, que tiene mucha relación con el tema de formularios y donde se utiliza el evento onchange de Javascript. Es un ejemplo sobre cómo realizar una página con un par de selects donde, según el valor escogido en uno de ellos, cambien las opciones posibles del otro select.

Una vez pongas el ejemplo en funcionamiento podrás cambiar la selección del primer select y comprobarás como las opciones del segundo select cambian automáticamente.

Esta práctica de selects dependientes se podría hacer de varias maneras distintas y en este artículo te vamos a proponer dos de ellas, para que puedas escoger la que más te guste. Una de las maneras incluye más Javascript que la otra, dado que en la primera tendremos que componer con código las opciones del segundo y en la segunda nos ahorramos esa parte debido a que los selects ya estarán montados en el HTML de antemano.

Conocer el objeto select y los option

Antes de comenzar con la práctica de selects dependientes vamos a dejarte unas referencias a temas que consideramos básicos sobre los elementos de formulario, que deberías saber para poder entender el problema.

Es importante conocer los objetos de formulario select y los option. Los select corresponden con las cajas de selección desplegables y los option con cada una de las opciones de la caja desplegable. Podemos ver un artículo que habla de ello.

En concreto nos interesa hacer varias cosas que tienen que ver con extraer el valor de un select en cualquier momento, fijar su número de opciones y, para cada opción, colocar su valor y su texto asociado. Todo esto aprenderemos a hacerlo en este ejemplo.

Referencia: Para conocer el trabajo con formularios y la jerarquía de objetos javascript (Todo eso es la base del trabajo con los elementos de las páginas en Javascript) debemos haber leer el manual de Javascript II.

Selects dependientes construyendo los option con Javascript

Esta primera técnica que vamos a aprender consiste en la construcción dinámica de las opciones del segundo select. Es decir, tendremos definidos todas las opciones del segundo select en arrays javascript y consruiremos las option del segundo select dinámicamente, cuando cambie la selección del primero.

El ejemplo que hemos ilustrado utiliza provincias y países. Al escoger en el primer select un país, en el segundo debe mostrarnos las provincias de ese país para que escojamos una provincia, pero sólo una que tenga que esté en el país seleccionado en primer término.

Para empezar, vamos a utilizar un formulario con dos selects, uno para el país y otro para la provincia.

<form name="f1"> 
<select name=pais onchange="cambia_provincia()"> 
<option value="0" selected>Seleccione... 
<option value="1">España 
<option value="2">Argentina 
<option value="3">Colombia 
<option value="4">Francia 
</select>

<select name=provincia> 
<option value="-">- 
</select> 
</form>

Nos fijamos en el select asociado al país de este formulario que, cuando se cambia la opción de país, se debe llamar a la función cambia_provincia(). Veremos más adelante esta función, ahora es importante fijarse que está asociada al evento onchange que se activa cuando cambia la opción en el select.

Todo lo demás será código Javascript. Empezamos definiendo un montón de arrays con las provincias de cada país. En este caso tenemos sólo 4 países, entonces necesitaré 4 arrays. En cada array tengo la lista de provincias de cada país, colocada en cada uno de los elementos del array. Además, dejaré una primera casilla con un valor "-" que indica que no se ha seleccionado ninguna provincia.

var provincias_1=new Array("-","Andalucía","Asturias","Baleares","Canarias","Castilla y León","Castilla-La Mancha","...") 
var provincias_2=new Array("-","Salta","San Juan","San Luis","La Rioja","La Pampa","...") 
var provincias_3=new Array("-","Cali","Santamarta","Medellin","Cartagena","...") 
var provincias_4=new Array("-","Aisne","Creuse","Dordogne","Essonne","Gironde ","...")

Hay que fijarse que los índices del array de cada país se corresponden con los del select del país. Por ejemplo, la opción España, tiene el valor asociado 1 y el array con las provincias de España se llama provincias_1.

Actualizado: Observarás que en este ejemplo se usa el método antiguo de creación de arrays en Javascrip, por medio de un constructor Array. Hoy afortunadamente es posible crear arrays en Javascript usando un literal, simplemente colocando sus valores entre corchetes. Luego tenemos un código para que puedas ver esto.

Estos arrays están sueltos, pero generalmente para procesarlos mejor nos conviene tenerlos en un array de dos dimensiones, lo que sería un array de array. Esto es importante para que luego el código para generar los combos dependientes nos salga más sencillo.

Podemos combinar los arrays en uno solo, con este literal de array.

var todasProvincias = [
    [],
    provincias_1,
    provincias_2,
    provincias_3,
    provincias_4,  
];

El script se completa con una función que realiza la carga de las provincias en el segundo select. El mecanismo realiza básicamente estas acciones:

La función tiene el siguiente código. Está comentado para que se pueda entender mejor.

function cambia_provincia(){ 
   	//tomo el valor del select del pais elegido 
   	var pais 
   	pais = document.f1.pais[document.f1.pais.selectedIndex].value 
   	//miro a ver si el pais está definido 
   	if (pais != 0) { 
      	//si estaba definido, entonces coloco las opciones de la provincia correspondiente. 
      	//selecciono el array de provincia adecuado 
      	mis_provincias=todasProvincias[pais] 
      	//calculo el numero de provincias 
      	num_provincias = mis_provincias.length 
      	//marco el número de provincias en el select 
      	document.f1.provincia.length = num_provincias 
      	//para cada provincia del array, la introduzco en el select 
      	for(i=0;i<num_provincias;i++){ 
         	document.f1.provincia.options[i].value=mis_provincias[i] 
         	document.f1.provincia.options[i].text=mis_provincias[i] 
      	}	
   	}else{ 
      	//si no había provincia seleccionada, elimino las provincias del select 
      	document.f1.provincia.length = 1 
      	//coloco un guión en la única opción que he dejado 
      	document.f1.provincia.options[0].value = "-" 
      	document.f1.provincia.options[0].text = "-" 
   	} 
   	//marco como seleccionada la opción primera de provincia 
   	document.f1.provincia.options[0].selected = true 
}

Espero que el ejemplo haya sido suficientemente claro para que puedas crear tu sistema de combos dependientes con Javascript, de manera sencilla y rápida.

Código completo de los selects dependientes

Para que te sea más sencillo de comprobar el funcionamiento de este ejemplo y reproducir los pasos para llegar a poner en marcha el ejercicio de los selects dependientes, te pasamos ahora el código completo de este primer ejemplo.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  

  <form name="f1"> 
    <select name=pais onchange="cambia_provincia()"> 
    <option value="0" selected>Seleccione... 
    <option value="1">España 
    <option value="2">Argentina 
    <option value="3">Colombia 
    <option value="4">Francia 
    </select>
    
    <select name=provincia> 
    <option value="-">- 
    </select> 
  </form>


  <script>
  var provincias_1=new Array("-","Andalucía","Asturias","Baleares","Canarias","Castilla y León","Castilla-La Mancha","...");
  var provincias_2=new Array("-","Salta","San Juan","San Luis","La Rioja","La Pampa","...");
  var provincias_3=new Array("-","Cali","Santamarta","Medellin","Cartagena","...");
  var provincias_4=new Array("-","Aisne","Creuse","Dordogne","Essonne","Gironde ","...");

  var todasProvincias = [
    [],
    provincias_1,
    provincias_2,
    provincias_3,
    provincias_4,
  ];

  function cambia_provincia(){ 
   	//tomo el valor del select del pais elegido 
   	var pais 
   	pais = document.f1.pais[document.f1.pais.selectedIndex].value 
   	//miro a ver si el pais está definido 
   	if (pais != 0) { 
      	//si estaba definido, entonces coloco las opciones de la provincia correspondiente. 
      	//selecciono el array de provincia adecuado 
      	mis_provincias=todasProvincias[pais]
      	//calculo el numero de provincias 
      	num_provincias = mis_provincias.length 
      	//marco el número de provincias en el select 
      	document.f1.provincia.length = num_provincias 
      	//para cada provincia del array, la introduzco en el select 
      	for(i=0;i<num_provincias;i++){ 
         	document.f1.provincia.options[i].value=mis_provincias[i] 
         	document.f1.provincia.options[i].text=mis_provincias[i] 
      	}	
   	}else{ 
      	//si no había provincia seleccionada, elimino las provincias del select 
      	document.f1.provincia.length = 1 
      	//coloco un guión en la única opción que he dejado 
      	document.f1.provincia.options[0].value = "-" 
      	document.f1.provincia.options[0].text = "-" 
   	} 
   	//marco como seleccionada la opción primera de provincia 
   	document.f1.provincia.options[0].selected = true 
}

  </script>
</body>
</html>

Verás que funciona perfectamente y que consigues tu objetivo de tener dos campos select donde los valores posibles del segundo campo dependan de la selección realizada en el primero.

Selects dependientes creando todos los select de antemano

Ahora vamos a resolver este mismo problema de selects dependientes creando una solución más sencilla, que hace uso de muy poco Javascript. Esta solución será un poco más fácil de aplicar si te sientes poco cómodo con Javascript y estás en un lenguaje del lado del servidor como PHP.

El enfoque que vamos a utilizar consiste en crear todos los select de antemano. Tendremos un select que es el principal, que estará siempre en la página y luego todos los select asociados que estarán también escritos en el código HTML de antemano y los iremos usando selectivamente.

Para este ejercicio tenemos varios niveles de formación, primaria, ESO... y dependiendo del nivel tendremos cursos distintos. Nuestro formulario en este caso podría ser algo como esto:

<form action="#">
  <select name="grado" id="grado">
    <option value="">Seleccionar grado</option>
    <option value="primaria">Primaria</option>
    <option value="ESO">ESO</option>
  </select>
  <p id="cursos">
    Selecciona el grado de formación
  </p>
  <p>
    <button>Enviar</button>
  </p>
</form>

Fíjate que el primer select está escrito en la página con las opciones principales. Sin embargo, el segundo select no está en el formulario y no aparecerá hasta que se seleccionen las opciones del primero.

Los posibles conjuntos de cursos que dependen de la selección del primer select los vamos a tomar de otro bloque de selects ya montados de antemano.

<div class="alternativa" id="alternativa-primaria">
  <select name="curso">
    <option value="1">Primero</option>
    <option value="2">Segundo</option>
    <option value="3">Tercero</option>
    <option value="4">Cuarto</option>
    <option value="5">Quinto</option>
    <option value="6">Sexto</option>
  </select>
</div>
<div class="alternativa" id="alternativa-ESO">
  <select name="curso">
    <option value="1eso">Primero ESO</option>
    <option value="2eso">Segundo ESO</option>
    <option value="3eso">Tercero ESO</option>
    <option value="4eso">Cuarto ESO</option>
  </select>
</div>

Para que te funcione bien, estos selects deberían estar ocultos de la página, lo que hacemos con CSS (display: none) y además deben estar fuera del código del formulario que estamos creando.

Es importante que estos select dependientes no estén dentro el formulario, porque si no al submitir el formulario se enviarían todos, o los datos de uno podría machacar los de otro, porque todos tienen el mismo name. Los colocaremos fuera del formulario y los insertaremos selectivamente.

Ahora, para conseguir que se muestre el select oportuno de cursos cuando se cambia el valor de los select de grado, vamos a hacer este código.

document.getElementById('grado').addEventListener('change', function(e) {
  if(this.value != '') {
    document.getElementById('cursos').innerHTML = document.getElementById(`alternativa-${this.value}`).innerHTML;
  } else {
    document.getElementById('cursos').innerText = 'Selecciona un grado de formación'
  }
}

Como puedes ver, la cantidad de código Javascript es minúscula. Esto es debido a que la parte compleja de este ejemplo, que es construir los select de todos los cursos para cada grado de formación está ya hecha de antemano, ya que tenemos los selects montados en la página.

Lo único que hacemos es asociar un manejador de evento change en el que verificamos si se marcó alguna opción válida en el primer select. En ese caso simplemente cambiamos el contenido HTML del espacio destinado a mostrar el select dependiente con el contenido del segundo select que debería mostrarte, de aquellos que ya están montados.

Si no se seleccionó algo válido en el primer select simplemente mostramos el mensaje de que se tiene que seleccionar algo.

Puedes ver el código completo de esta segunda alternativa de selects dependienes a continuación.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>selects dependientes</title>
  <style>
    .alternativa {
      display: none;
    }
  </style>
</head>
<body>
  <form action="#">
    <select name="grado" id="grado">
      <option value="">Seleccionar grado</option>
      <option value="primaria">Primaria</option>
      <option value="ESO">ESO</option>
    </select>
    <p id="cursos">
      Selecciona el grado de formación
    </p>
    <p>
      <button>Enviar</button>
    </p>
  </form>

  <div class="alternativa" id="alternativa-primaria">
    <select name="curso">
      <option value="1">Primero</option>
      <option value="2">Segundo</option>
      <option value="3">Tercero</option>
      <option value="4">Cuarto</option>
      <option value="5">Quinto</option>
      <option value="6">Sexto</option>
    </select>
  </div>
  <div class="alternativa" id="alternativa-ESO">
    <select name="curso">
      <option value="1eso">Primero ESO</option>
      <option value="2eso">Segundo ESO</option>
      <option value="3eso">Tercero ESO</option>
      <option value="4eso">Cuarto ESO</option>
    </select>
  </div>

  <script>
    document.getElementById('grado').addEventListener('change', function(e) {
      console.log(this, this.value);
      if(this.value != '') {
        document.getElementById('cursos').innerHTML = document.getElementById(`alternativa-${this.value}`).innerHTML;
      } else {
        document.getElementById('cursos').innerText = 'Selecciona un grado de formación'
      }
    });
  </script>
</body>
</html>

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual