¿Accesibilidad y javascript?
acc_calendar: Calendario accesible en javascript (innecesario pero útil)
Actualizado el 1 de Junio de 2008, por Rumoroso
En los campos de formulario en los que se tiene que introducir una fecha, de cara a mejorar la experiencia de usuario, y a la par que se aumenta el control en el formato de los datos, se puede incluir un calendario mediante javascript. Lo se, palabra maldita, aunque si se hace con cuidado y control, no tiene por qué tener implicaciones negativas en cuanto a estándares y accesibilidad.
Objetivos
En principio he establecido dos objetivos principales, que más que objetivos han sido pautas de trabajo a la hora de construirlo:
- Que sea accesible y no obstrusivo. Evidentemente, en ausencia de soporte para javascript no se ofrece la opción de desplegar el calendario, pero, si hay soporte… ¿por qué no hacer que el contenido generado sea accesible y utilizable?
- Que sea fácil de implementar y utilizar. He buscado una forma tal los programadores que deseen implementarlo en sus páginas web no requieran de introducir código adicional. Al igual que en CSS se utilizan diversos tipos de selectores (de elementos, id, clases,…) para asociar estilos a las diferentes partes de nuestros documentos, ¿por qué no utilizar lo mismo para asociar comportamientos?
Además, como objetivos secundarios están: optimizar, generalizar, internacionalizar,… (siendo realista, tuve que eliminar los objetivos de ligar y el de ganar dinero.)
Incluyéndolo en nuestros documentos
Antes de nada indicar que el script se puede obtener directamente descargando el ejemplo completo.
La inclusión del calendario en nuestro documento es tan sencillo como incluir el elemento script correspondiente en el head:
<script type="text/javascript" src="acc_calendar/acc_calendar.js"> </script>
El calendario se cargará para cualquier campo de texto que lleve incluida la clase “fecha“ (si el idioma del documento es el español). El formato de la fecha se introduce en la primera línea del script. Así, si por ejemplo se desea que la fecha siga el orden día/mes/año, no incluyendo un 0 delante del día cuando esté formada por un dígito, e incluyéndolo en el mes cuando sea necesario, y que el formato para el año sean 4 dígitos:
var formato = 'd/mm/yyyy';
Como ya se mencionó, para conseguir mostrar el calendario junto a un campo de texto, este deberá llevar la clase “fecha” si el idioma declarado para el documento es el español (“date” si es el inglés, etc). Estos nombres de clase se pueden modificar, añadir nuevos para otros idiomas, etc., directamente en el script. Además, todos los posibles parámetros se introducen como clases. La lista completa es la siguiente:
- Cargar calendario (requerido):
fecha - Fechas previas a hoy:
prev - Fechas posteriores a hoy:
post - Rango de años:
rangX(siendo X el número de años) - No se incluye el día actual:
todnact - Aplciar filtro para fechas disponibles:
disp
¿Y si cargo dinamicamente los input con AJAX?
El script tiene la propiedad de que si en cualquier momento se introducen nuevos campos de texto de forma asíncrona con AJAX, bastará con que tras dicha carga se llame a la función cargaLinks() para que a los inputs se les asocien los enlaces para la apertura del calendario
Primer ejemplo
<input class="fecha post" type="text"
id="fecha1" name="fecha1" value="" />
<input class="fecha post todnact" type="text"
id="fecha2" name="fecha2" value="" />
<input class="fecha prev rang100" type="text"
id="fecha3" name="fecha3" value="" />
<input class="fecha post rang20 todnact" type="text"
id="fecha4" name="fecha4" value="" />
<input class="fecha prev rang15" type="text"
id="fecha5" name="fecha5" value="" />
<input class="fecha rang10" type="text"
id="fecha6" name="fecha6" value="" />
Nueva Mejora (abril 2007)
En ocasiones podríamos desear que la fecha se introduzca en tres campos de texto, uno para cada dato que la compone. Se ha añadido la posibilidad de hacerlo. Para ello seguiremos controlándolo todo mediante el uso de clases asignadas a los input.
Para que constituyan un grupo, los tres campos de texto deberán añadir un código que los identifique como tal. Esto, que parece algo raro, no lo es tanto. En realidad, lo que hay que hacer es añadir a la palabra fecha que empleamos como clase en los tres, una letra o un número. Así, por ejemplo, les podríamos aplicar a los tres la clase “fechaA” e inmediatamente, además de asociarse el enlace para la apertura del calendario, se pasarían a comportar como un grupo. Más adelante se incluyen dos ejemplos que lo muestran claramente.
Cada uno de los campos deberá llevar una clase en función del dato que se le asocie:
- Para el campo día la clase “
day“ - Para el campo mes la clase “
month“ - Para el campo año la clase “
year“
Existe total libertad para el orden en el que se pongan, colocando las clases para la configuración del calendario (número de años, previos, posteriores, etc.) en el primero de los campos que se utilice. En el ejemplo siguiente se podrá apreciar la forma de hacerlo:
Segundo ejemplo
Fecha de los próximos 10 años en formato día, mes, año: / /
<input class="fechaA day post rang10"
maxlength="2" type="text" id="dia" name="dia" value="" />
<input class="fechaA month"
maxlength="2" type="text" id="mes" name="mes" value="" />
<input class="fechaA year"
maxlength="4" type="text" id="year" name="year" value="" />
Consideración importante es informar siempre al usuario de cuál es el campo para cada cosa. En el ejemplo se informa en el texto previo y además, las etiquetas de los input lo incluyen.
Fecha de los últimos 15 años en formato año, mes, día: / /
<input class="fechaB year prev rang15"
maxlength="4" type="text" id="otroyear" name="otroyear" value="" />
<input class="fechaB month"
maxlength="2" type="text" id="otromes" name="otromes" value="" />
<input class="fechaB day"
maxlength="2" type="text" id="otrodia" name="otrodia" value="" />
Consideración importante es informar siempre al usuario de cuál es el campo para cada cosa. En el ejemplo se informa en el texto previo y además, las etiquetas de los input lo incluyen.
Actualización (abril de 2007)
Se ha retocado el script para reducir los estilos que se aplican desde este. Ahora, el enlace generado tiene la imagen por contenido (antes esta se cargaba desde la hoja de estilos). El enlace se genera inmediatamente después del input (fuera del label si está incluido en él) y posee el siguiente marcado:
<a title="Desplegar para seleccionar la fecha para fecha"
href="#" class="enl_cal">
<img src="acc_calendar/acc_calendar.png" alt="Calendario">
</a>
En el caso de que sea el enlace para la carga de la fecha en tres campos de texto, la clase del enlace pasa a ser “enl_cal_group, y este se situa antes del primero de ellos.
Actualización (7 de julio de 2007)
De forma opcional y mediante una consulta ajax se puede aplicar un filtro para que únicamente determinados días del mes esten disponibles como enlaces. Para ello, el script envía mediante el método POST las variables month (mes en forma de número) y year, y este ha de devolver (mediante el lenguaje de servidor que queramos) la secuencia de días disponibles separados por comas. Al inicio del código del script se encuentra una variable (fichero_consulta) donde pondremos la dirección sobre la que resolver la consulta. Aquellos campos en los que queramos aplicar el filtro deberán incluir la clase disp (además de las restantes que ya se han mencionado).
Y como con ejemplos se puede entender mejor:
Fecha de este año (el calendario permitirá la elección exclusiva de días disponibles): / /
<input class="fechaN day disp"
maxlength="2" type="text" id="dian" name="dian" value="" />
<input class="fechaN month"
maxlength="2" type="text" id="mesn" name="mesn" value="" />
<input class="fechaN year"
maxlength="4" type="text" id="yearn" name="yearn" value="" />
* Actualización (21 de octubre de 2007)
Se acaban de incluir dos pequeñas variaciones en el script:
- La posibilidad de que el formato del año sea de dos o cuatro dígitos.
- La posibilidad de que se muestre el día de la semana cuando se ha seleccionado la fecha. Esto es posible si en el documento se incluye un elemento cuya “id” sea “nombre_dia_” más la “id” del campo donde se va a incluir la fecha, en el caso de utilizar un único campo de texto para esta, o la “id” del campo donde se incluirá el día si se emplean tres campos para ello.
Esta última modificación no implica la necesidad de incluir dicho elemento. El script reconoce su presencia si lo hay y en este caso, lo utiliza. No se ha considerado la opción de hacer que el script carge el nombre del día dentro del campo de texto, dado que esto tendría implicaciones en el formato a emplear en el caso de que el usuario tuviese que escribirlo directamente. A continuación se incluye un ejemplo de aplicación.
<span id="nombre_dia_fechaj"></span>
<input class="fecha post" type="text"
id="fechaj" name="fechaj" value="" />
* Actualización (1 de junio de 2008)
Gracias a Gerard y a su aportación, ahora el script para el calendario presenta dos nuevas mejoras.
- El script reconoce si el campo de texto al que se le asocia el calendario es readonly, evitando enviarle el foco al cerrarlo. Previo a esta modificación, en el caso de tener esta característica el mencionado campo de texto, el script podría devolver un error.
- Añadido soporte para el catalán.
Nuevamente le agradezco a Gerard su aportación e invito a todos a continuar mejorando el acc_calendar.
* Estilos enviados por los lectores
Cesar Caballero nos envió un nuevo estilo para el calendario. Si lo queréis utilizar, únicamente lo tenéis que descargar y remplazar por el archívo homónimo.
Gracias por vuestras aportaciones. Podéis enviar los estilos que queráis y aquí los enlazaremos.
Ventajas
Entre las ventajas que se le pueden atribuir tenemos:
- Fácil de usar e implementar.
- No es intrusivo.
- El código y el contenido que se genera es accesible (marcado, organización, contenido,…) y es utilizable mediante el uso de ayudas técnicas (lector de pantalla,…). En este punto se ha tenido en cuenta en qué lugar recae el foco tanto al mostrarse como durante el funcionamiento y al desaparecer. Así, cuando se muestra, el foco recae directamente sobre el selector de años, siguiendo un orden lógico al tabular desde él, y cuando se cierra el calendario (mediante el enlace de cierre o tras haber seleccionado una fecha) el foco recae sobre el campo de texto al que se le había asociado.
- Se facilita la navegación por el mismo independientemente del dispositivo. Se puede navegar utilizando cualquiera de los dispositivos con los que podamos navegar por la web.
- Sus parámetros son fácilmente configurables y su llamada muy simple (mediante el uso de nombres de clase).
- El idioma lo toma directamente del documento padre, pudiendo añadir traducciones nuevas al código. En el caso de no estar declarado el idimoa en el documento (cosa que no debe ocurrir), el español será el que se utilice por defecto. Actualmente, además del español incluye el inglés. Adicionalmente se ha hecho que reconozca si es inglés americano, no porque vaya a cambiar el contenido, sino para cambiar la disposición de los días de la semana (el domingo se coloca primero).
- Los estilos aplicados al calendario se incluyen mediante una CSS enlazada por medio del script, con lo que en ausencia de soporte para este, se optimiza la descarga del documento al no llamarse a dicha hoja de estilos.
- Se han incluido clases de tal manera que se puedan aplicar estilos sobre cualquiera de las celdas de la tabla (días activos, días no activos, día actual), así como estilos específicos para los sábados o domingos.
Conclusión
A modo de cierre… ¿qué se podría decir de este calendario?… pues que “es innecesario… pero útil” y que “no tiene implicaciones negativas en términos de accesibilidad“.
…por cierto ¿qué día es hoy?
Puedes hacer un seguimiento de los comentarios gracias al feed RSS 2.0. También podrías dejar un comentario, o enviar un trackback con la dirección http://www.niquelao.net/acc_calendar-calendario-accesible-en-javascript-innecesario-pero-util/trackback/ desde tu sitio.

