Niquelao

¿Cómo dices que te ha quedado?

¿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:

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:

¿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:

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:

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.

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:

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.

12  comentarios

12 comentarios

Javier (1 de March de 2009)

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);

Javier (1 de March de 2009)

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);

Rumoroso (10 de March de 2009)

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

Julio (31 de March de 2009)

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

Rumoroso (3 de April de 2009)

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

SauronZ (19 de May de 2009)

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.

Rumoroso (19 de May de 2009)

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

Convert (23 de May de 2009)

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

Rumoroso (23 de May de 2009)

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

SauronZ (2 de June de 2009)

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 .

david (30 de June de 2009)

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

Rumoroso (30 de June de 2009)

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

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.

Deja tu comentario

Información Personal

...y si quieres y aun no tienes un Gravatar.

Creative Commons License Esta obra está bajo una licencia de Creative Commons.