Introducción a la clase calendar

En los temas anteriores vimos que una primera ventaja de los objetos es que podemos reutilizar el código de la clase en tantas instancias como queramos. Supongamos que en una página hay un formulario que se envía a un servidor donde el usuario ha de poner varias fechas. Pero queremos controlar que introduzca fechas válidas. Es usual ver que en estos casos suele ponerse un acceso a un pequeño calendario y así el usuario ha de seleccionar la fecha en el mismo.

Pues eso es lo que intentaremos hacer: declarar una clase calendar para luego poder crear múltiples instancias de la misma. Este clase es única y no se aplican relaciones de composición o herencia con otras subclases o superclases creadas.

En esta página vamos a exponer varios ejemplos, donde los primeros nos servirán para usar directamente la clase calendar, aún sin saber como esta diseñada, lo cual se explica en los últimos apartados. Lo hacemos así porque uno de los objetivos de la Programación Orientada a Objetos (POO) es la abstracción y encapsulamiento principalmente, con lo que el programador que usa una clase no tiene porque saber necesariamente los detalles de como está diseñada, sino sólo las reglas para usar esa clase cuando vaya a instanciar objetos de élla.

Ejemplos de uso de la clase calendar para instanciar objetos calendario

A modo de resumen, las características generales del calendario son:

  • Objeto que almacena una fecha (día, mes y año) y que muestra en pantalla una clásica hoja de calendario de un mes y año dado.
  • El rango de años que cubre el calendario debe ser el máximo posible.
  • Ejecución sólo en el navegador del cliente con JavaScript, por lo que el servidor no participa en esa ejecución.
  • Presenta los días festivos nacionales y autonómicos de uso más frecuente con un estilo diferenciado. No se consideran las fiestas nacionales que se sustituyen o las que se trasladan de domingo a lunes. Avisa al usuario de esto.
  • Presenta el jueves y viernes santo como festivo.
  • La fecha actual aparece con un estilo diferenciado.
  • El usuario puede seleccionar un día del mes para almacenarlo en el objeto.
  • El usuario tiene facilidades para moverse a otra hoja del calendario.
  • Puede recoger una fecha y almacenarla así como devolver la fecha almacenada en varios formatos.
  • El programador que use el objeto tiene facilidades para cambiar el estilo de los días marcados (festivos, actual y seleccionado).

Ejemplo de calendario con interfaz visual

El constructor de la clase es el siguiente:

new calendar(nombreInstancia, dondeTabla
[, dondeTitulo][, fecha][, conSeleccionDia])
    

Nota aclaratoria: Esta clase calendar la he modificado en Agosto 2010 con una nueva distribución de los argumentos del constructor. Antes se declaraba new calendar(elDia, elMes, elAnyo, dondeTabla, dondeTitulo[, conSeleccionDia, nombreInstancia]). Ahora he agrupado día, mes y año que eran números enteros en un string fecha que se pasa como "d/m/aaaa" siendo un argumento opcional. Además se cambia el orden de los argumentos poniendo en primer lugar el nombreInstancia porque también ahora es obligatorio. Sin embargo el argumento dondeTitulo es ahora opcional.

La razón de estos cambios es debido a un problema detectado con las referencias a elementos HTML que se pasan a un objeto de JavaScript. Antes dondeTabla y dondeTitulo eran referencias a elementos HTML, ahora son tipos string con los identificadores id de esos elementos. Ver más en un problema con las referencias al DOM en objetos JavaScript. Por otro lado hacer obligatorio el nombreInstancia es debido a lo que también se comenta más abajo sobre un problema con this en JavaScript, pero también porque he incorporado control de errores en la clase y es necesario tener ahí el nombre de la instancia para ofrecerlo en un mensaje.

Los dos primeros argumentos son obligatorios, el resto opcionales. Los opcionales del final que no se pasen no es necesario ni siquiera indicarlos, pero si están antes de otro que si se pasa, entonces ha de ponerse una cadena vacía "" para ignorarlo.