Puedes hacer un seguimiento de los comentarios gracias al feed RSS 2.0. También podrías dejar un comentario, o enviar un trackback desde tu sitio.

12 comentarios
Hola tengo este código y me muestra un error que no soy capaz de saber por qué. Aparentemente, por la línea del error, es por que el Label no está asociado al input pero cuando reviso el codigo si lo veo vinculado. Incluso le he aplicado el estilo style=”display: inline-block” a la celda ya que está en tablas.
[..]
[..]
Fecha inicial (dd/mm/yyyy):
Fecha final (dd/mm/yyyy):
[..]
EL JS:
var formato = ‘dd/mm/yyyy’; var fichero_consulta = ‘days.php’; var dir_imagenes = ‘acc_calendar/image’;
El fichero days.php está en la misma ruta que el fichero html del formulario y las imágenes están en un subdirectorio para contenerlas
Me muestra error en la línea 184:
var elasociado = document.getElementById(asociado);
Disculpas, no ha salido el codigo, lo intento de nuevo:
[link href=”estilos.css” rel=”stylesheet” type=”text/css” media=”screen” /] [script type=”text/javascript” src=”acc_calendar/acc_calendar.js”][/script]
[form id=”form1″ name=”form1″ method=”post” action=”estadisticaCatalogos.asp”] [table width=”95%” border=”0″ align=”center”] [tr] [td]
[label for=”fechaj”] Fecha inicial (dd/mm/yyyy): [input class=”fecha rang10″ type=”text” id=”fechaj” name=”fechaj” value=”" /] [/label] [/td] [/tr] [tr] [td][label for=”fechat”] Fecha final (dd/mm/yyyy): [input class=”fecha rang10″ type=”text” id=”fechat” name=”fechat” value=”" /] [/label][/td] [/tr] [tr] [td align=”center”][label] [input type=”submit” name=”button” id=”button” value=”Enviar” /] [/label][/td] [/tr] [/table] [/form]
[..]
EL JS:
var formato = ‘dd/mm/yyyy’; var fichero_consulta = ‘days.php’; // Dirección que devuelve los días disponibles del mes y año var dir_imagenes = ‘acc_calendar/image’; //Direcctorio donde se encuentren las imágenes
El fichero days.php está en la misma ruta que el fichero html del formulario y las imágenes están en un subdirectorio para contenerlas
Me muestra error en la línea 184:
var elasociado = document.getElementById(asociado);
Buenos días Javier. Perdona que no te haya contestado antes pero es que he estado liado.
El error que te está devolviendo parece por un problema en los identificadores. Tal parece que estás marcando correctamente el formulario, así que lo que podría estar pasando es que en algún otro punto del documento estés repitiendo una o más “id” de las que usa el calendario. Revisa el código y comprueba que valida (si están repetidas las id, no lo hará).
Suerte
Buenos días!
Me parece un recurso muy muy bueno, muy util y muy facil de usar… además de accesible.
Aunque…. :)… con fecha de hoy (31/03/2009 en el ordenador) el calendario se vuelve un poco loco. Es decir, marzo lo pinta bien, pero abril en lugar de empezar el miércoles empieza el viernes.
Si cambias la fecha del ordenador a mañana se soluciona todo, pero hoy… falla.
He mirado otra implementación de un calendario similar y… ocurre lo mismo, lo cual me lleva a pensar que puede ser un error Javascript.
Alguna idea al respecto?
Un saludo,
Julio
Hola Julio.
La verdad es que no tengo claro el motivo por el que puede ocurrir. Voy a tratar de averiguar el motivo por el que esto pasa. Tan pronto sepa algo (si llego a saberlo
) te digo algo. Gracias por avisar, y gracias por tu opinión sobre el calendario…
Un saludo
Buenas Campeon!
Ando como loco buscando la manera de posicionar el calendario sobre el icono del calendario y no justo debajo.
Podrias decirme donde estan dichas funciones por favor?
Un saludo y gracias.
HOla SauronZ. Si mal no recuerdo, la posición se determina mediante la aplicación de estilos por parte del script, con lo que supongo que si buscas la cadena “.top” en este, seguramente encontrarás el punto donde deberías editar para conseguir lo que pretendes.
Suerte y un saludo
Hola tengo una pequeña duda sobre tu calendario me da ciertos problemas cuando puedas ponte en en contacto conmigo si quieres hablarlo un saludo y gracias
Tal vez sería mejor que comentases aquí los problemas que te está dando, más que nada porque puede que a otras personas les haya pasado o les esté pasando lo mismo, o incluso, que hayan encontrado su origen y su solución.
Un saludo
Buenas!
Al final consgui lo que necesitaba comentando la linea : calendar.style.left = (document.getElementById(’cal_’ + id).offsetLeft-2*(calendar.offsetWidth/3)) + ‘px’;
del JS y cambiando de la lina:
calendar.style.top = (document.getElementById(id).offsetHeight + document.getElementById(id).offsetTop) + ‘px’;
la propiedad top por bottom
De esta manera el calendario queda justo encima y no hay que andar haciendo scoll.
un saludo y muchas gracias .
mi consulta es como podria poner yo los dias aviles en el calendario me gustaria saber en k parte hay k meterc para modificar eso =D
Hola David. Lo que quieres conseguir está mencionado en la actualización de julio de 2007 (http://www.niquelao.net/acc_calendar-calendario-accesible-en-javascript-innecesario-pero-util#julio2007 ). El proceso se realiza mediante una consulta. Al generar el calendario se envían dos variables mediante el método post y se obtiene (ajax) la secuencia de días disponibles del mes.
Un saludo