Dans cet article, nous examinons les champs de formulaire HTML et les options de validation offertes par HTML5. Nous verrons également comment ces dernières peuvent être améliorées grâce à l’utilisation de CSS et de JavaScript.
Qu’est-ce que la Validation par Contraintes?
Chaque champ de formulaire a un but. Et ce but est souvent régi par contraintes — ou les règles gouvernant ce qui doit et ne doit pas être entré dans chaque champ de formulaire. Par exemple, un champ email
nécessitera une adresse email valide; un champ password
pourrait exiger certains types de caractères et avoir un nombre minimum de caractères requis; et un champ de texte pourrait avoir une limite sur le nombre de caractères pouvant être entrés.
Les navigateurs modernes ont la capacité de vérifier que ces contraintes sont respectées par les utilisateurs et peuvent les avertir lorsque ces règles ont été enfreintes. Cela s’appelle la validation par contraintes.
Validation côté client vs côté serveur
La plupart du code JavaScript écrit dans les premières années du langage traitait de la validation côté client des formulaires. Même aujourd’hui, les développeurs passent beaucoup de temps à écrire des fonctions pour vérifier les valeurs des champs. Est-ce encore nécessaire dans les navigateurs modernes? Probablement pas. Dans la plupart des cas, cela dépend vraiment de ce que vous essayez de faire.
Mais d’abord, voici un gros message d’avertissement:
La validation côté client est une commodité qui peut empêcher les erreurs courantes d’entrée de données avant qu’une application ne perde du temps et de la bande passante en envoyant des données à un serveur. Ce n’est pas un substitut à la validation côté serveur!
Toujours nettoyer les données côté serveur. Toutes les requêtes ne proviennent pas d’un navigateur. Même quand c’est le cas, il n’y a aucune garantie que le navigateur ait validé les données. Quiconque sait comment ouvrir les outils de développement d’un navigateur peut également contourner votre bien pensé HTML et JavaScript.
Champs de saisie HTML5
HTML propose :
<textarea>
pour les zones de texte multiligne<select>
pour une liste déroulante d’options<button>
pour … des boutons
Mais vous utiliserez le plus souvent <input>
:
<input type="text" name="username" />
L’attribut type
définit le type de contrôle, et il existe un large choix d’options:
type |
description |
---|---|
button |
a button with no default behavior |
checkbox |
a check/tick box |
color |
a color picker |
date |
a date picker for the year, month, and day |
datetime-local |
a date and time picker |
email |
an email entry field |
file |
a file picker |
hidden |
a hidden field |
image |
a button which displays the image defined by the src attribute |
month |
a month and year picker |
number |
a number entry field |
password |
a password entry field with obscured text |
radio |
a radio button |
range |
a slider control |
reset |
a button that resets all form inputs to their default values (but avoid using this, as it’s rarely useful) |
search |
a search entry field |
submit |
a form submission button |
tel |
a telephone number entry field |
text |
a text entry field |
time |
a time picker with no time zone |
url |
a URL entry field |
week |
a week number and year picker |
Le navigateur retombe sur text
si vous omettez l’attribut type
ou s’il ne prend pas en charge une option. Les navigateurs modernes ont une bonne prise en charge de tous les types, mais les anciens navigateurs afficheront toujours un champ d’entrée de texte.
D’autres attributs utiles de <input>
incluent:
attribute | description |
---|---|
accept |
file upload type |
alt |
alternative text for the image types |
autocomplete |
hint for field auto-completion |
autofocus |
focus field on page load |
capture |
media capture input method |
checked |
checkbox/radio is checked |
disabled |
disable the control (it won’t be validated or have its value submitted) |
form |
associate with a form using this ID |
formaction |
URL for submission on submit and image buttons |
inputmode |
data type hint |
list |
ID of <datalist> autocomplete options |
max |
maximum value |
maxlength |
maximum string length |
min |
minimum value |
minlength |
minimum string length |
name |
name of control, as submitted to server |
pattern |
a regular expression pattern, such as [A-Z]+ for one or more uppercase characters |
placeholder |
placeholder text when the field value is empty |
readonly |
the field is not editable, but it will still be validated and submitted |
required |
the field is required |
size |
the size of the control (often overridden in CSS) |
spellcheck |
set true or false spell-checking |
src |
image URL |
step |
incremental values in numbers and ranges |
type |
field type (see above) |
value |
the initial value |
Champs de sortie HTML
En plus des types d’entrée, HTML5 fournit des sorties en lecture seule :
output
: le résultat textuel d’un calcul ou d’une action de l’utilisateurprogress
: une barre de progression avec les attributsvalue
etmax
meter
: une échelle qui peut varier entre vert, ambre et rouge en fonction des valeurs définies pour les attributsvalue
,min
,max
,low
,high
etoptimum
.
Labels d’entrée
Les champs doivent avoir un <label>
associé, que vous pouvez entourer l’élément :
<label>your name <input type="text" name="name" /><label>
Ou lier le champ à l’étiquette en utilisant un attribut for
:
<label for="nameid">your name</label>
<input type="text" id="nameid" name="name" />
Les étiquettes sont importantes pour l’accessibilité. Vous avez peut-être rencontré des formulaires qui utilisent un placeholder
pour économiser de l’espace à l’écran :
<input type="text" name="name" value="" placeholder="your name" />
Le texte du placeholder disparaît une fois que l’utilisateur tape quelque chose – même un seul espace. Il est préférable de montrer une étiquette plutôt que de forcer l’utilisateur à se souvenir de ce que le champ demandait !
Comportements d’entrée
Les types de champs et les attributs de contrainte modifient le comportement d’entrée du navigateur. Par exemple, une entrée number
affiche un clavier numérique sur les appareils mobiles. Le champ peut afficher un curseur de retournement et les pressions de clavier haut/bas incrémenteront et décrémenteront les valeurs.
La plupart des types de champs sont évidents, mais il y a des exceptions. Par exemple, les cartes de crédit sont numériques, mais le spinner de décrément/incrément est inutile et il est trop facile de presser vers le haut ou vers le bas lors de la saisie d’un numéro à 16 chiffres. Il est préférable d’utiliser un type texte
standard, mais de définir l’attribut inputmode
sur numérique
, ce qui affiche un clavier approprié. La configuration de autocomplete="cc-number"
suggère également toutes les cartes de crédit préconfigurées ou précédemment entrées.
L’utilisation du bon type de champ type
et autocorrect
offre des avantages qui seraient difficiles à obtenir en JavaScript. Par exemple, certains navigateurs mobiles peuvent :
- importer les détails de la carte de crédit en scannant une carte à l’aide de la caméra
- importer codes à usage unique envoyés par SMS
Validation automatique
Le navigateur garantit qu’une valeur d’entrée respecte les contraintes définies par les attributs type
, min
, max
, step
, minlength
, maxlength
, pattern
et required
. Par exemple :
<input type="number" min="1" max="100" required />
Tentative de soumission d’une valeur vide empêche la soumission du formulaire et affiche le message suivant dans Chrome :
Les curseurs ne permettront pas de valeurs en dehors de la plage de 1 à 100. Des messages de validation similaires apparaissent si vous tapez une chaîne qui n’est pas un nombre. Tout cela sans une seule ligne de JavaScript.
Vous pouvez arrêter la validation du navigateur en :
- ajoutant un attribut
novalidate
à l’élément<form>
- ajoutant un attribut
formnovalidate
à un bouton de soumission ou à une image
Création d’entrées JavaScript personnalisées
Si vous écrivez un composant d’entrée de date basé sur JavaScript, arrêtez-vous et éloignez-vous de votre clavier !
Écrire des contrôles d’entrée personnalisés est difficile. Vous devez prendre en compte la souris, le clavier, le tactile, la parole, l’accessibilité, les dimensions de l’écran et ce qui se passe lorsque JavaScript échoue. Vous créez également une expérience utilisateur différente. Peut-être que votre contrôle est supérieur au sélecteur de date standard sur desktop, iOS et Android, mais l’interface utilisateur inconnue confondra certains utilisateurs.
Il y a trois raisons principales pour lesquelles les développeurs choisissent de créer des entrées basées sur JavaScript.
1. Les contrôles standard sont difficiles à styliser
Le style CSS est limité et nécessite souvent des astuces, telles que l’ajout d’un input avec les pseudo-éléments ::before
et ::after
de son étiquette. La situation s’améliore, mais interrogez toute conception qui privilégie la forme sur la fonction.
2. Les types modernes de <input>
ne sont pas pris en charge dans les anciens navigateurs
En substance, vous codez pour Internet Explorer. Les utilisateurs d’IE n’obtiendront pas un sélecteur de date mais peuvent toujours saisir des dates au format AAAA-MM-JJ
. Si votre client insiste, chargez un polyfill uniquement dans IE. Il n’est pas nécessaire de surcharger les navigateurs modernes.
3. Vous avez besoin d’un nouveau type d’entrée qui n’a jamais été implémenté auparavant
Ces situations sont rares, mais commencez toujours avec des champs HTML5 appropriés. Ils sont rapides et fonctionnent même avant que le script ne soit chargé. Vous pouvez améliorer progressivement les champs au besoin. Par exemple, un peu de JavaScript peut s’assurer qu’une date de fin d’événement de calendrier survient après une date de début.
En résumé : évitez de réinventer les contrôles HTML !
Style de Validation CSS
Vous pouvez appliquer les pseudo-classes suivantes aux champs d’entrée pour les styliser en fonction de l’état actuel :
selector | description |
---|---|
:focus |
the field with focus |
:focus-within |
an element contains a field with focus (yes, it’s a parent selector!) |
:focus-visible |
an element has focus owing to keyboard navigation, so a focus ring or more evident styling is necessary |
:required |
a field with a required attribute |
:optional |
a field without a required attribute |
:valid |
a field that has passed validation |
:invalid |
a field that has not passed validation |
:user-valid |
a field that has passed validation after the user has interacted with it (Firefox only) |
:user-invalid |
a field that hasn’t passed validation after the user has interacted with it (Firefox only) |
:in-range |
the value is within range on a number or range input |
:out-of-range |
the value is out of range on a number or range input |
:disabled |
a field with a disabled attribute |
:enabled |
a field without a disabled attribute |
:read-only |
a field with a read-only attribute |
:read-write: |
a field without a read-only attribute |
:checked |
a checked checkbox or radio button |
:indeterminate |
an indeterminate checkbox or radio state, such as when all radio buttons are unchecked |
:default |
the default submit button or image |
Vous pouvez styliser le texte placeholder
d’un champ d’entrée avec le pseudo-élément ::placeholder
:
/* placeholer bleu sur les champs email */
input[type="email"]::placeholder {
color: blue;
}
Les sélecteurs ci-dessus ont la même spécificité, donc l’ordre peut être important. Considérez cet exemple :
input:invalid { color: red; }
input:enabled { color: black; }
Les entrées invalides ont un texte rouge, mais cela n’est appliqué qu’aux entrées avec un attribut disabled
— donc toutes les entrées activées sont en noir.
Le navigateur applique les styles de validation au chargement de la page. Par exemple, dans le code suivant, chaque champ invalide reçoit une bordure rouge :
:invalid {
border-color: #900;
}
L’utilisateur est confronté à un ensemble intimidant de boîtes rouges avant d’interagir avec le formulaire. Afficher les erreurs de validation après la première soumission ou lorsqu’une valeur est modifiée offrira une meilleure expérience. C’est là que JavaScript intervient…
JavaScript et l’API de Validation des Contraintes
La API de Validation des Contraintes offre des options de personnalisation du formulaire qui peuvent améliorer le contrôle des champs HTML de base. Vous pourriez :
- arrêter la validation jusqu’à ce que l’utilisateur interagisse avec un champ ou soumette le formulaire
- afficher des messages d’erreur avec un style personnalisé
- fournir une validation personnalisée qui est impossible en HTML seul. C’est souvent nécessaire lorsque vous devez comparer deux entrées — comme lorsque vous entrez une adresse e-mail ou un numéro de téléphone, vérifiez que les champs « nouveau » et « confirmer » de mot de passe ont la même valeur, ou assurez-vous qu’une date vient après une autre.
Validation du Formulaire
Avant d’utiliser l’API, votre code devrait désactiver la validation par défaut et les messages d’erreur en définissant la propriété noValidate
du formulaire sur true
(le même effet que l’ajout d’un attribut novalidate
) :
const myform = document.getElementById('myform');
myform.noValidate = true;
Vous pouvez ensuite ajouter des gestionnaires d’événements — comme lorsque le formulaire est soumis :
myform.addEventListener('submit', validateForm);
Le gestionnaire peut vérifier que tout le formulaire est valide en utilisant les méthodes checkValidity()
ou reportValidity()
, qui renvoient true
lorsque tous les inputs du formulaire sont valides. (La différence est que checkValidity()
vérifie si des inputs sont soumis à la validation des contraintes.)
Les documents Mozilla expliquent:
Un événement
invalid
est également déclenché sur chaque champ invalide. Cela ne remonte pas : les gestionnaires doivent être ajoutés à chaque contrôle qui l’utilise.
// valider le formulaire à la soumission
function validateForm(e) {
const form = e.target;
if (form.checkValidity()) {
// le formulaire est valide - faire d'autres vérifications
}
else {
// le formulaire est invalide - annuler la soumission
e.preventDefault();
}
};
A valid form could now incur further validation checks. Similarly, an invalid form could have invalid fields highlighted.
Validation des champs
Les champs individuels ont les propriétés de validation des contraintes suivantes :
-
willValidate
: renvoietrue
si l’élément est candidat à la validation des contraintes. -
validationMessage
: le message de validation. Ce sera une chaîne vide si le champ est valide. -
valitity
: un objet ValidityState. Cela a une propriétévalid
définie surtrue
lorsque le champ est valide. Si elle estfalse
, l’une ou plusieurs des propriétés suivantes seronttrue
:ValidityState description .badInput
le navigateur ne peut pas comprendre l’entrée .customError
un message de validité personnalisé a été défini .patternMismatch
la valeur ne correspond pas à l’attribut pattern
spécifié.rangeOverflow
la valeur est supérieure à l’attribut max
.rangeUnderflow
la valeur est inférieure à l’attribut min
.stepMismatch
la valeur ne respecte pas les règles de l’attribut step
.tooLong
la longueur de la chaîne est supérieure à l’attribut maxlength
.tooShort
la longueur de la chaîne est inférieure à l’attribut minlength
.typeMismatch
la valeur n’est pas un email ou une URL valide .valueMissing
une valeur requise
est vide
Les champs individuels ont les méthodes de validation des contraintes suivantes:
setCustomValidity(message)
: définit un message d’erreur pour un champ invalide. Un message vide doit être passé lorsque le champ est valide, sinon le champ restera invalide indéfiniment.checkValidity()
: renvoietrue
si l’entrée est valide. La propriétévalitity.valid
fait la même chose, maischeckValidity()
déclenche également un événementinvalid
sur le champ, ce qui pourrait être utile.
La fonction de gestionnaire validateForm()
pourrait parcourir chaque champ et appliquer une classe invalid
à son élément parent le cas échéant:
function validateForm(e) {
const form = e.target;
if (form.checkValidity()) {
// le formulaire est valide - effectuer d'autres vérifications
}
else {
// le formulaire est invalide - annuler la soumission
e.preventDefault();
// appliquer la classe invalide
Array.from(form.elements).forEach(i => {
if (i.checkValidity()) {
// le champ est valide - supprimer la classe
i.parentElement.classList.remove('invalid');
}
else {
// le champ est invalide - ajouter la classe
i.parentElement.classList.add('invalid');
}
});
}
};
Supposons que votre HTML ait défini un champ email :
<div>
<label for="email">email</label>
<input type="email" id="email" name="email" required />
<p class="help">Please enter a valid email address</p>
</div>
Le script applique une classe invalid
au <div>
lorsque l’email n’est pas spécifié ou est invalide. Le CSS peut afficher ou masquer le message de validation lorsque le formulaire est soumis :
.help { display: none; }
.invalid .help { display: block; }
.invalid label, .invalid input, .invalid .help {
color: red;
border-color: red;
}
Création d’un validateur de formulaire personnalisé
La démonstration suivante présente un exemple de formulaire de contact qui nécessite un nom d’utilisateur et soit une adresse e-mail, un numéro de téléphone, ou les deux :
Il est mis en œuvre à l’aide d’une classe de validation de formulaire générique appelée FormValidate
. Un élément de formulaire est transmis lors de l’instanciation d’un objet. Un deuxième paramètre optionnel peut être défini :
true
pour valider chaque champ au fur et à mesure que l’utilisateur interagit avec luifalse
(par défaut) pour valider tous les champs après le premier envoi (la validation au niveau du champ se produit après cela)
// valider le formulaire de contact
const contactForm = new FormValidate(document.getElementById('contact'), false);
Une méthode .addCustom(field, func)
définit des fonctions de validation personnalisées. Le code suivant garantit que soit le champ email
soit le champ tel
sont valides (aucun n’a d’attribut required
) :
// validation personnalisée - email et/ou téléphone
const
email = document.getElementById('email'),
tel = document.getElementById('tel');
contactForm.addCustom(email, f => f.value || tel.value);
contactForm.addCustom(tel, f => f.value || email.value);
A FormValidate
object monitors both of the following:
- Les événements
focusout
, qui vérifient ensuite un champ individuel - Les événements
submit
du formulaire, qui vérifient ensuite chaque champ
Les deux appellent la méthode .validateField(field)
, qui vérifie si un champ réussit la validation de contrainte standard. Lorsqu’il le fait, toutes les fonctions de validation personnalisées attribuées à ce champ s’exécutent à leur tour. Toutes doivent renvoyer true
pour que le champ soit valide.
Les champs invalides ont une classe invalid
appliquée à l’élément parent du champ, qui affiche un message d’aide rouge à l’aide de CSS.
Enfin, l’objet appelle une fonction personnalisée submit
lorsque tout le formulaire est valide:
// soumission personnalisée
contactForm.submit = e => {
e.preventDefault();
alert('Form is valid!\n(open the console)');
const fd = new FormData(e.target);
for (const [name, value] of fd.entries()) {
console.log(name + ': ' + value);
}
}
Alternativement, vous pouvez utiliser un addEventListener
standard pour gérer les événements submit
du formulaire, car FormValidate
empêche l’exécution d’autres gestionnaires lorsque le formulaire est invalide.
Form Finesse
Les formulaires sont la base de tous les applications web et les développeurs passent beaucoup de temps à manipuler les entrées utilisateur. La validation des contraintes est bien prise en charge : les navigateurs peuvent gérer la plupart des vérifications et afficher des options d’entrée appropriées.
Recommandations:
- Utilisez les types d’entrée HTML standard lorsque c’est possible. Définissez les attributs
min
,max
,step
,minlength
,maxlength
,pattern
,required
,inputmode
, etautocomplete
comme il convient. - Si nécessaire, utilisez un peu de JavaScript pour activer la validation et les messages personnalisés.
- Pour les champs plus complexes, améliorez progressivement les entrées standard.
Enfin : oubliez Internet Explorer !
À moins que vos clients ne soient principalement des utilisateurs d’IE, il n’est pas nécessaire d’implémenter vos propres fonctions de validation de secours. Tous les champs d’entrée HTML5 fonctionnent dans IE mais peuvent nécessiter plus d’effort de la part de l’utilisateur. (Par exemple, IE ne détecte pas quand vous entrez une adresse e-mail invalide.) Vous devez toujours valider les données côté serveur, alors envisagez d’utiliser cela comme base du contrôle des erreurs IE.
Foire aux questions (FAQ) sur les formulaires HTML et la validation des contraintes
Quelle est l’importance de la validation des formulaires HTML?
La validation des formulaires HTML est un aspect crucial du développement web. Elle garantit que les données entrées par les utilisateurs dans un formulaire respectent certains critères avant d’être envoyées au serveur. Cela non seulement maintient l’intégrité des données, mais améliore également l’expérience utilisateur en fournissant un retour immédiat sur la correction des données entrées. Sans validation des formulaires, il existe un risque de recevoir des données incorrectes, incomplètes ou même malveillantes, ce qui peut entraîner diverses problèmes, y compris la corruption des données, les violations de sécurité et les plantages du système.
Comment HTML5 améliore-t-il la validation des formulaires?
HTML5 introduit plusieurs nouveaux éléments et attributs de formulaire qui facilitent et rendent beaucoup plus efficace la validation des formulaires. Par exemple, il fournit de nouveaux types d’entrée tels que email, URL et nombre, qui valident automatiquement les données d’entrée en fonction du type. Il introduit également de nouveaux attributs comme required, pattern, et min/max qui vous permettent de spécifier diverses contraintes sur les données d’entrée. De plus, HTML5 fournit une API de validation intégrée qui vous permet de réaliser une validation personnalisée à l’aide de JavaScript.
Puis-je effectuer la validation des formulaires sans JavaScript?
Oui, vous pouvez effectuer une validation de base des formulaires en utilisant uniquement HTML5. HTML5 fournit plusieurs nouveaux types d’entrée et attributs qui vous permettent de spécifier diverses contraintes sur les données d’entrée. Par exemple, vous pouvez utiliser l’attribut required pour rendre un champ obligatoire, l’attribut pattern pour appliquer un format spécifique, et les attributs min/max pour définir une plage pour les entrées numériques. Cependant, pour une validation plus complexe, vous pourriez toujours avoir besoin d’utiliser JavaScript.
Comment puis-je personnaliser les messages d’erreur dans la validation des formulaires HTML5?
HTML5 fournit une API de validation qui vous permet de personnaliser les messages d’erreur. Vous pouvez utiliser la méthode setCustomValidity de l’objet ValidityState pour définir un message d’erreur personnalisé pour un champ. Cette méthode prend un argument de chaîne, qui devient le message de validation du champ lorsque le champ est invalide. Vous pouvez appeler cette méthode en réponse à l’événement invalid, qui est déclenché lorsqu’un champ échoue à la validation.
Comment puis-je désactiver la validation des formulaires HTML5?
Vous pouvez désactiver la validation des formulaires HTML5 en ajoutant l’attribut novalidate à l’élément form. Lorsque cet attribut est présent, le navigateur ne procédera à aucune validation sur le formulaire lorsqu’il est soumis. Cela peut être utile si vous souhaitez gérer la validation entièrement côté serveur ou en utilisant un JavaScript personnalisé.
Comment puis-je valider plusieurs champs ensemble en HTML5?
HTML5 ne fournit pas de méthode intégrée pour valider plusieurs champs ensemble. Cependant, vous pouvez réaliser cela en utilisant JavaScript. Vous pouvez écrire une fonction de validation personnalisée qui vérifie les valeurs de plusieurs champs et définit un message de validité personnalisé s’ils ne répondent pas aux critères requis. Vous pouvez appeler cette fonction en réponse à l’événement de soumission du formulaire ou aux événements d’entrée/changement des champs.
Comment puis-je valider un champ en fonction de la valeur d’un autre champ en HTML5?
HTML5 ne fournit pas de méthode intégrée pour valider un champ en fonction de la valeur d’un autre champ. Cependant, vous pouvez réaliser cela en utilisant JavaScript. Vous pouvez écrire une fonction de validation personnalisée qui vérifie la valeur d’un champ par rapport à la valeur d’un autre champ et définit un message de validité personnalisé s’ils ne correspondent pas. Vous pouvez appeler cette fonction en réponse aux événements d’entrée/changement des champs.
Comment puis-je effectuer une validation asynchrone en HTML5?
HTML5 ne prend pas en charge la validation asynchrone en standard. Cependant, vous pouvez réaliser cela en utilisant JavaScript. Vous pouvez écrire une fonction de validation personnalisée qui effectue une opération asynchrone, telle qu’une requête AJAX, et définit un message de validité personnalisé en fonction du résultat. Vous pouvez appeler cette fonction en réponse aux événements d’entrée/changement des champs ou à l’événement de soumission du formulaire.
Comment puis-je styliser les messages d’erreur dans la validation de formulaire HTML5?
L’apparence des messages d’erreur dans la validation des formulaires HTML5 est déterminée par le navigateur et ne peut pas être directement stylisée à l’aide de CSS. Cependant, vous pouvez créer des messages d’erreur personnalisés à l’aide de JavaScript et les styliser comme vous le souhaitez. Vous pouvez utiliser l’API de validation pour déterminer quand un champ est invalide et afficher un message d’erreur personnalisé en conséquence.
Comment puis-je tester la validation d’un formulaire HTML?
Vous pouvez tester la validation d’un formulaire HTML en entrant divers types de données dans les champs et en essayant de soumettre le formulaire. Vous devriez tester avec des données valides et invalides pour vous assurer que la validation fonctionne correctement dans tous les cas. Vous pouvez également utiliser des outils ou des bibliothèques de test automatisés pour effectuer un test plus approfondi.
Source:
https://www.sitepoint.com/html-forms-constraint-validation-complete-guide/