Mundo Web
manuales - recursos - gráficos - programación...

Home - WebScript - Formularios - Combos con fecha

Combos con fecha
por Luciano Moreno, del departamento de diseño web de BJS Software.


Cuando nos vemos en la necesidad de implementar un formulario de entrada de datos en nuestras páginas es bastante común el tener que situar unos campos para que el usuario introduzca una fecha.

Una solución sería establecer una o más cajas de texto para esta labor, aunque entonces deberemos habilitar una función de JavaScript para que valide la fecha en ellas introducida antes de enviar los datos. Y otra solución, que considero mejor, es permitir a nuestro visitante que sólo pueda introducir una fecha correcta, evitándonos así el proceso de validación.

Vamos a ver un ejemplo de ésto último, implementando 3 combos para ello, uno para el día, otro para el mes y otro para el año, con la peculiaridad adicional de que inicialmente van a reflejar la fecha actual del sistema del usuario. El combo de los días se va a actualizar automáticamente al mes y año seleccionados, presentando los días correspondientes a los mismos, con lo que tendremos resuelto el tema de la validación.

El código necesario para ello es el siguiente:

<head>
  <title>Combos de fecha</title>
   
  <style type="text/css"> 
    .fecha{font-size:10px;font-family:Verdana,Helvetica;} 
  </style>

  <script language="JavaScript" type="text/javascript">
    /**
    * definimos las variables que almacenaran los componentes de la fecha actual
    */
    ahora          = new Date();
    ahoraDay    = ahora.getDate();
    ahoraMonth = ahora.getMonth();
    ahoraYear   = ahora.getYear();

    /**
 * Nestcape Navigator 4x cuenta el anyo a partir de 1900, por lo que es necesario
 * sumarle esa cantidad para obtener el anyo actual adecuadamente
 **/
 if (ahoraYear < 2000)
        ahoraYear += 1900;

    /**
 * funcion para saber cuantos dias tiene cada mes
 */
    function cuantosDias(mes, anyo)
    {
        var cuantosDias = 31;
        if (mes == "Abril" || mes == "Junio" || mes == "Septiembre" || mes == "Noviembre")
      cuantosDias = 30;
        if (mes == "Febrero" && (anyo/4) != Math.floor(anyo/4))
      cuantosDias = 28;
        if (mes == "Febrero" && (anyo/4) == Math.floor(anyo/4))
      cuantosDias = 29;
        return cuantosDias;
    }

    /**
 * una vez que sabemos cuantos dias tiene cada mes
 * asignamos dinamicamente este numero al combo de los dias dependiendo
 * del mes que aparezca en el combo de los meses
 */
    function asignaDias()
    {
        comboDias = document.formFecha.seleccionaDia;
        comboMeses = document.formFecha.seleccionaMes;
        comboAnyos = document.formFecha.seleccionaAnyo;

        Month = comboMeses[comboMeses.selectedIndex].text;
        Year = comboAnyos[comboAnyos.selectedIndex].text;

        diasEnMes = cuantosDias(Month, Year);
        diasAhora = comboDias.length;

        if (diasAhora > diasEnMes)
        {
            for (i=0; i<(diasAhora-diasEnMes); i++)
            {
                comboDias.options[comboDias.options.length - 1] = null
            }
        }
        if (diasEnMes > diasAhora)
        {
            for (i=0; i<(diasEnMes-diasAhora); i++)
            {
                sumaOpcion = new Option(comboDias.options.length + 1);
                comboDias.options[comboDias.options.length]=sumaOpcion;
            }
        }
        if (comboDias.selectedIndex < 0)
          comboDias.selectedIndex = 0;
     }

    /**
 * ahora selecionamos en los combos los valores correspondientes
 * a la fecha actual del sistema
 */
    function ponDia()
    {
        comboDias = eval("document.formFecha.seleccionaDia");
        comboMeses = eval("document.formFecha.seleccionaMes");
        comboAnyos = eval("document.formFecha.seleccionaAnyo");

        comboAnyos[0].selected = true;
        comboMeses[ahoraMonth].selected = true;
 
        asignaDias();

        comboDias[ahoraDay-1].selected = true;
    }

    /**
 * esta funcion crea dinamicamente el combo de los anyos, empezando
 * por el actual y acabando por el actual+masAnyos
 */
    function rellenaAnyos(masAnyos)
    {
        cadena = "";

        for (i=0; i<masAnyos; i++)
        {
            cadena += "<option>";
            cadena += ahoraYear + i;
        }
        return cadena;
    }
  </script>

</head>

<body bgcolor="#ffff99" onLoad="ponDia();">
<center>
<form name="formFecha" class="fecha">
  <select name="seleccionaDia" class="fecha">
    <option>1
    <option>2
    <option>3
    <option>4
    <option>5
    <option>6
    <option>7
    <option>8
    <option>9
    <option>10
    <option>11
    <option>12
    <option>13
    <option>14
    <option>15
    <option>16
    <option>17
    <option>18
    <option>19
    <option>20
    <option>21
    <option>22
    <option>23
    <option>24
    <option>25
    <option>26
    <option>27
    <option>28
    <option>29
    <option>30
    <option>31
  </select>
  <select name="seleccionaMes" class="fecha" onchange="asignaDias()">
    <option>Enero
    <option>Febrero
    <option>Marzo
    <option>Abril
    <option>Mayo
    <option>Junio
    <option>Julio
    <option>Agosto
    <option>Septiembre
    <option>Octubre
    <option>Noviembre
    <option>Diciembre
  </select>
  <select name="seleccionaAnyo" class="fecha" onchange="asignaDias()">
    <script language="JavaScript" type="text/javascript">
        document.write(rellenaAnyos(50));
    </script>
  </select>
</form>
</center>
</body>
</html>

Consideraciones:

1) Obtenemos la fecha actual en el sistema del usuario mediante el objeto propio de JavaScript Date, y el día, el mes y el año que éste contiene mediante sus métodos getDate(), getMonth() y getYear().

2) Nestcape Navigator 4x empieza a contar los años desde el 1900, por lo que para él el año 2001 será el 101. Es por ésto por lo que añadimos 1900 al año obtenido mediante el método getYear().

3) Para saber si un año es bisiesto (en cuyo caso Febrero tendrá 29 días) usamos la propiedad que tienen éstos años de ser divisibles por 4. Usamos entonces el método Math.floor(expresion) del objeto propio Math, que recibe como argumento un número, variable que lo contenga o expresión válida y devuelve el menor entero inferior a éste. En realidad lo que estamos haciendo con la comparación que establecemos es ver si la división del año por 4 tiene resto cero, en cuyo caso será bisiesto.

OJO. Esto sólo es válido para años superiores al 2000, como es éste caso. Para años inferiores hay que añadir condiciones extras.

4) Cuando el usuario cambia el mes o el año en los combos correspondientes, el código JavaScript se encarga de ver el nuevo valor elegido, comprobar cuántos días tuvo ese mes de ese año y cambiar dinámicamente el número de días presentes en el combo, para que las posibles combinaciones de los 3 combos de una fecha correcta.

5) El combo de los años de rellena dinámicamente al cargar la página, presentando como primer elemento el año actual, y como último la suma del actual más el número que le hayamos pasado a la función rellenaAnyos(n) como argumento, que en nuestro ejemplo han sido 50.

El resultado de éste código podéis verlo pinchando aquí.

 


Home - WebScript - Formularios - Combos con fecha