Creación de formas fabulosas con HTML5

HTML5 Rocks

Introducción

No a todo el mundo le gustan los formularios, pero HTML5 ofrece algunas mejoras considerables, tanto para los desarrolladores que los crean como para los usuarios que los rellenan. Gracias a los nuevos elementos, atributos, tipos de entrada, validación basada en el navegador, técnicas de creación de estilos CSS3 y al objeto FormData, todos ellos relacionados con los formularios, ahora crear formas resulta más fácil y divertido.

There is even more up to date forms guidance on our new Web Fundamentals site.

Compatibilidad con el navegador

En lo que respecta a la escritura de código, la compatibilidad con todos los tipos, atributos y elementos de entrada y de formularios nuevos varía ampliamente según el navegador. Incluso entre navegadores que admiten una función concreta, el comportamiento de estos puede ser diferente. Sin embargo, el estado de compatibilidad de los formularios de HTML5 cambia de forma muy rápida y continúa mejorándose. En lo que respecta a la escritura de código, estos gráficos son la información más actualizada que he podido encontrar. En ellos, se detalla el estado de compatibilidad del navegador en relación con los formularios de HTML5.

Descripción general de las novedades

Nuevos elementos

HTML5 incorpora cinco nuevos elementos relacionados con las entradas y los formularios.

Elemento Función Notas
progress Representa el proceso de finalización de una tarea. El elemento progress puede representar el progreso de subida de un archivo.
meter Representa una medida escalar en un intervalo conocido. El elemento meter se puede utilizar para representar medidas como la temperatura o el peso.
datalist Representa un conjunto de elementos option que se pueden utilizar en combinación con el nuevo atributo list de entrada para crear menús desplegables. Al destacar la entrada con la lista de datos asociada, aparecerá un menú desplegable con los valores del elemento datalist.
keygen Representa un control para generar pares de claves. Cuando se envía el formulario, la clave privada se almacena en el almacenamiento de claves local y la clave pública se envía al servidor.
output Muestra los resultados de un cálculo. Por ejemplo, el elemento output se puede utilizar para mostrar la suma de los valores de dos elementos de entrada.

Nuevos tipos de entrada

HTML5 incorpora 13 nuevos tipos de entrada. Cuando estos tipos de entrada se visualizan en un navegador que no es compatible, se convierten en entrada de texto.

Tipo de entrada Función Notas
tel Sirve para introducir un número de teléfono. El tipo de entrada tel no requiere una sintaxis específica, por lo que si quieres garantizar un formato concreto, puedes utilizar pattern o setCustomValidity() para realizar una validación adicional.
search Sirve para solicitar a los usuarios que introduzcan el texto que quieran buscar. La diferencia entre search y text es fundamentalmente de estilo. Si utilizas un tipo de entrada search, es posible que al campo de entrada se le aplique un estilo que se corresponda con el de los campos de búsqueda de la plataforma.
url Sirve para introducir una única URL. El tipo de entrada url está diseñado para introducir una única URL absoluta, que representa un intervalo de valores bastante amplio.
email Sirve para introducir una dirección de correo electrónico única o una lista de direcciones de correo electrónico. Si se especifica el atributo multiple, se podrán introducir varias direcciones de correo electrónico separadas por comas.
datetime Sirve para introducir una fecha y una hora, siempre y cuando la zona horaria esté configurada como UTC.
date Sirve para introducir una fecha sin zona horaria.
month Sirve para introducir una fecha formada por el año y el mes, pero sin zona horaria.
week Sirve para introducir una fecha formada por el año y el número de semana, pero sin zona horaria. Por ejemplo, 2011-W05 para la quinta semana de 2011.
time Sirve para introducir un valor de hora formado por las horas, los minutos, los segundos y las fracciones de segundo, pero sin zona horaria.
datetime-local Sirve para introducir una fecha y una hora sin zona horaria.
number Sirve para introducir un número. Los valores válidos son números correspondientes a puntos flotantes.
range Sirve para introducir números, pero a diferencia de tipo de entrada number, esta no es importante. En la mayoría de los navegadores que admiten la implementación del control de intervalo, esta es un control deslizante.
color Sirve para elegir un color a través de un control adecuado del color. El valor debe ser un color simple en minúscula, por ejemplo, #ffffff.

Nuevos atributos de entrada

HTML5 también incorpora varios atributos nuevos para los elementos de formulario y entrada.