El primer argumento nombreInstancia es un string obligatorio que será el mismo que el nombre de la variable con la que hemos instanciado el objeto. Por ejemplo var x = new calendar("x",...). El argumento dondeTabla es una referencia a un elemento HTML de bloque, un <div> por ejemplo. Es ahí donde se construirá dinámicamente una tabla (elemento table) con los días en las celdas. Pero ha de pasarse un string con el identificador id de ese elemento, no la referencia al propio elemento. Este argumento debe ser una referencia válida, pues la clase no lo verifica.

<div id="div1"></div>
<script>
    var calendario1 = new calendar("calendario1", "div1");
    if (calendario1.creado) calendario1.construyeCalendario();

</script>
    
NOV-2012: El código de este script ho he trasladado al window.onlad, para que se ejecute tras cargar el módulo calendar.js

Puede observar que hemos dispuesto un elemento <div id="div1"> y le hemos pasado la referencia a su id. Una vez creado con new calendar() entonces es aconsejable ver si se ha creado efectivamente y luego construirlo con el método construyeCalendario(). Como en este caso no pasamos el argumento dondeTitulo el calendario lo sitúa en el elemento <caption> de la propia tabla. Al no pasar el argumento fecha el calendario se construye con el mes y año de la fecha actual. El día actual se señala con fondo amarillo, mientras que los festivos tienen también un estilo particular.

Ejemplo:

Un calendario con el título en la tabla

No es necesario aplicar inmediatamente construyeCalendario() para presentar la hoja del mes tras la creación del objeto con new calendar(). En este ejemplo se crea el calendario cuando se carga la página pero se construye la hoja cuando el usuario pulse el botón:

Ejemplo:

Ver calendario de Febrero 2000 con este

<b><i>Ver calendario de Febrero 2000 con este </i></b>
<input type="button" value="botón"
onclick = "calendario1a.construyeCalendario()" />
<div id="div1a"></div>
<script>
    var calendario1a = new calendar("calendario1a", "div1a", "", "1/02/2000");
</script>
    
NOV-2012: El código de este script ho he trasladado al window.onlad, para que se ejecute tras cargar el módulo calendar.js.

También hay otros métodos que construyen el calendario, como situaFecha(fecha), donde el argumento es un literal de fecha "d/m/aaaa", situaHoy() y mueveCalendar(+-1) para mover a una hoja antes o después:

<ul>
<li><input type="button" value="situaFecha('1/12/1995')"
onclick = "calendario1b.situaFecha('1/12/1995')" /> construye...</li>
<li><input type="button" value="situaHoy()"
onclick = "calendario1b.situaHoy()" /> construye...</li>
<li><input type="button" value="mueveCalendar(1)"
onclick = "calendario1b.mueveCalendar(1)" /> construye...</li>
<li><input type="button" value="mueveCalendar(-1)"
onclick = "calendario1b.mueveCalendar(-1)" />, lo mismo...</li>
</ul>
<div id="div1b"></div>
<script>
    var calendario1b = new calendar("calendario1b", "div1b");
</script>
    
NOV-2012: El código de este script ho he trasladado al window.onlad, para que se ejecute tras cargar el módulo calendar.js.

Ejemplo:

Ver calendario con alguno de estos botones:
  • construye la hoja para el mes y año dado con el método situaFecha(fecha)
  • construye la hoja para el mes y año de la fecha actual.
  • construye el calendario para el mes posterior al de la fecha que tenga almacenada.
  • , lo mismo pero mueve un mes atrás.

Ejemplo de calendario con ubicación externa del título

Si no pasamos dondeTitulo el calendario sitúa el título con el mes y el año en el elemento <caption> de la propia tabla. Si no queremos esto le pasamos otro elemento externo HTML para situarlo. Puede ser de bloque o de línea, pero que admita introducir una cadena de texto con elemento.innerHTML. Este argumento dondeTitulo es un string con el atributo id del elemento.

<div>
    <span id="titulo2" style="border: blue double 3px"></span>
    <div id="div2"></div>
