
 
 posTarget = getPos("targetCombos[]");

 function InitCombos()
  {
        // Iniciamos el proceso con el source predeterminado a nulo y con el parámetro
        // usedefault a true, para indicar que estamos recargando las combos automáticas en el
        // proceso inicial. Este parámetro estará a falso cuando el proceso en cascada de
        // combos automáticas se deba a cambios manuales introducidos por el usuario.
        disparaCombo(null, true);
  } 
 
 
 function disparaCombo(sourceName, usedefault)
 {
      if (usedefault== null)  {usedefault = false;}               // Inicialización del parámetro usedefault.

      if (sourceName == null)                                     // Carga las combos padres e inicia la cascada.
      {
         for (var k = 0; k < combos[0][posTarget].length; k++)    // Recorre todas las combos padres de la página.
         {
           var padre = combos[0][posTarget][k];
           cargacombo(null, padre, true);
         }
      }
     else
	 {
         // Hallamos el target para nuestro source.
         for (var i = 0; i < combos.length; i++)                 // Recorre todos los elementos del array combos.
         {
            if (sourceName == combos[i][0])                      // Buscamos nuestro source en el array combos.
	       {
				var target = combos[i][posTarget];                // Obtengo las próximas combos que deben recargarse.

               if (!((target.length ==1) && (target[0]=="")))    // Evitamos las combos automáticas finales(no lanzan ninguna otra).
	             {
                  for (var j=0; j<target.length ; j++)           // Un mismo source puede lanzar varias combos.
                  {
                      cargacombo(sourceName, target[j], usedefault);
                  }
	             }
            }
         }
      }
  }

  //Carga las combo dependiendo del valor seleccionado
  function cargacombo(sourceName, targetName, usedefault)
  {
	  // Busco los datos de la combo que se quiere cargar.
    var valuetarget = getDatos(targetName,getPos("InitialValue"));
	  var frm = getDatos(targetName,getPos("FormName"));
	  var blankSize = getDatos(targetName,getPos("blankSize"));
    var matrizname = getDatos(targetName, getPos("DataMatrizName"));

	  if (usedefault== null) {usedefault = false;}
	  else {valuesource = getDatos(sourceName,getPos("InitialValue"));}

	  //Obtenemos los indices del source y del target.
	  if  (sourceName == null) {sourceIndex = 'flag_padre';}   // Nota: No indicarlo con '' porque puede confundirse con 0.
	  else                     {sourceIndex = getIndice(frm, sourceName);}
	  targetIndex = getIndice(frm, targetName);

	  if ((sourceIndex == null) || (targetIndex == null))
	  {
	      alert ("Elemento no definido en el formulario: " + sourceName  + "/" + sourceIndex + " - " + targetName + "/" + targetIndex);
	      return;
	  }

	  // Comprobamos el navegador.
	  esExplorer =  (navigator.appName.charAt(0) == 'M');

	  // Borra todas las options del target.
	  len = document.forms[frm].elements[targetIndex].options.length;

    if (sourceIndex != 'flag_padre')
    {
      for (i = 0; i<len; i++)
      {
        document.forms[frm].elements[targetIndex].options[0] = null;
      }
      
	    //Añade una option en blanco a la combo con el tamaño predeterminado y value ''.
	    for (str = '', i = 0; i < blankSize; i++) {str += ' ';}
	    document.forms[frm].elements[targetIndex].options[0] = new Option(str, '');
    }

	  // Calculamos el código que usaremos en la consulta para obtener los valores del target.
	  if (usedefault)
	  {
	      selectedValue = valuesource; // Tomamos el valor transpasado desde la BD al formulario.
	  }
	  else
	  {
	    // Tomamos el valor seleccionado manualmente en la combo.
	    if (document.forms[frm].elements[sourceIndex].options.length > 0)
	    {
	       if (esExplorer)
	       {
	          selectedValue = document.forms[frm].elements[sourceIndex].value;
	       }
	       else
	       {
	          selectedIndex = document.forms[frm].elements[sourceIndex].selectedIndex;
	          if (selectedIndex == (-1)) selectedValue = '';
	          selectedValue = document.forms[frm].elements[sourceIndex].options[selectedIndex].value;
	       }
	    }
	  }

	  // Realizamos la consulta para obtener todos los posibles valores del target dependiendo del valor(elegido o llegado) del source.
	  if (((selectedValue != '') && (sourceIndex != 'flag_padre')))
	  {
        elementos = getRecuperaDatos(selectedValue, values[getPosMatriz(matrizname)]);
	      desde = 0;
	      flag = 0;

	      //Tamaño de la cadena recuperada en la consulta.
	      tam = elementos.length;

	      // Separamos códigos y descripciones recuperadas en la consulta.
	      for (i = 0; i < tam; i++)
	      {
	         if (elementos.substring(i, i+1) == '|')
	         {
	           if (flag == 0)
	           {
	              code = elementos.substring(desde, i);
	              flag = 1;
	              desde = i + 1;
	           }
	           else
	           {
	              desc = elementos.substring(desde, i);
	              flag = 0;
	              desde = i + 1;
	              document.forms[frm].elements[targetIndex].options[document.forms[frm].elements[targetIndex].options.length] = new Option(desc, code);
	           }
	         }
	      }
	  }

	  // Volvemos a llamar a la función dispara combo para que obtenga el próximo target y recargue esta nueva combo.
	  if (usedefault)
	  {
        if ((valuetarget=="")||(valuetarget==null)) valuetarget=selectedValue;
   	      document.forms[frm].elements[targetIndex].options[getIndiceOption(frm, targetIndex, valuetarget)].selected = true ;
	      disparaCombo(targetName, true);  // Para que continue la cascada.
	  }
	  else
	  {
        //if (document.forms[frm].elements[sourceIndex].options.length > 0)
  	    document.forms[frm].elements[targetIndex].options[getIndiceOption(frm, targetIndex, selectedValue)].selected = true;
	      disparaCombo(targetName);        // Para que continue la cascada.
	  }

  }

  // Recupera los valores dependientes del código pasado
  function getRecuperaDatos(cod, values)
  {
    var seleltos = new String("");
    for (var j=0; j<values.length; j++)
    {
      if (cod == values[j][0])
      {
         seleltos += values[j][1]+ "|" + values[j][2] + "|";
      }
    }
    return seleltos;
  }

  // Obtiene el indice que ocupa un option dentro de un select buscando por su valor.
  function getIndiceOption(frm, target, valor)
  {
      var numoptions = document.forms[frm].elements[target].length;
      for (var i=0; i<numoptions; i++)
      {
          if (document.forms[frm].elements[target].options[i].value == valor)
              return  i; //document.forms(frm).elements[source].options[i].index;

      }
      return 0; // Evita errores por cambiar los valores de los códigos en las tablas.
  }

  // Obtiene la posición que ocupa dentro del Array el tipo de dato pasado.
  function getPos(name)
  {
     for (i=0; i<desccombos.length; i++)
     {
       if (name == desccombos[i]) {return i;}
     }
  }

  // Obtiene la posición que ocupa en el Array values la matriz pasara
  function getPosMatriz(name)
  {
     for (i=0; i<dataMatrizNames.length; i++)
     {
       if (name == dataMatrizNames[i]) return i;
     }
  }

  // Obtiene los datos necesarios para cargar una combo.
  function getDatos(target,pos)
  {
     for (var j=0; j < combos.length; j++)                  // Recorre todos los elementos del array datos.
     {
       if (target == combos[j][0])                          // Para acceder a los datos del target.
       {
           return  combos[j][pos];                          // Devuelve el dato buscado de la combo automática.
       }
     }
  }

  // Obtiene el indice que ocupa el parámetro pasado dentro del formulario.
  function getIndice(frm, nombreCampo)
  {
      len = document.forms[frm].elements.length;
      for (var i = 0; i < len; i++)
      {
        if (document.forms[frm].elements[i].name  == nombreCampo)
           return i;
      }
  }
