Créez des formulaires fabuleux avec HTML5

Jusqu'à présent, les formulaires ne provoquaient pas un enthousiasme excessif, mais HTML5 apporte des améliorations importantes, autant pour les développeurs qui les créent que pour les utilisateurs qui les remplissent. Ces nouveautés concernent les éléments de formulaires, les attributs, les types de champs, la validation par le navigateur, des styles CSS3 et l'objet FormData qui rendent l'utilisation des formulaires plus agréable et conviviale.

Cet article est la traduction de Making Forms Fabulous with HTML5, publié sur le site HTML5 Rocks par Jan Kleinert.

2 commentaires Donner une note à l'article (5)

Article lu   fois.

Les trois auteurs et traducteur

Site personnel

Traducteur : Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

Compatibilité des navigateurs

Au moment de la rédaction de cet article (NDT Juin 2011), le support des nouveaux éléments et champs de formulaire ainsi que leurs attributs varie largement en fonction des navigateurs. Même parmi ceux supportant une fonctionnalité donnée, le comportement peut être différent d'un navigateur à l'autre. En fait, le support des formulaires HTML5 est en constante et rapide évolution. Lors de la rédaction de cet article, ces tableaux étaient les plus à jour que j'ai pu trouver.

Récapitulatif des nouveautés

Nouveaux éléments

HTML5 introduit cinq nouveaux éléments de formulaire.

Élément Rôle Notes
progress Représente la progression d'une opération. Par exemple, l'élément progress peut correspondre à la progression de l'envoi d'un fichier.
meter Représente une mesure scalaire dans un intervalle déterminé. L'élément meter peut servir par exemple à représenter une valeur comme une température ou un poids.
datalist Représente un ensemble d'options prédéfinies qui peuvent être utilisées avec le nouvel attribut list de la balise input pour créer un menu déroulant de valeurs possibles. Lorsque l'input lié à datalist prend le focus, les suggestions correspondant aux options apparaissent.
keygen Permet la génération de clés. Lorsque le formulaire est soumis, la clé privée est stockée par le navigateur et la clé publique est envoyée au serveur.
output Affiche le résultat d'un calcul. Peut par exemple servir à afficher la somme de deux champs numériques.

Nouveaux types de champs

HTML5 introduit treize nouveaux types de champs. S'ils ne sont pas reconnus par le navigateur, celui-ci les affichera comme des champs texte simples.

Type Rôle Notes
tel Pour renseigner un numéro de téléphone. L'attribut tel ne définit pas de format spécifique, si vous souhaitez forcer un format particulier, vous devrez utiliser l'attribut pattern ou la méthode setCustomValidity().
search Permet d'indiquer à l'utilisateur qu'il s'agit d'un champ de recherche. La différence avec un input de type text est purement stylistique. L'utilisation d'un type search va permettre au navigateur d'afficher le champ dans un style approprié.
url Pour renseigner une URL. Ce type de champ est destiné à une unique URL absolue, ce qui laisse un large choix d'entrées possibles.
email Pour renseigner une ou plusieurs adresses e-mail. Si l'attribut multiple est présent, plusieurs adresses, séparées par des virgules, peuvent être entrées.
datetime Pour renseigner une date et une heure sur le fuseau UTC.  
date Pour renseigner une date.  
month Pour renseigner une date avec une année et un mois.  
week Pour renseigner une date à partir du numéro de semaine de l'année considérée. Un exemple serait 2011-W05 pour la cinquième semaine de 2011.
time Pour renseigner une heure comprenant l'heure, les minutes, les secondes et les fractions de seconde.  
datetime-local Pour renseigner une date et une heure sans considération de fuseau.  
number Pour renseigner une valeur numérique. Les valeurs sont des nombres à virgule flottante.
range Pour renseigner une valeur numérique dans un intervalle donné. L'implémentation pour les navigateurs supportant ce type est un curseur.
color Pour renseigner une couleur. La valeur doit être une valeur de couleur valide en minuscules.

Nouveaux attributs

De nouveaux attributs concernant les formulaires et leurs éléments ont aussi été introduits par HTML5.