Atributo Función Notas
autofocus Centra la entrada en el elemento cuando se carga la página. El atributo autofocus se puede aplicar a entradas, selecciones, áreas de texto y botones.
placeholder Sugiere al usuario el tipo de datos que debe introducir. El valor "placeholder" se muestra en texto de color claro hasta que se destaca el elemento y el usuario introduce algunos datos. Se puede especificar en entrada y área de texto.
form Especifica uno o varios formularios a los que pertenece el elemento de entrada. Al utilizar el atributo form, los elementos de entrada se pueden ubicar en cualquier zona de la página, no solo en el elemento de formulario. Además, se puede asociar un único elemento de entrada a más de un formulario.
required Es un atributo booleano que indica que el elemento es obligatorio. El atributo required resulta útil para realizar una validación basada en el navegador sin utilizar JavaScript personalizado.
autocomplete Sirve para especificar que el navegador no debe autocompletar o rellenar previamente un campo en base a las entradas anteriores del usuario. El atributo autocomplete está destinado a campos como el número de tarjeta de crédito o una contraseña de un solo uso, que no quieres que se completen automáticamente. De forma predeterminada, autocomplete se encuentra activado (estado on), por lo que si quieres inhabilitarlo, debes establecerlo en el estado off.
pattern Sirve para validar el valor de un elemento comparándolo con una expresión regular. Al utilizar un atributo pattern, también debes especificar un valor title para proporcionar al usuario una descripción del patrón previsto.
dirname Sirve para enviar la direccionalidad del control con el formulario. Por ejemplo, si el usuario introdujo datos de texto con una direccionalidad de derecha a izquierda y el elemento de entrada contenía el atributo dirname, se enviará una indicación de direccionalidad de derecha a izquierda junto con el valor de entrada.
novalidate Sirve para inhabilitar la validación de envíos de formularios cuando se especifique en un elemento de formulario.
formaction Sirve para anular el atributo "action" en el elemento de formulario. Este atributo es compatible con los elementos input y button.
formenctype Sirve para anular el atributo "enctype" en el elemento de formulario. Este atributo es compatible con los elementos input y button.
formmethod Sirve para anular el atributo "method" en el elemento de formulario. Este atributo es compatible con los elementos input y button.
formnovalidate Sirve para anular el atributo "novalidate" en el elemento de formulario. Este atributo es compatible con los elementos input y button.
formtarget Sirve para anular el atributo de destino en el elemento de formulario. Este atributo es compatible con los elementos input y button.

El objeto FormData

Una de las mejoras de XMLHttpRequest es la incorporación del objeto FormData. Gracias al objeto FormData, puedes crear y enviar un conjunto de pares de valores/claves y, de forma opcional, archivos mediante XMLHttpRequest. Al utilizar esta técnica, los datos se envían en el mismo formato que si los enviaras a través del método de formulario submit() con el tipo de codificación multipart/form-data.

FormData te ofrece una forma de crear formularios en HTML sobre la marcha utilizando JavaScript y luego enviarlos mediante XMLHttpRequest.send(). A continuación se indica un sencillo ejemplo:

var formData = new FormData();
formData.append("part_num", "123ABC"); 
formData.append("part_price", 7.95);
formData.append("part_image", somefile)

var xhr = new XMLHttpRequest();
xhr.open("POST", "http://some.url/");  
xhr.send(formData);

También puedes utilizar el objeto FormData para añadir datos adicionales a un formulario existente antes de enviarlo.

var formElement = document.getElementById("someFormElement");
var formData = new FormData(formElement);
formData.append("part_description", "The best part ever!");

var xhr = new XMLHttpRequest();
xhr.open("POST", "http://some.url/");
xhr.send(formData);

Validación basada en el navegador

Seamos sinceros. Validar datos de formularios es una tarea muy aburrida, pero debes realizarla de todas formas. Actualmente, para realizar la validación de formularios del cliente, probablemente escribes algún código de JavaScript personalizado o que utilizas una biblioteca para realizar acciones como comprobar entradas válidas o asegurarte de que todos los campos estén completos antes de enviar el formulario.

Si utilizas los nuevos atributos de entrada como required y pattern en combinación con selectores de pseudoclases de CSS puede que te resulte más fácil escribir las comprobaciones y mostrar comentarios al usuario. También existen otras técnicas de validación que te permiten utilizar JavaScript para establecer mensajes y reglas de validación personalizadas o determinar si un elemento no es válido y por qué.

El atributo "required"

Si el atributo required está presente, el campo debe contener un valor a la hora de enviar el formulario. A continuación, se muestra un ejemplo de un campo de entrada para una dirección de correo electrónico obligatoria que garantiza que el campo contenga un valor y que ese valor sea una dirección de correo electrónico válida, tal y como se explica en esta página.

<input type="email" id="email_addr" name="email_addr" required />

El atributo "pattern"

El atributo pattern especifica una expresión regular utilizada para validar un campo de entrada. Este ejemplo representa un campo de entrada de texto para un número de pieza. Para el objetivo del ejemplo, diremos que un número de pieza está formado por tres letras en mayúscula seguidas de cuatro dígitos. El uso de los atributos required y pattern garantiza que el campo contenga un valor y que ese valor coincida con el formato adecuado para un número de pieza. Si el usuario pasa el ratón por encima del campo, se mostrará el mensaje del atributo "title".

