<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>SELECTs depedientes con inteligencia hacia atrás</title>
<meta name="Author" content="derkeNuke">
</head>
<body>
<script>
/************************************************** **************
ESTRUCTURA BÁSICA
************************************************** **************/
var paises=["PAIS1","PAIS2","PAIS3"];
var provincias=[
["PROVINCIA1 (p1)","PROVINCIA2 (p1)", "PROVINCIA3 (p1)", "PROVINCIA4 (p1)"],
["PROVINCIA1 (p2)", "PROVINCIA2 (p2)", "PROVINCIA3 (p2)", "PROVINCIA4 (p2)", "PROVINCIA5 (p2)", "PROVINCIA6 (p2)"],
["PROVINCIA1 (p3)", "PROVINCIA2 (p3)", "PROVINCIA3 (p3)" ]
];
var ciudades=[
[
["ciud1-1-1", "ciud1-1-2", "ciud1-1-3", "ciud1-1-4", "ciud1-1-5" ],
["ciud1-2-1", "ciud1-2-2", "ciud1-2-3", "ciud1-2-4" ],
["ciud1-3-1", "ciud1-3-2", "ciud1-3-3", "ciud1-3-4" ],
["ciud1-4-1", "ciud1-4-2", "ciud1-4-3" ]
],
[
["ciud2-1-1", "ciud2-1-2", "ciud2-1-3", "ciud2-1-4", "ciud2-1-5", "ciud2-1-6", "ciud2-1-7", "ciud2-1-8" ],
["ciud2-2-1", "ciud2-2-2", "ciud2-2-3", "ciud2-2-4", "ciud2-2-5", "ciud2-2-6" ],
["ciud2-3-1", "ciud2-3-2", "ciud2-3-3", "ciud2-3-4", "ciud2-3-5", "ciud2-3-6" ],
["ciud2-4-1", "ciud2-4-2", "ciud2-4-3", "ciud2-4-4", "ciud2-4-5", "ciud2-4-6", "ciud2-4-7" ],
["ciud2-5-1", "ciud2-5-2", "ciud2-5-3", "ciud2-5-4", "ciud2-5-5" ],
["ciud2-6-1", "ciud2-6-2", "ciud2-6-3", "ciud2-6-4", "ciud2-6-5" ]
],
[
["ciud3-1-1", "ciud3-1-2", "ciud3-1-3", "ciud3-1-4", "ciud3-1-5", "ciud3-1-6", "ciud3-1-7", "ciud3-1-8" ],
["ciud3-2-1", "ciud3-2-2", "ciud3-2-3" ],
["ciud3-3-1", "ciud3-3-2", "ciud3-3-3", "ciud3-3-4" ]
]
];
/************************************************** **************
FUNCIONES ÚTILES PARA ARRAYS Y SELECTS
************************************************** **************/
//agrega un option a un select, con un par de atributos extra que nos serán útiles
function agregarOpt(elSel,txt,valor,suPais,suProvincia,cont ieneProvincias,contieneCiudades) {
var indice=elSel.options.length;
elSel.options[ indice ] = new Option(txt,valor);
elSel.options[ indice ].suPais=suPais;
elSel.options[ indice ].suProvincia=suProvincia;
elSel.options[ indice ].contieneProvincias=contieneProvincias;
elSel.options[ indice ].contieneCiudades=contieneCiudades;
}
//selecciona la opción iPos en el select elSelect
function selecciona(elSelect,iPos) {
elSelect.options[iPos].selected="selected"; // para los estándares
elSelect.options.selectedIndex=iPos; // a la manera IE
}
//devuelve true si el elemento elem se encuentra entre los elementos del array
Array.prototype.existe=function(elem) {
for(var i=0;i<this.length;i++)
if( this[i] == elem ) return true;
return false;
}
//borra todas las opciones de un select cuyo valor no se encuentre entre los elementos de elArray
function dejarOpcionesExistentes(elSelect,elArray) {
for(var i=0; i<elSelect.options.length; i++) {
if( !elArray.existe( elSelect.options[i].value ) ) {
//borramos la opcion
elSelect.options[i]=null;
i--; //reducimos i porque tenemos que iterar más veces (el length de las options es uno menos)
}
}
}
/************************************************** **************
CREACIÓN Y RELLENADO DE LOS SELECTS
************************************************** **************/
//Creamos los SELECTS
var selPais=document.createElement("SELECT");
var selProv=document.createElement("SELECT");
var selCiud=document.createElement("SELECT");
//la función coloca en los selects creados todos los valores de los arrays, pudiendo salvar el select que se indique en los argumentos
function reiniciar_selects(conPaises,conProvincias,ConCiuda des) {
if (conPaises==undefined || conPaises)
haCambiadoPais=false;
//eliminamos las option de los selects que procedan
while( (conPaises==undefined || conPaises) && selPais.options.length>0 )
selPais.options[0]=null;
while( (conProvincias==undefined || conProvincias) && selProv.options.length>0 )
selProv.options[0]=null;
while( (ConCiudades==undefined || ConCiudades) && selCiud.options.length>0 )
selCiud.options[0]=null;
//colocamos las opciones nuevas si procede
for(var i=0; i<paises.length; i++) {
if(conPaises==undefined || conPaises )
agregarOpt(selPais, paises[i], paises[i], null, null, provincias[i].toString().split(","), ciudades[i].toString().split(",") );
for(var j=0; j<provincias[i].length; j++) {
if(conProvincias==undefined || conProvincias )
agregarOpt(selProv, provincias[i][j], provincias[i][j], i, null, null, ciudades[i][j].toString().split(",") );
for(k=0; k<ciudades[i][j].length; k++) {
if(ConCiudades==undefined || ConCiudades ) {
//cuenta regresiva para contar todas las provincias anteriores (cuantas provincias habia en los paises anteriores)
var aux=i-1, provinciasAnteriores=0;
while(aux>=0)
provinciasAnteriores+=provincias[aux--].length;
agregarOpt(selCiud, ciudades[i][j][k], ciudades[i][j][k], i, provinciasAnteriores+";"+j, null, null);
}
}
}
}
}
var haCambiadoPais=false; //elemento de control para contar las provincias al cambiar de ciudad
reiniciar_selects(true,true,true); //todos los valores en todos los selects
//adjuntamos al documento
document.body.appendChild(selPais);
document.body.appendChild(selProv);
document.body.appendChild(selCiud);
/************************************************** **************
EVENTOS ONCHANGE PARA CADA UNO DE LOS SELECTS
************************************************** **************/
selPais.onchange=function() {
//restablecemos provincias, ciudades
reiniciar_selects(false,true,true);
//cambiar provincias para que sólo contengan .contieneProvincias
var contieneProvincias=this.options[this.options.selectedIndex].contieneProvincias;
dejarOpcionesExistentes(selProv,contieneProvincias );
//cambiar ciudades para que sólo contengan .contieneCiudades
var contieneCiudades=this.options[this.options.selectedIndex].contieneCiudades;
dejarOpcionesExistentes(selCiud,contieneCiudades);
haCambiadoPais=true;
}
selProv.onchange=function() {
//restablecemos sólo ciudades
reiniciar_selects(false,false,true);
//seleccionar el pais al que pertenece la provincia
var suPais=this.options[this.options.selectedIndex].suPais;
selecciona(selPais,suPais);
//cambiar ciudades para que sólo contengan .contieneCiudades
var contieneCiudades=this.options[this.options.selectedIndex].contieneCiudades;
dejarOpcionesExistentes(selCiud,contieneCiudades);
}
selCiud.onchange=function() {
//seleccionar el pais al que pertenece la ciudad
var suPais=this.options[this.options.selectedIndex].suPais;
selecciona(selPais,suPais);
//seleccionar la provincia a la que pertenece la ciudad
var suProvincia=this.options[this.options.selectedIndex].suProvincia;
if(!haCambiadoPais) suProvincia=eval( suProvincia.replace(";","+") ); //suma de las provincias de los anteriores paises más la suya
else suProvincia=suProvincia.split(";")[1]; //sólo la suya
selecciona(selProv,suProvincia);
}
//creamos un botón por si acaso se necesita restablecer todo:
var boton=document.createElement("INPUT");
with(boton) {
type="button", value="Restablecer";
setAttribute("onclick","reiniciar_selects(true,tru e,true)"); // estándar
boton.onclick=reiniciar_selects; // IE
}
document.body.appendChild(boton);
</script>
</body>
</html>