Formulaires : une méthode de validation qui a de l’avenir

Par Ryan Seddon

La validation des formulaires a toujours été une affaire délicate dès les débuts du web. D’abord, il y a eu les rapports d’erreurs de la validation côté serveur. Ensuite, on a évolué vers la validation côté client pour vérifier les résultats en ligne. Aujourd’hui, nous avons affaire au géant en marche que représentent les normes HTML5 et CSS3 : le chapitre sur les formulaires d’HTML5 propose de nouveaux types de saisies et de nouveaux attributs qui rendent possibles les contraintes de validation. Le module basique d’interface utilisateur de CSS3 fournit plusieurs pseudo-classes qui nous aident à appliquer des styles à ces états de validation et à modifier l’apparence d’un champ de saisie en fonction des actions de l’utilisateur. Voyons comment combiner les deux pour créer un validateur de formulaire basé sur les CSS et qui serait compatible avec un nombre suffisant de navigateurs.

Plus un utilisateur est guidé en temps réel lorsqu’il remplit un champ de formulaire, moins il risque de faire des erreurs. Regardez cet exemple de validation de formulaire en CSS3, dans un navigateur qui prend en charge les pseudo-classes UI de CSS3 (UI pour User Interface = Interface Utilisateur, NdT) comme Chrome 4+, Safari5+ ou encore Opera 9.6+. J’utilise des pseudo-classes UI de CSS3 et des attributs de formulaire en HTML5 pour effectuer une validation basée sur les CSS. Voyons comment tout cela fonctionne.

Les pseudo-classes UI de CSS3

Le module UI propose plusieurs pseudo-classes qui permettent d’appliquer un style aux champs de formulaires selon leur état. Leur sens en français est ici indiqués entre parenthèses.

Dans la démonstration ci-dessus, j’emploie les pseudo-classes required, invalid et valid pour que la validation puisse se faire via la CSS :

input:focus:required:invalid {
  background: pink url(ico_validation.png) 379px 3px no-repeat;
}
input:required:valid {
  background-color: #fff;
  background-position: 379px -61px;
}

Puisque nous voulons attendre qu’un champ soit sélectionné avant de signaler qu’il est invalide, nous utilisons la pseudo-classe focus pour déclencher le style qui indique le caractère non valide de l’entrée. (Bien entendu, il serait peu judicieux en termes de design de marquer d’emblée comme non valides tous les champs restant à compléter).

Dès qu’un champ obligatoire non valide est sélectionné, le style déclenche l’apparition de l’image du point d’exclamation, qui signifie à l’utilisateur qu’il est nécessaire de remplir le champ. Une fois que les contraintes de validation de ce champ sont satisfaites, la pseudo-classe valid entre en action. On retire alors la pseudo-classe focus, afin que soit maintenue la coche verte qui indique un champ correct.

Les noms des pseudo-classes dont j’ai fait la liste plus haut sont explicites. Les pseudo-classes in-range et out-of-range sont à combiner avec les attributs min et max, qu’il s’agisse d’entrer une valeur par curseur, par saisie de nombre, ou pour tout autre type qui accepte ces attributs. Par exemple, si un utilisateur saisit une valeur qui sort des limites prévues (out-of-range), il est possible d’utiliser la pseudo-classe pour modifier le style afin de signaler cette situation ; on peut faire de même pour les valeurs qui sont bien dans les limites (in-range).

Pour le moment, seul Opera supporte les pseudo-classes in-range et out-of-range. D’autres navigateurs suivront rapidement.

De nouveaux types et attributs à notre disposition

Les formulaires HTML5 comportent désormais de nouveaux types d’entrées, tels que email, url et number. Par exemple, email ne déclenche la pseudo-classe valid que lorsque l’utilisateur saisit une adresse email valide ; le principe est le même pour number et pour url. Les contraintes de validation d’une URL varient selon les navigateurs. Sous Opera, il suffit de saisir « http:// » pour valider le champ de l’URL. Chrome réclame la saisie de « http://w », tandis que Safari n’exige que « http: ».

Il existe aussi quelques attributs qui peuvent faciliter la validation, comme placeholder, required, maxlength, pattern, min, max, et step :