</div>
<script>
    var calendario2 = new calendar("calendario2", "div2", "titulo2", "1/7/2010");
    if (calendario2.creado) calendario2.construyeCalendario();
</script>
NOV-2012: El código de este script ho he trasladado al window.onlad, para que se ejecute tras cargar el módulo calendar.js.

Se observa que hemos elegido un elemento <span id="titulo2"> como lugar donde irá el título con el mes y el año, situándolo antes de la tabla. También en este caso pasamos un fecha para que se almacene en el calendario "1/7/2010". Este argumento si se pasa ha de tener el formato "d/m/aaaa". En este ejemplo se construye el calendario para el mes de julio de 2010.

Ejemplo:

Calendario con el título en un elemento externo a la tabla

Ejemplo de calendario con título modificable

Podemos también hacer que el usuario final interaccione con el calendario para que seleccione un mes y un año y obtener esa hoja del calendario. Para ello es necesario que en el argumento dondeTitulo haya un string con el identificador id de un elemento HTML <input type="text">, de tal forma que en ese cuadro de texto pueda modificarse el mes y año:

<input type="text" id="input3"
    onfocus = "calendario3.entraFecha(this)"
    onblur = "calendario3.mueveMesAnyo(this)" />
<div id="div3"></div>
<script>
    var calendario3 = new calendar("calendario3", "div3", "input3");
    if (calendario3.creado) calendario3.construyeCalendario();
</script>
    
NOV-2012: El código de este script ho he trasladado al window.onlad, para que se ejecute tras cargar el módulo calendar.js.

El elemento <input> contiene el título con el formato del nombre del mes en 3 letras primeras mayúsculas, una espacio y el año. Por ejemplo, "JUN 2010". Cuando el usuario entra en el cuadro se activa el evento onfocus que ejecuta el método entraFecha(), el cual convierte "JUN 2010" en "6/2010". Así el usuario puede cambiar de mes y año para ir a otra hoja del calendario con el evento onblur que ejecuta el método mueveMesAnyo(). Estos dos métodos son exclusivos para usar con un <input>, por lo que no funcionarán con cualquier otro elemento.

Ejemplo:

Calendario con el título modificable

Ejemplo de calendario con selección de día

Otra posibilidad que tiene el usuario final del calendario es seleccionar un día del mes y que este pase a la propiedad dia del objeto. Para ello es necesario pasar el argumento conSeleccionDia igual a true.

<div class="cal">
    <input type="button" class="mov" value="<"
        onclick="calendario4.mueveCalendar(-1)" />
    <input type="text" class="titulo"" id="input4"
        size="8" maxlength="7"
        onfocus = "calendario4.entraFecha(this)"
        onblur = "calendario4.mueveMesAnyo(this)" />
    <input type="button" class="mov" value=">"
        onclick="calendario4.mueveCalendar(1)" />
    <div id="div4" class="tab"></div>
</div>
<fieldset>
    <input type="button" value="Información"
        onclick="calendario4.mensaje()" />
    <input type="button" value="Ir a hoy"
        onclick="calendario4.situaHoy()" />
    <br />
    <input type="text" id="inputfecha" value="31/12/1999"
        size="10" maxlength="10" title="dd/mm/aaaa" />
    <input type="button" value="Ir a esa fecha"
        onclick = "document.getElementById('inputfecha').value =
            calendario4.situaFecha(document.getElementById('inputfecha').value)" />
    <br />
    <input type="button" value="Fecha seleccionada"
        onclick="alert(calendario4.devuelveFecha(document.getElementById('formato').value))" />
    Formato:
    <select id="formato">
        <option value="fecha-larga">"fecha-larga" p.e. "10/6/2010"</option>
        <option value="fecha-corta">"fecha-corta" p.e. "10/6/10"</option>
        <option value="fecha-dia-semana">
            "fecha-dia-semana" p.e. "Jueves, 10 de Junio de 2010"</option>
        <option value="array">"array": objeto Array()</option>
        <option value="date">"date": objeto Date()</option>
    </select>