<input type="text" id="part" name="part" required pattern="[A-Z]{3}[0-9]{4}"
       title="Part numbers consist of 3 uppercase letters followed by 4 digits."/>

Según el ejemplo anterior, también puedes destacar el campo de entrada en rojo si se introduce un número de pieza no válido. Para ello, añade esta hoja de estilo CSS para que establezca un borde rojo alrededor del campo de entrada si el valor no es válido.

:invalid {
  border: 2px solid #ff0000;
}

El atributo "formnovalidate"

El atributo formnovalidate se puede aplicar a los elementos input o button. Si se encuentra presente, se inhabilitará la validación del envío del formulario. A continuación, se muestra un ejemplo en el que para enviar un formulario a través del botón "Enviar" se necesita una entrada válida, pero para enviarlo mediante el botón "Guardar" no es necesaria.

<input type="text" id="part" name="part" required pattern="[A-Z]{3}[0-9]{4}"
       title="Part numbers consist of 3 uppercase letters followed by 4 digits."/>
<input type="submit" formnovalidate value="Save">
<input type="submit" value="Submit">

El API de validación restringida

El API de validación restringida te ofrece potentes herramientas para realizar una validación personalizada. El API te permite realizar acciones como configurar un error personalizado, comprobar si un elemento es válido y determinar la razón por la que no lo es. A continuación, se muestra un ejemplo que muestra un error personalizado si los valores de dos campos no coinciden.

<label>Email:</label>
<input type="email" id="email_addr" name="email_addr">

<label>Repeat Email Address:</label>
<input type="email" id="email_addr_repeat" name="email_addr_repeat" oninput="check(this)">

<script>
function check(input) {
  if (input.value != document.getElementById('email_addr').value) {
    input.setCustomValidity('The two email addresses must match.');
  } else {
    // input is valid -- reset the error message
    input.setCustomValidity('');
  }
}
</script>

Unión de todos los elementos

A continuación, se muestra un ejemplo de un formulario de solicitud de reserva que agrupa diferentes tipos de entrada, validación de formularios y estilos y selectores CSS.

99,00USD

Este es el código HTML y JavaScript del formulario:

<form oninput="total.value = (nights.valueAsNumber * 99) + 
 ((guests.valueAsNumber - 1) * 10)">

  <label>Full name:</label>
  <input type="text" id="full_name" name="full_name" placeholder="Jane Doe" required>

  <label>Email address:</label>
  <input type="email" id="email_addr" name="email_addr" required>

  <label>Repeat email address:</label>
  <input type="email" id="email_addr_repeat" name="email_addr_repeat" required 
   oninput="check(this)">

  <label>Arrival date:</label>
  <input type="date" id="arrival_dt" name="arrival_dt" required>
  
  <label>Number of nights (rooms are $99.00 per night):</label>
  <input type="number" id="nights" name="nights" value="1" min="1" max="30" required>

  <label>Number of guests (each additional guest adds $10.00 per night):</label>
  <input type="number" id="guests" name="guests" value="1" min="1" max="4" required>

  <label>Estimated total:</label>
  $<output id="total" name="total">99</output>.00
  <br><br>

  <label>Promo code:</label>
  <input type="text" id="promo" name="promo" pattern="[A-Za-z0-9]{6}" 
   title="Promo codes consist of 6 alphanumeric characters.">

  <input type="submit" value="Request Reservation" /> 
</form>

<script>
function check(input) {
  if (input.value != document.getElementById('email_addr').value) {
    input.setCustomValidity('The two email addresses must match.');
  } else {
    // input is valid -- reset the error message
    input.setCustomValidity('');
  }
}
</script>

Esta es la hoja de estilo CSS que acompaña al código del formulario:

:invalid { 
  border-color: #e88;
  -webkit-box-shadow: 0 0 5px rgba(255, 0, 0, .8);
  -moz-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
  -o-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
  -ms-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
  box-shadow:0 0 5px rgba(255, 0, 0, .8);
}

:required {
  border-color: #88a;
  -webkit-box-shadow: 0 0 5px rgba(0, 0, 255, .5);
  -moz-box-shadow: 0 0 5px rgba(0, 0, 255, .5);
  -o-box-shadow: 0 0 5px rgba(0, 0, 255, .5);
  -ms-box-shadow: 0 0 5px rgba(0, 0, 255, .5);
  box-shadow: 0 0 5px rgba(0, 0, 255, .5);
}

form {
  width:300px;
  margin: 20px auto;
}

input {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  border:1px solid #ccc;
  font-size:20px;
  width:300px;
  min-height:30px;
  display:block;
  margin-bottom:15px;
  margin-top:5px;
  outline: none;

  -webkit-border-radius:5px;
  -moz-border-radius:5px;
  -o-border-radius:5px;
  -ms-border-radius:5px;
  border-radius:5px;
}

input[type=submit] {
  background:none;
  padding:10px;
}

Recursos

Comments

0