<input id="code_postal" name="code_postal" type="number" min="1001" max="8000"
maxlength="4" required />

Le champ code_postal exploite le nouveau type number et certains des nouveaux attributs. En Australie, un code postal ne peut être composé que de quatre chiffres, donc j’indique cette limite avec l’attribut maxlength (= longueur maximale). Comme je veux aussi limiter la plage des nombres pouvant être saisis, j’utilise les attributs min et max pour fixer les limites. L’attribut required (= obligatoire) parle de lui-même.

Il est possible d’utiliser l’attribut step (= un pas) pour ajouter une contrainte en plus des indications de min et max. Par défaut, step est fixé à 1, ce qui permet de valider n’importe quel nombre situé entre les valeurs min et max, avec une incrémentation d’au moins 1. En passant step à 100, la validation ne se fera que si l’utilisateur saisit une valeur avec une incrémentation de 100. Par exemple, si je fixe à 100 la valeur de l’attribut step sur mon champ code_postal, 1001 sera une entrée valide, tout comme 1101, 1201, 1301, etc.

Trouver un modèle

Pour déclencher la pseudo-classe invalid dans des situations plus complexes, comme pour la saisie d’un numéro de téléphone rudimentaire, il est possible d’employer l’attribut pattern (= modèle) qui va nous permettre d’appliquer au champ une expression régulière.

<input type="tel" id="tel" name="tel" pattern="d{10}" placeholder=
"Veuillez saisir un numéro de téléphone à 10 chiffres" required />

L’expression régulière ci-dessus est assez simple. Elle énonce ceci : « Je n’accepterai qu’une saisie de dix chiffres exactement, et rien d’autre ». Ainsi, le champ restera non valide tant que les exigences de l’expression régulière ne sont pas satisfaites. Remarquez l’emploi de l’attribut placeholder pour donner une petite indication à l’utilisateur.

Les possibilités de l’attribut pattern peuvent aller plus loin encore, avec une expression régulière plus complexe, comme ici pour le champ mot_de_passe :

<input id="mot_de_passe" name="mot_de_passe" type="password" title="Au moins 8 caractères, un chiffre, une lettre majuscule et une minuscule" required
pattern="(?=^.{8,}$)((?=.*d)|(?=.*W+))(?![.n])(?=.*[A-Z])
(?=.*[a-z]).*" />

Puisque nous imposons des conditions spécifiques qui limitent ce que peut saisir l’utilisateur, l’obligeant ainsi à créer un mot de passe plus sûr, nous établissons une expression régulière complexe comme ci-dessus. Le mot de passe doit contenir au moins huit caractères, dont un chiffre, une lettre minuscule et une majuscule.

Afin d’aider l’utilisateur à remplir ces conditions, j’emploie l’attribut title pour l’aider à comprendre exactement en quoi elles consistent. J’évite ici d’utiliser placeholder car je dois donner un certain nombre d’explications, alors que placeholder ne doit être employé que pour de brèves indications.

Ajouter d’autres indications

Si l’utilisateur ne passe jamais son pointeur au-dessus des champs, mais se contente plutôt de passer de l’un à l’autre avec la touche Tab, il peut très bien ne jamais remarquer les instructions supplémentaires fournies par l’attribut title. Notez que sur les champs tel, code_postal et mot_de_passe, un message d’aide apparaît lorsqu’un champ exige des instructions complémentaires.

<input id="mot_de_passe" type="password"  /><p class="validation01">
  <span class="invalid">Au moins 8 caractères, un chiffre, une lettre majuscule et une minuscule</span>
  <span class="valid">Votre mot de passe remplit nos conditions, merci.
</span>
</p>

Le balisage ci-dessus intègre un conteneur supplémentaire qui contient à la fois les boîtes d’indications pour valid et pour invalid. Ainsi, quand l’utilisateur entre des données non valides dans le champ, l’information complémentaire vient l’aider. Mais quand il a saisi ce qu’il fallait, notre message ainsi que la petite coche verte le rassure en lui indiquant qu’il a rempli le champ correctement.