Attribut Rôle Notes
autofocus Donne le focus à l'élément au chargement de la page. autofocus peut être appliqué aux balises input, select, textarea et button.
placeholder Donne une indication à l'utilisateur sur le type de donnée à entrer. La valeur de l'attribut placeholder est affichée jusqu'à ce que le champ prenne le focus ainsi qu'à la perte du focus si le champ est vide. S'applique aux balises input et textarea.
form Précise à quel(s) formulaire(s) est attaché le champ. En utilisant l'attribut form, le champ peut être placé n'importe où dans la page, même en dehors des balises <form>. Un même champ peut ainsi être associé à plusieurs formulaires.
required Attribut booléen indiquant que le champ est obligatoire. Cet attribut sert essentiellement pour les vérifications côté navigateur sans utiliser JavaScript.
autocomplete Attribut booléen indiquant si les suggestions de précédentes saisies doivent être affichées. Le navigateur retient les saisies associées à un champ et les propose en suggestion lors de la saisie, cet attribut permet de désactiver cette fonctionnalité.
pattern Permet de préciser une expression régulière que doit satisfaire la saisie. Lorsque vous utilisez cet attribut, n'oubliez pas d'ajouter un attribut title pour indiquer à l'utilisateur le format attendu.
dirname La valeur de cet attribut permet d'envoyer à la soumission du formulaire un paramètre indiquant le sens d'écriture. Le sens d'écriture peut être "ltr" ou "rtl". Cette valeur est envoyée avec les autres champs du formulaire si l'attribut est précisé.
novalidate Désactive les vérifications du formulaire avant de l'envoyer.  
formaction Permet de modifier l'attribut action du formulaire. Cet attribut est valable pour les éléments input (de type submit) et button.
formenctype Permet de modifier l'attribut enctype du formulaire. Cet attribut est valable pour les éléments input (de type submit) et button.
formmethod Permet de modifier l'attribut method du formulaire. Cet attribut est valable pour les éléments input (de type submit) et button.
formnovalidate Permet de modifier l'attribut novalidate du formulaire. Cet attribut est valable pour les éléments input (de type submit) et button.
formtarget Permet de modifier l'attribut target du formulaire. Cet attribut est valable pour les éléments input (de type submit) et button.

L'objet FormData

L'une des améliorations apportées à XMLHttpRequest est l'ajout de l'objet FormData. Avec cet objet, vous pouvez créer et envoyer des paires clé/valeur (optionnellement, des fichiers) avec XMLHttpRequest. Avec cette technique, vous pouvez envoyer des données au même format que si vous aviez validé un formulaire à l'aide de la méthode submit() de l'objet form avec l'encodage multipart/form-data.

L'objet FormData vous permet donc de créer des formulaires à la volée avec JavaScript puis de les soumettre en utilisant XMLHttpRequest.send(). Voici un exemple d'utilisation :

 
Sélectionnez
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);

Vous pouvez aussi aussi utiliser FormData pour ajouter des données à un formulaire existant avant de le soumettre :

 
Sélectionnez
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);

Validation par le navigateur

Soyons honnêtes., la validation des données d'un formulaire est une tâche assez pénible, mais nous devons malgré tout la faire. Actuellement, pour valider les données d'un formulaire côté client, vous avez probablement codé vos propres fonctions JavaScript ou utilisé une bibliothèque. Cela afin de vérifier la validité du format de certaines entrées ou que les champs obligatoires ont bien été remplis avant d'envoyer les données au serveur.

Les nouveaux attributs comme required ou pattern, utilisés conjointement avec les pseudoclasses CSS facilitent grandement ces vérifications et l'affichage des informations utiles à l'utilisateur. D'autres techniques plus avancées permettent d'utiliser JavaScript pour définir des règles personnalisées de validation et les messages associés, ou de déterminer si un élément est invalide et pourquoi.

L'attribut required

Si l'attribut required est présent, alors le champ en question doit contenir une valeur lorsque le formulaire est soumis. Voici un exemple de champ input concernant une adresse e-mail obligatoire et permettant de vérifier que l'adresse est bien renseignée et valide selon les critères définis ici :

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

L'attribut pattern