</fieldset>
<script>
    var calendario4 = new calendar("calendario4", "div4", "input4", "", true);
    if (calendario4.creado) calendario4.construyeCalendario();
</script>
    
NOV-2012: El código de este script ho he trasladado al window.onlad, para que se ejecute tras cargar el módulo calendar.js.

Ahora pasamos el argumento conSeleccionDia y valor true para que el usuario pueda seleccionar el día pinchando con el ratón. Ese día se almacenará en la propiedad dia del objeto y se aplicará un estilo para resaltarlo visualmente. Con el método devuelveFecha(formato) podemos entonces rescatar ese día incluido en una fecha con formato.

El método del calendario para seleccionar el día necesita adjudicar eventos a las celdas <td> de la tabla y existe un problema con la palabra reservada this de JavaScript que, por ahora, no he podido resolver. Se explica con más detalle en la parte de diseño del calendario este problema con this.

Antes del script está todo el código HTML. Primero hay un <div class="cal"> donde ponemos el título, dos botones para navegar por los meses y la propia tabla del calendario. Luego hay un <fieldset> para albergar elementos y aplicar otros métodos adicionales del objeto. En cada elemento hemos puesto un atributo title que nos enseña que método de la clase se va a ejecutar. En la documentación de la clase se puede leer el funcionamiento de estos métodos.

Ejemplo:




Formato:

La tabla se crea sin estilo de ninguna clase a excepción de los días festivos y del día actual. En este ejemplo hemos puesto un estilo que está situado en la cabecera de este documento. Los elementos de la tabla no tienen nombre de clase para luego dar estilo, por lo que es más fácil acceder a ellos metiendo la tabla, el título y los dos botones de navegación dentro de algún bloque tal como hicimos aquí.

/* Estilo para el ejemplo calendario4 */
div.cal div.tab {
    padding-bottom: 0.2em;
    }
div.cal input.titulo {
    border: none;
    color: green;
    font-size: 2em;
    font-weight: bold;
    text-align: center;
    }
div.cal input.mov {
    color: green;
    font-size: 2em;
    font-weight: bold;
    }
div.cal div.tab table {
    font-family: Courier New;
    font-size: 2em;
    border-collapse: collapse;
    }
div.cal div.tab table th {
    color: navy;
    font: 1.1em 'Arial';
    padding: 0.3em;
    border: navy solid 1px;
    }
div.cal div.tab table td {
    color: black;
    font-weight: bold;
    text-align: right;
    padding: 0.3em;
    border: navy solid 1px;
    }

Ejemplo de calendario para integrar en un formulario

NOTA: Estos dos ejemplos funcionaron en Explorer 8, Firefox 3.6 y Safari 4.0. En Opera 10.6 también funcionó pero no se actualizan los bordes internos de la tabla en la primera presentación. Este efecto sucede también con otros objetos que crean dinámicamente tablas en el DOM, pero hasta el momento no he conseguido aislar el problema.

En meses posteriores he creado una nueva clase de objetos, los mensajes o formularios emergentes. Hay un ejemplo que usa un emergente para un calendario con igual propósito que el presente.

Nota de arreglo del pintado de bordes en Opera: En Julio 2011 por fin he encontrado la raíz del problema y ya Opera actualiza estos bordes. Ver cómo se hacen los contenedores con pestañas para más información. En el estilo CSS se cambia border-collapase: collapse por el valor separate y se declara border-spacing: 0. Aunque ahora el grosor de los bordes se duplica, sin embargo se corrige el problema del pintado de Opera.

Como último ejemplo proponemos un uso de nuestro calendario para el caso en que un usuario haya de introducir una fecha. Así podemos obligar a que use el calendario y sólo se introduzcan fechas válidas. En primer lugar hemos de crear un objeto calendar que, en este caso, es preferible situarlo en un script de un archivo externo que puede ver en la página codigo-calendario-form.html, donde también se expone el código del estilo CSS también situado en un archivo externo. Con la carga de la página creamos el calendario:

