Combo que depende de otro Combo con Javascript y jQuery

De ChuWiki

En ocasiones tenemos un combo (o select en html) cuyas opciones dependen de la opción que se haya seleccionado previamente en otro combo. Vamos a ver aquí un pequeño ejemplo de como implementar esto con Javascript. Nos ayudaremos de la librería jQuery para facilitar la modificación de las posibles opciones del combo.


html[editar]

Un pequeño html con los dos combos.

<body>
<div>
   <select id="primary">
      <option value="color">Color</option>
      <option value="country">Country</option>
   </select> 
   <select id="secondary">
   </select>
</div>
</body>

Tehemos los dos select a los que identificaremos por su id, primary el uno, secondary el otro. Cuando elijamos "color" en el primero, se añadiran distintos colores como opciones para el segundo. Cuando elijamos "country" en el primero, se añadirán distintos países como opciones del segundo.

Veamos la parte javascript del ejemplo


javascript[editar]

El total del código javascript, usando jQuery, puede ser como el siguiente

<script
	src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var options = {
		color : ["red","green","blue"],
		country : ["Spain","Germany","France"]
}

$(function(){
	var fillSecondary = function(){
		var selected = $('#primary').val();
		$('#secondary').empty();
		options[selected].forEach(function(element,index){
			$('#secondary').append('<option value="'+element+'">'+element+'</option>');
		});
	}
	$('#primary').change(fillSecondary);
	fillSecondary();
});

Vamos a explicarlo con calma.

Primero cargamos la librería jQuery, que nos será útil para modificar el segundo combo de forma más fácil que con javascript puro y duro.

Definimos una variable options en la que ponemos las distintas opciones para color y country. En este caso es importante que color y country sean los mismos nombres que los valores del primer combo. En la variable options, cada una de estas opciones tiene un array con las opciones que serán las del segundo combo.

No es necsario que se definan de esta forma las opciones. Lo importante es tenerlas disponibles de alguna forma y esta es la más sencilla para nuestro ejemplo. Después veremos una forma de obtener estas opciones del servidor por medio de AJAX.

$(function() {...}) es una forma de decirle a jQuery que llame a la función que definimos ahí cuando todo el docuemnto esté cargado. Es decir, en cuanto el navegador cargue la página, jQuery se encargará de llamar a esta función. Ahí es donde vamos a poner nuestro código javascript para modificar el segundo combo.

Con var fillSecondary = function() {...} estamos definiendo una función fillSecondary() cuyo objetivo es añadir al segundo combo las opciones que indique el primero. Dentro de esa función

  • var selected = $('#primary').val(); mete en la variable selected la opción seleccionada en el primer combo. $('#primary') es una llamada a jQuery para que nos devuelva el elemento html cuyo id es primary. Sería equivalente a un document.getElementById("primary") de javascript. La llamada .val() nos devuelve el valor de ese elemento, en este caso, la opción seleccionada en el primer combo, color o country.
  • $('#secondary').empty(); Vacía las opciones del segundo combo. Inicialmente ya están vacías, pero cuando empecemos a jugar con el primer combo, se rellenarán, así que cuando queramos cambiarlas, lo primero que tendremos que hacer es quitar las que hubiera antes de añadir las nuevas. Igual que antes, $('#secondary') nos devuelve el elemento html cuyo id es secondary y la llamada a empty() vacía todo su contenido html interno (las option si las hubiera).
  • options[selected].forEach(...) . Como vimos antes, options tiene todas las posibles opciones. options[selected] será el array de options.color o options.coutry, según lo que valga selected. El forEach() hace que se recorra el array, llamando para cada elemento a la función que se pase como argumento function(element,index) {...}. A esa función se le pasará cada vez un element del array (o sea, uno de los colores o uno de los países, según que array estemos recorriendo) Dentro de esta función sólo tenemos que ir añadiendo la opción element al combo secundario con $('#secondary').append('<option value="'+element+'">'+element+'</option>');. La función append() añade un elemento html hijo (un option).

Bueno, ya tenemos definida una función fillSecondary() que vacía el segundo combo y lo rellena con los posibles valores de acuerdo a lo que hay seleccionado en el primer combo. Solo nos queda

  • Con $('#primary').change(fillSecondary); le decimos a jQuery que llame a la función fillSecondray() cada vez que el primer combo cambie de valor. fillSecondary() se encargará de borrar el contenido del segundo combo y añadirle sus nuevas opciones.
  • Llamar a fillSecondary(); para darle los valores iniciales al segundo combo.

Aquí puedes ver el código funcionando


Un poco de AJAX[editar]

Vamos a complicar el ejemplo, sólo un poco, haciendo que los valores del segundo combo nos los de el servidor en vez de tenerlos como variable de javascript. Partimos de que tenemos una página en el servidor (puede ser un .php, un .jsp o cualquier otro lenguaje) a la que podemos llamar para obtener las opciones del segundo combo en función del primer combo. Puede ser algo como pagina.php?selected=color o pagina.php?selected=country. Esta llamada debe devolvernos un array json bien formado, es decir, debe devolver ["red","green","blue"] o ["Spain","Germany","France"] según el valor del parámetro selected que se le pase.

El código html es exactamente el mismo que antes.

El código javascript puede ser como este

<script
	src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function(){
	var fillSecondary = function(){
		var selected = $('#primary').val();
		$('#secondary').empty();
		$.getJSON("pagina.jsp?selected="+selected,null,function(data){
	 	   data.forEach(function(element,index){
		      $('#secondary').append('<option value="'+element+'">'+element+'</option>');
		   });
		});
	}
	$('#primary').change(fillSecondary);
	fillSecondary();
	

});

La carga de jQuery es igual que antes.

De la misma forma que antes, cuando jQuery nos indique que la página se ha cargado totalmente, definimos la función fillSecondary(), le decimos a jQuery que llame a esta función cuando cambie el contenido del primer combo y llamamos a la función para rellenar el segundo combo con unos valores iniciales.

Dentor del fillSecondary() es todo igual excepto la forma de obtener las opciones del segundo combo. Usamos $.getJSON() que es una llamada AJAX de jQuery que nos permite obtener datos en formato json del servidor. Esta función getJSON() admite tres paraámetros:

  • La url de la que queremos obtener los datos, en nuestro caso "pagina.jsp?selected="+selected que se traducirá a pagina.jsp?selected=color o pagina.jsp?selected=country según lo que haya seleccionado en el primer combo.
  • Datos que queramos pasar a esta url. Ponemos null, aunque podríamos poner la url como "pagina.jsp" sin parámetro y hacer que los datos fueran {selected:selected}, es decir, un atributo de nombre selected cuyo valor sería el contenido de la variable selected.
  • La función a la que nos llamarán cuando el servidor responda. A esta función se la llamará pasandole data como parámetro. En data estará el array de opciones para el segundo combo, si el servidor devuelve bien ["red","green","blue"], bien ["Spain","Germany","France"], es decir, un array bien formado en JSON.

Así que teneiendo en data el array de elementos para el segundo combo, sólo nos queda, igual que antes, recorrer el array con un forEach() para ir añadiendo los elementos.