Formularios HTML5: Date, cómo usar y detectar calendarios nativos

Una de las novedades anunciadas en HTML5 desde el principio son los nuevos tipos de elementos para formulario. Selectores de color, numéricos, fechas, rangos o urls entre otros. El problema llega cuando pasan los años, y hay navegadores que no implementan estos elementos (ni la W3C saca una recomendación definitiva), y tenemos navegadores que los soportan desde hace ya varios años, y otros que no lo hacen ni se les espera.

En este caso, me voy a referir al elemento de fecha, aunque tiene varios subtipos (mes, año, fecha con hora...) y no todos están implementados, vamos al caso más sencillo, la fecha, elegir un día (día-mes-año) en un calendario. Algo bastante habitual en los formularios de Internet, y que solemos tener que implementar con widgets javascript de alguna librería.



¿Por qué es mejor que ese widget esté ya implementado en el navegador?
  • El código del widget no formará parte de la página, por lo que la página será más ligera.
  • El widget se ejecutará de forma nativa en el navegador, siendo más rápido y eficiente que javascript interpretado.
  • El elemento estará mucho más comprobado y su código será más seguro, dará menos fallos.
  • Al ser nativo no interfiere con otras librerías javascript que podamos estar usando en la página.
  • Es desarrollo es más rápido, poner type=”date” es todo lo que tenemos que hacer para tener un calendario funcional.
  • El usuario se acostumbrará al widget que le ofrezca su navegador favorito, y al usar el mismo en todas las páginas no perderá el tiempo mirando como se pasa de mes o de año.
  • Se podría ofrecer servicios adicionales. Por ejemplo, en el móvil, que el calendario del navegador esté sincronizado con el calendario del móvil y al desplegarse muestre con colores los días que tenemos eventos marcados, nos puede ayudar a elegir mejor qué día era para el que teníamos que comprar un billete de tren.

Tiene una desventaja, podremos personalizar o saber muy poco del calendario que le ofrezca el navegador al usuario. Si queremos un funcionamiento muy particular o asegurarnos que todos los usuarios de la web usan el mismo calendario, entonces tendremos que volver a un calendario javascript. Pero en la mayoría de casos, con que el usuario pueda darnos una fecha nos vale, y nos da igual cómo sea el widget que le ayude a elegirla.

Para tener un campo de fecha que muestre un calendario HTML5, es tan sencillo como poner

<input type="date" />

Y esto funcionará en Chrome, Opera, IOs y las nuevas Blackberry. A continuación la tabla detalladas sobre su implantación:




Así que el problema que tenemos es que Firefox, Android, Safari e Internet Explorer no lo soportan, ni lo van a hacer próximamente, y entre todos ellos son más del 50% de uso de los navegadores, por lo que tenemos que ofrecer una alternativa javascript. En este caso nos vamos a ir al calendario “datepicker” de jQuery UI. Su uso es muy sencillo (una vez enlazadas las librerías y css apropiados):

<input type="text" id=”fecha” />

Y en una sección javascript:

$( "#fecha" ).datepicker();

El problema es saber cuándo tenemos que usar el de javascript y cuándo no. Porque los navegadores que no soportan el tipo date con calendario, aceptan elementos de ese tipo, aunque se comportan en la realidad como elementos de texto. Así que nosotros podemos usar siempre elementos de tipo date, por lo que Chrome u Opera mostrarán su calendario propio, y en los demás añadimos el de jQuery UI. Pero el problema lo tendremos en Chrome y Opera, donde se desplegarán los dos calendarios, el nativo y el de jQuery. Hay que hacer algo para que el de jQuery no se ejecute en esos casos.

Y a ser posible, sin tener que usar javascript de detección de versiones de navegador. Es un rollo, nuestro código funcionará (con suerte) bien en navegadores actuales y anteriores, pero cuando salgan nuevas versiones de navegador que implementen el calendario, tendremos que cambiar todas esas comprobaciones página por página. Un rollo.

Si intentamos detectar el valor del atributo type nos encontramos:

document.getElementById(“fecha”).getAttribute("type");
//Devuelve “date”

Devuelve date para todos los navegadores. Sin embargo si en lugar de preguntar por el atributo tipo, preguntamos directamente por el tipo, ahí si tendremos la respuesta:


document.getElementById(“fecha”).type;
//Devuelve “date” o “text”

Aquí si que tendremos que Chrome u Opera devuelven “date”, mientras que Firefox e IE devuelven “text”, y de esta forma tenemos una comprobación que no depende de versión o navegador, sino de la funcionalidad implementada. Así el código de comprobación (con jQuery) sería:
$fecha=$('#fecha');
if ($fecha[0].type!="date"){
$fecha.datepicker();
}