NOV-2012: Este ejemplo usaba dos archivos vinculados con esta página. Uno era calendario-form.js con el JavaScript y otro calendario-form.css con el estilo. Al modificar el módulo calendar.js para que se carge en el window.onload, he tenido que traspasar el JavaScript a esta página. De paso también he puesto el CSS para evitar una petición HTTP adicional.
//Variable global que apunta al calendario
var calendarioForm;
//Variable global que apuntará al elemento de el calendario.
//Puede ser un <input>, un /<span> o cualquier otro similar
var dondeFecha = null;

/* Esta es la función que se ejecuta cuando se completa la carga de la página, lo que
 * es ideal para crear objetos a los que luego se accede desde elementos y eventos
 * en la página.
 */
window.onload = function() {
    ...
    calendarioForm = new calendar("calendarioForm", "cf-tabla", "cf-titulo", "", true);
    if (calendarioForm.creado) calendarioForm.construyeCalendario();
    calendarioForm.cambiaEstiloDias("outline: red solid 3px", "dia-seleccionado");
    ...
}

Se puede ver que usamos una variable global calendarioForm para apuntar al objeto instanciado de la clase calendar. También usamos dondeFecha que tiene valor nulo al inicio, pero cuando abramos el calendario pasará una referencia del elemento HTML sobre el que interactuará el calendario. Además hay otras funciones que, brevemente, hacen lo siguiente:

  • function abreCalendarioForm(donde)

    Esta función nos permite poner como visible el bloque contenedor del calendario y sus botones. El argumento donde es la referencia a un <input>, un <span> o cualquier otro, cuyo texto como fecha se pasará al calendario con su método situaFecha(). Así cuando pasamos de un elemento a otro, la referencia dondeFecha se traslada a ese otro elemento de HTML. Si es un <input> se coge el value mientras que para el resto se coge el valor que haya en innerHTML (aunque debería cogerse con innerText pero no es estándar en todos los navegadores). El método situaFecha() de devuelve la misma fecha o bien "Error" si la fecha introducida no es válida, por lo que volvemos a regresar ese valor devuelto por el método y así si la fecha no es valida el usuario lo puede detectar.

  • function cierraCalendarioForm()

    Esta función oculta el bloque contenedor del calendario y botones poniendo la propiedad visibility = "hidden".

  • function recogeFechaCalendario()

    Esta función recoge la fecha que el usuario ha seleccionado y la inserta en el elemento con el que esta interactuando el calendario. En este caso se toma la fecha seleccionada en el calendario y se traspasa al elemento <input>, <span> o cualquier otro. Luego se oculta el calendario, como si se cerrara.

Para que el código anterior se ejecute, hemos de montar el bloque contenedor del calendario y botones de navegación:

<div id="cf-cal">
    <input type="button" class="cf-mov" value="<"
        title = "Un mes atrás"
        onclick="calendarioForm.mueveCalendar(-1)"
    /><input type="text" id="cf-titulo"
        size = "10" maxlength="10"
        onfocus = "calendarioForm.entraFecha(this)"
        onblur = "calendarioForm.mueveMesAnyo(this)"
    /><input type="button" class="cf-mov" value=">"
        title = "Un mes adelante"
        onclick="calendarioForm.mueveCalendar(1)"
    /><input type="button" class="cf-mov" value="OK"
        title = "Aceptar fecha"
        onclick="recogeFechaCalendario()"
    /><input type="button" class="cf-mov" value="X"
        title = "Cerrar"
        onclick="cierraCalendarioForm()" />
    <div id="cf-tabla"></div>
</div>
    

Aquí hemos puesto este código en esta altura de la página, pero se puede poner en cualquier sitio, puesto que inicialmente se ha dotado del siguiente estilo al bloque contenedor <div id="cf-cal">:

div#cf-cal {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    visibility: hidden;
    ...
    }
    