.validation01 {
  background: red;
  color: #fff;
  display: none;
  font-size: 12px;
  padding: 3px;
  position: absolute;
  right: -110px;
  text-align: center;
  top: 0;
  width: 100px;
}
input:focus + .validation01 {
  display: block;
}
input:focus:required:valid + .validation01 {
  background: green;
}
input:focus:required:valid + .validation01 .invalid {
  display: none;
}
input:focus:required:invalid + .validation01 .valid {
  display: none;
}

Pour montrer ou cacher le message d’aide selon l’état du champ, je peux cibler le champ en reliant les pseudo-classes grâce au combinateur-enfant adjacent qui ciblera l’indication adaptée. Une fois le champ correctement renseigné, le fond passe au vert et le message de validation apparaît.

L’approche actuelle et l’expérience utilisateur

On peut émettre un sérieux reproche vis-à-vis du fonctionnement de la pseudo-classe invalid, lorsque le remplissage d’un champ est requis et qu’il a des conditions supplémentaires à satisfaire : par exemple, quand on exige que le champ soit rempli ET que la saisie soit du type email. Dans la mesure où le champ restera non valide jusqu’à ce que les conditions soient remplies, il ira chercher les styles d’invalidité. Dans le cas présent, le champ se retrouverait non valide d’emblée et s’afficherait en rouge avec un message d’erreur avant même que l’utilisateur ait saisi quoi que ce soit. C’est pourquoi nous employons la pseudo-classe focus pour que les styles d’invalidité s’affichent uniquement quand un champ est sélectionné. Mais cette méthode n’est pas idéale, car si un utilisateur sort de ce champ sans avoir rempli les conditions de validation, le champ n’indiquera plus la présence d’un problème tant que l’utilisateur ne l’aura pas à nouveau sélectionné.

Une solution à ce problème consisterait à ajouter la pseudo-classe indeterminate qui est disponible avec les saisies de type bouton radio (radio) ou case à cocher (checkbox). Techniquement, cela signifie qu’un champ qui a d’autres conditions que son caractère obligatoire ne sera alors ni valide ni invalide, mais indéterminé. Cette idée réglerait la question de l’invalidité immédiate et nous permettrait d’appliquer un style au champ de façon optimale selon son état de validation.

Par ailleurs, nous pouvons appliquer des fonctions assez étendues sans employer de Javascript. Nous pouvons dire quel est l’état d’un champ, s’il est obligatoire, lui dire de se conformer à un certain schéma avec des expressions régulières, lui donner des valeurs maximales et minimales, et plus encore. Et si cela ne suffisait pas ? Et si on voulait aller plus loin ? Eh bien nous avons de la chance : le chapitre du HTML5 sur les formulaires propose aussi une spécification de l’API (API : interface de programmation, NdT) de contrainte de validation.

L’API de contrainte de validation

En plus de proposer tous ces nouveaux attributs, tous ces types de saisies et les pseudo-classes CSS3, le chapitre du HTML5 sur les formulaires spécifie une API JavaScript très simple qui va nous permettre de pousser plus loin les capacités de validation des formulaires, grâce à des méthodes, des attributs et des événements fort utiles qui y sont intégrés. Jetez un œil à la démonstration améliorée, qui exploite les possibilités de l’API de contrainte de validation.

Chaque champ de formulaire possède un nouvel attribut appelé validity. Cet attribut de validité renvoie un objet ValidityState qui représente le ou les état(s) de validité actuel(s) d’un élément. L’objet ValidityState contient plusieurs attributs booléens qui identifient l’état de validité dans lequel se trouve l’élément. Pour simplifier, il s’agit d’une série de réponses en vrai/faux qui indiquent au développeur ce qui ne va pas dans un champ donné :

Et ce n’est pas fini...

L’événement invalid est un autre outil bien commode. Il est invoqué par le champ de saisie tant que celui-ci reste invalide. Nous pouvons donc y attacher un comportement et, dans notre cas, modifier le style du champ pour refléter son état actuel.

De plus, la méthode checkValidity() peut être exécutée soit sur un champ individuel, soit sur l’ensemble du formulaire, et elle renverra true ou false. L’exécution de cette méthode déclenchera aussi par voie de programme l’événement invalid pour tous les champs non valides (ou sur un seul élément si la méthode est exécutée sur un seul champ).