L'attribut pattern permet de définir une expression régulière qui sera utilisée pour déterminer si la saisie est conforme au format attendu. L'exemple suivant correspond à un champ texte requis et représentant un code particulier. Dans l'exemple, nous souhaitons que ce code soit composé de trois lettres majuscules suivies de quatre chiffres. Les attributs required et pattern permettent de s'assurer que le champ sera rempli au format souhaité lors de la soumission. Enfin, lors du survol du champ, l'utilisateur verra apparaître un message correspondant à l'attribut title lui indiquant le format attendu.

 
Sélectionnez
<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."/>

À partir de l'exemple précédent, on peut ajouter une bordure rouge à l'input tant que le champ ne contient pas de saisie valide. Pour cela, nous ajoutons le code CSS suivant pour créer la bordure rouge si le champ est invalide :

 
Sélectionnez
:invalid {
  border: 2px solid #ff0000;
}

L'attribut formnovalidate

L'attribut formnovalidate s'applique aux input et button de type submit. S'il est présent, alors la validation par le navigateur sera désactivée. Dans l'exemple suivant, la validation du formulaire est effectuée en cliquant sur "Submit" mais ne l'est pas en cliquant sur "Save".

 
Sélectionnez
<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">

L'API de validation

L'API de validation met à votre disposition des outils puissants permettant de gérer une validation personnalisée des formulaires. Cette API permet de déterminer des messages d'erreurs, de vérifier si un élément est valide et de préciser la raison pour laquelle il est invalide. Dans l'exemple suivant, nous affichons un message personnalisé si les valeurs de deux champs sont différentes.

 
Sélectionnez
<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>

Un exemple récapitulatif

Voici un exemple de formulaire de réservation qui permet d'assembler les différents éléments déjà vus : nouveaux types d'input et leurs attributs, validation de formulaire et mise en forme CSS avec les sélecteurs adaptés.

Image non disponible
Voir le formulaire en ligne

Voici les codes HTML, CSS et JavaScript du formulaire :

 
Sélectionnez
<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8" />
    <title>Formulaire HTML5</title>
    <style>
        body{
          background-image: url(background.png);
          font-family: 'Open Sans',sans-serif;
          font-weight: 400;
          font-size: 13px;
        }
 
        :invalid { 
          background-color: #F0DDDD;
          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;
          cursor: pointer;
        }
 
        label{
          cursor: pointer;
        }
    </style>
</head>
<body>
    <form oninput="total.value = (nights.valueAsNumber * 99) + 
     ((guests.valueAsNumber - 1) * 10)">
 
      <label>Nom complet :</label>
      <input type="text" id="full_name" name="full_name" placeholder="Jane Doe" required>
 
      <label>Adresse e-mail :</label>
      <input type="email" id="email_addr" name="email_addr" required>
 
      <label>Confirmez l'adresse e-mail :</label>
      <input type="email" id="email_addr_repeat" name="email_addr_repeat" required 
       oninput="check(this)">
 
      <label>Date d'arrivée :</label>
      <input type="date" id="arrival_dt" name="arrival_dt" required>
 
      <label>Nombre de nuitées (99 € par nuit) :</label>
      <input type="number" id="nights" name="nights" value="1" min="1" max="30" required>
 
      <label>Nombre d'invités (10 € par invité supplémentaire) :</label>
      <input type="number" id="guests" name="guests" value="1" min="1" max="4" required>
 
      <label>Total :</label>
      <output id="total" name="total">99</output>.00 €
      <br><br>
 
      <label>Code de promotion :</label>
      <input type="text" id="promo" name="promo" pattern="[A-Za-z0-9]{6}" 
       title="Le code de promotion contient six caractères alphanumériques.">
 
      <input type="submit" value="Effectuer la réservation" /> 
    </form>
 
    <script>
    function check(input) {
      if (input.value != document.getElementById('email_addr').value) {
        input.setCustomValidity('Les deux adresses e-mail ne correspondent pas.');
      } else {
        // le champ est valide : on réinitialise le message d'erreur
        input.setCustomValidity('');
      }
    }
    </script>
</body>
</html>

Voir l'exemple en ligne.

Ressources et remerciements

Cet article a été traduit avec l'aimable autorisation de Jan Kleinert.

L'article original : Making Forms Fabulous with HTML5 peut être vu sur le site HTML5 Rocks.

Nous tenons aussi à remercier ClaudeLELOUP et Gurdil le nain pour leur relecture attentive de cet article.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Licence Creative Commons
Le contenu de cet article est rédigé par Jan Kleinert et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.