Esto quiere decir que se dota de posición absoluta por lo que se posicionará según los valores de top y left, que inicialmente son (0,0), pero que con visibility: hidden lo ocultamos de la vista. Luego con la con la función abreCalendarioForm(donde) lo situamos con su top y left en la posición donde queremos que se vuelva visible. Además hay que ponerlo en una capa superior con z-index: 1.

Y esto es en resumen lo que hay que hacer. Veámos dos aplicaciones de ejemplo, una en primer lugar con un elemento <span>, para lo cual insertamos en este punto de la página el siguiente código:

Introduzca fecha: <span id="span-fecha" class="cf-span"></span>
<input type="button" value="calendario"
    onclick = "abreCalendarioForm(document.getElementById('span-fecha'))" />
    

Ejemplo:

Introduzca fecha:

Observe que abreCalendarioForm(donde) pasa como argumento la referencia al <span> donde queremos que se abra el calendario. El segundo y último ejemplo lo hacemos con un elemento <input>:

Introduzca fecha:
<input type="text" id="input-fecha" class="cf-span" value="" />
<input type="button" value="calendario"
    onclick = "abreCalendarioForm(document.getElementById('input-fecha'))" />
    

Ejemplo:

Introduzca fecha:

Al cambiar de un caso a otro el calendario actualiza la fecha del elemento correspondiente. Si el elemento está vacío o la fecha no es valida, en el calendario no se actualiza nada y devuelve la palabra "Error" que se escribe en el elemento.

Documentación de la clase calendar