Je veux une démo

Reprenons notre démo précédente, afin de l’améliorer avec l’API de validation de contrainte. Grâce à ce que nous a appris Luke Wroblewski dans son article Inline Validation in Web Forms, et grâce à nos propres découvertes, nous sommes en mesure d’appliquer toutes ces idées à notre formulaire pour que l’expérience de validation en ligne soit optimale.

Premier élément que nous pouvons régler : l’application systématique du style « erreur » aux champs non valides. Au lieu d’appliquer immédiatement un style au champ pour indiquer à l’utilisateur qu’il ne remplit pas les conditions, on va plutôt attendre qu’il ait quitté le champ pour indiquer le problème.

Si les conditions sont satisfaites alors que le champ est toujours actif, nous informons instantanément l’utilisateur que le champ est correctement rempli. Pour cela, nous y attachons l’événement de saisie pour vérifier si le champ est valide. Dès qu’il l’est, nous mettons à jour les styles pour afficher immédiatement l’information.

Si un champ contient des valeurs incorrectes, et si l’utilisateur passe au suivant, l’événement blur (qui se produit lorsque l’élément perd le focus, NdT) va vérifier la validité du champ, puis appliquer les styles d’erreur pour informer l’utilisateur qu’il y a un problème. Ces styles resteront en place jusqu’à ce que les conditions soient remplies.

Et pour les navigateurs anciens ?

Toutes ces idées sont assez récentes, et la question de la compatibilité avec les navigateurs se pose : même si cette compatibilité est globalement bonne, il est irréaliste de penser qu’elle serait suffisante dans un environnement de production réel, qui doit prendre en compte les navigateurs plus anciens. C’est là que le script que j’ai écrit tombe à pic.

Pour les navigateurs qui ne prennent pas en charge le chapitre du HTML5 sur les formulaires et l’API de contrainte de validation, le script vient proposer une émulation de cette fonctionnalité. Pour les navigateurs qui sont compatibles avec ces éléments, le script le détecte et renvoie à la fonctionnalité d’origine. Jetez un œil à la démonstration qui a été mise à jour en y incorporant le nouveau script. Testez-la sous IE ou Firefox pour voir si cela fonctionne comme avec les navigateurs qui offrent un support natif.

Prise en charge par les navigateurs

Ce script a été testé avec succès dans les navigateurs suivants :

Les fonctions suivantes sont émulées dans le script :

Validation à gogo !

La prise en charge des formulaires HTML5 et du module CSS3 UI par les navigateurs commence à progresser. Opera 9 a montré le chemin en implémentant les formulaires Web 2.0 avant même qu’ils soient intégrés au chapitre du HTML5 sur les formulaires, mais ce navigateur ne supporte le module CSS3 UI qu’à partir de la version 9.6. Chrome est compatible depuis la version 4, Safari le fournit depuis peu dans sa version 5, Firefox doit l’ajouter dans sa prochaine version 4 (beta) ; et IE9, s’il continue à progresser dans ce sens, devrait aussi l’intégrer à l’une de ses prochaines versions.

Il est possible de réaliser de grandes choses avec les nouveaux modules et chapitres de CSS3 et d’HTML5. Au fur et à mesure que la prise en charge dans les navigateurs s’améliorera, ces types de techniques vont devenir des options viables qui pourront répondre aussi bien à une validation simple qu’à une validation complexe des formulaires.


Translated with the permission of A List Apart and the author[s].

Fiche technique

À propos de l'auteur

Ryan Seddon (@ryanseddon) est un développeur frontend qui vit en Australie, à Melbourne. Il adore tripatouiller CSS et JavaScript et faire de nouvelles découvertes techniques. Vous pouvez les trouver, accompagnées d’autres articles, sur son blog : The CSS Ninja.

Articles similaires

Voici la liste des dix articles les plus récents en rapport avec cet article :

CSS

Ergonomie

© 2001-2016 Pompage Magazine et les auteurs originaux - Hébergé chez Nursit.com ! - RSS / ATOM - About this site