Para observar la estructura de la clase a efectos de que un programador pueda usarla sin conocer los detalles de su diseño e implantación, se puede crear un documento donde se relacionan las propiedades y métodos. Se explican de forma que el programador pueda usar la clase, sin entrar en detalles de diseño que no le aporten nada sobre ese uso. Algunos entornos de programación como los que usualmente se usan con Java, permiten obtener un documento similar de forma automática, tomando los comentarios previos que se ponen en el código de clase y método, pero respetando unas ciertas reglas. En todo caso aquí lo hemos realizado "a mano" para ofrecer como podría presentarse un documento de esta naturaleza:

  • Constructor y argumentos:
    new calendar(nombreInstancia, dondeTabla
    [, dondeTitulo][, fecha][, conSeleccionDia])
    • nombreInstancia: Un string obligatorio con el mismo valor que el nombre de la variable x con la que creamos el objeto.
    • dondeTabla: Un string del identificador id de un elemento HTML de bloque que pueda albergar un elemento <table> para construir las celdas del calendario.
    • dondeTitulo: Un string opcional del identificador id de un elemento HTML donde ubicar el título. Si no se pasa se pondrá el título en el elemento <caption> de la tabla.
    • fecha: Un string opcional con una fecha en formato "d/m/aaaa" para construir la hoja del calendario de ese mes y año. Se comproborá si la fecha es válida en el rango de años del calendario (1601 a 2299). Si no es válida o no se pasa se pondrá la fecha actual.
    • conSeleccionDia: Valor booleano true opcional para que el usuario final pueda seleccionar un día con lo que se almacenará en la propiedad dia. Si no se pasa este argumento se le dará el valor false.
  • Propiedades:
    • nombre: El nombre proviene del argumento obligatorio del constructor nombreInstancia.
    • seleccionDia: almacena el argumento opcional del constructor conSeleccionDia.
    • creado: Iniciado a falso, cuando se construye con éxito un nuevo calendario se pone a cierto.
    • anyo: Para almacenar un entero del año en el rango [1601..2299]. Se obtiene del argumento fecha tras aplicar la función global compruebaFecha(), al igual que para el mes y año siguientes.
    • mes: Para el mes en el rango [1..12]
    • dia: Para el día en el rango [1..31]
    • idDondeTabla: Almacena el argumento del constructor dondeTabla.
    • idDondeTitulo: Almacena el argumento del constructor dondeTitulo.
    • estiloFestivo: Un array con 3 valores de cadena que son expresiones de CSS para dotar de estilo a los días festivos. La posición 0 especifica el estilo de los días domingo, la 1 para los días festivos nacionales y la 2 para los días festivos autonómicos. El valor inicial que yo he puesto es Array("color: maroon", "color: red", "color: blue"). En lugar de la propiedad de estilo CSS de color podría usarse otra cosa o combinación de ellas, por ejemplo "background-color: lime; border: red solid 1px".
    • estiloDiaActual: Volvemos a usar CSS para dar un estilo al día actual. Inicialmente he puesto "background-color: yellow". Se debe tener en cuenta que el estilo del día actual se "pinta" al final, por lo que si se usan las mismas propiedades que los festivos, cuando coincida un festivo con el actual se sobreescribiran los estilos si son iguales y en otro caso se agregarán.
    • estiloDiaSeleccionado: Cuando la propiedad seleccionDia es true se dota de estilo CSS al día que figura en la propiedad dia. Si creamos un calendario con el día actual, encontramos que los estilos de estiloDiaActual y el presente estiloDiaSeleccionado se superponen. Por lo tanto este último no debe sobreescribir a los anteriores. Yo he optado por poner inicialmente el estilo "outline: green double 4px".
    • estiloDiaNoSeleccionado: Para quitar el estilo del día seleccionado. Yo he puesto el estilo que anula al anterior: "outline: none".
  • Métodos:
    • construyeCalendario(): Este método se encarga de construir de forma dinámica los elementos HTML para presentar el calendario en la página. Se genera un elemento <table border="0">, es decir, una tabla sin bordes ni más estilos de ninguna clase, lo cual puede dotarse luego de forma externa.
    • cambiaEstiloDias(estilo, queDia): Después de crear un calendario con new calendar() podemos cambiar el estilo de los días festivos, actual y seleccionado mediante esta función. En 'estilo' pasamos la cadena de estilo. En 'queDia' pasamos "domingo", "fiesta-estatal", "fiesta-autonomica", "dia-actual", "dia-seleccionado" o "dia-no-seleccionado".
    • situaHoy(): Reconstruye el calendario para presentar la hoja del mes y año de la fecha actual.
    • situaFecha(fechaString): Se pasa una cadena "d/m/aaaa" para reconstruir la hoja del mes y del año. El día también se almacena.
    • mueveCalendar(masMenos): El argumento recibido es un entero que puede valer 1 o -1 para mover en un mes la hoja del calendario. Su uso puede ser diverso, por ejemplo, poner dos eventos onclick en la página para la ejecución.
    • entraFecha(inpute): En el cuadro de texto <input type="text"> que hemos dispuesto antes de crear el calendario, el usuario final podrá teclear un mes (en número) y un año para mover la hoja de calendario. Con este método convertimos la cadena "MES/año", por ejemplo "JUN/2010" en los valores númericos 6 y 2010. Entonces hay que situar un evento onfocus en ese control de texto para ejecutar este método, por ejemplo onfocus = "calendario1.entraFecha(this)".
    • mueveMesAnyo(inpute): Cuando el usuario final salga del cuadro <input type="text"> captamos el valor que ha introducido en formato "nn/aaaa" y construimos con esos datos la nueva hoja de calendario. Un ejemplo sería onblur = "calendario1.mueveMesAnyo(this)"
    • devuelveFecha(formato): Nos devuelve la fecha almacenada en diferentes formatos:
      • "fecha-larga": devuelve una cadena "d/m/aaaa"
      • "fecha-corta": devuelve una cadena "d/m/aa"
      • "fecha-dia-semana": devuelve una cadena como por ejemplo "Lunes, 21 de Junio de 2010"
      • "array": devuelve un objeto Array(dia, mes, año)
      • "date": devuelve un objeto Date con la fecha almacenada.
    • mensaje(): Este método simplemente activa un mensaje con alert() de un texto que indica detalles relacionados con los días festivos marcados. Esto lo hacemos porque los días festivos son genéricos, es decir, son festivos que usualmente vienen marcados todos los años, pero que no deben tomarse como los oficiales. Estos son publicados todos los años en el BOE para las fiestas estatales y en los boletines autonómicos para las locales que en algunos casos modifican las anteriores.
    • verComoEs(): Devuelve una cadena que es una relación de las propiedades del objeto.
    • borrarSeleccionDia(): Este método es interno y no tiene razón que se use externamente. Se aplica para borrar el formato del dia seleccionado.
    • seleccionarDia(celda): Este método es interno y no tiene razón que se use externamente. Se aplica para dotar de estilo a la celda que contiene el día seleccionado.
  • Globales
    • Constantes globales
      • ANYO_INICIO: El año de inicio del calendario donde el 1 de enero fue lunes.
      • ANYO_FIN: El año final limitado por el cálculo de semana santa.
      • DIA_INICIO: El día de la semana antes del 1 de enero del año de inicio (en número entero 0-6).
      • RECTIF: Un array con los desplazamientos de los días en los meses.
      • NOMBRES_MES: Nombres de los meses.
      • DIAS_MES: Días en cada mes.
      • NOMBRES_DIAS_SEMANA: Nombres de los días de la semana.
      • FESTIVOS: Array con festividades.
      • GAUSS_PASCUA: onstantes para el cálculo del domingo de pascua en semana santa.
    • Funciones globales
      • construyeRECTIF(): Esta función no se usa pero sirve para construir los términos del array de desplazamiento de días var RECTIF = Array(0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5); En lugar de acudir a esta función es más rápido fijarla como una constante pues son valores que no varían.
      • esBisiesto(anyo): Comprueba si un año es bisiesto: Un año es bisiesto si es divisible por 4, excepto el último de cada siglo (aquel divisible por 100), salvo que este último sea divisible por 400.
      • calculaPascua(anyo): Algoritmo (Gauss) para calcular cuando cae el Domingo de Pascua de un año. En Wikipedia aparece una extensa descripción del algoritmo:
        a = Año mod 19
        b = Año mod 4
        c = Año mod 7
        d = (19a + f) mod 30
        e = (2b + 4c + 6d + g) mod 7
        Siendo f, g unas constantes de la tabla siguiente
        1583 - 1699 --> f=22 g=2 
        1700 - 1799 --> f=23 g=3 
        1800 - 1899 --> f=23 g=4 
        1900 - 2099 --> f=24 g=5 
        2100 - 2199 --> f=24 g=6 
        2200 - 2299 --> f=25 g=0 
        Si d + e < 10 --> PASCUA = (d + e + 22) Marzo sino PASCUA = (d + e - 9) Abril
        Tener en cuenta las excepciones:
        Si PASCUA == 26 de Abril --> PASCUA = 19 de Abril.
        Si PASCUA == 25 de Abril, d==28, e==6, a>10 --> PASCUA = 18 Abril.
      • buscaDiaSemana(dia, mes, anyo): Devuelve el díaSemana (0=lunes, ... , 6=domingo) de la fecha dada con dia (1-31), mes (1-12) y año dado (1601--2299) Este día de la semana es necesario para posicionar el día 1 de cada mes. Partiendo del 31/12/1600 que fue domingo (6º día de la semana), vamos sumando todos los días que hay hasta hoy. Luego hallamos el resto al dividir por 7 y nos da un número 0 a 6 que se corresponde con el día de la semana actual.
      • fechaActual(): Fecha actual que se devuelve en un array con 4 posiciones, el primero es el día de la semana, los 3 centrales son dia, mes y año y el último es un string con la fecha en formato "d/m/aaaa"
      • compruebaFecha(fecha): Comprueba si una fecha es correcta. Debe pasarse como un string "d/m/aaaa" y devuelve un array (dia, mes, año) con enteros 1..31, 1..12 y año Se pueden pasar varios tipos de separadores. Si hay algún error retorna nulo. Necesita las constantes DIAS_MES, ANYO_INICIO, ANYO_FIN El array devuelto tiene 4 posiciones, los 3 primeros para día, mes y año como enteros y el último un string con la fecha "d/m/aaaa". Los arrays son objetos que pueden combinar enteros y string.