Comment faire un formulaire en HTML
Un formulaire est un élément <form> qui contient des champs et un bouton d'envoi. Chaque champ a besoin d'un name : c'est la clé sous laquelle la valeur est envoyée. Remplissez le formulaire et appuyez sur Send. L'aperçu n'envoie rien nulle part ; il montre exactement ce que le navigateur aurait envoyé.
Les éléments :
actionest l'URL où vont les données, etmethodla manière (postici).- Un
namesur chaque champ. Sa valeur est ce que le lecteur a tapé. <label>nomme chaque champ à l'écran et pour les lecteurs d'écran (voir label HTML).requiredettype="email"font vérifier les champs par le navigateur avant l'envoi. Essayez d'envoyer avec un nom vide, ou avecabccomme e-mail.- Le bouton d'envoi envoie le formulaire. Appuyer sur Entrée dans un champ de texte aussi.
action et method : où et comment partent les données
| Attribut | Valeurs | Par défaut |
|---|---|---|
action | N'importe quelle URL | L'URL de la page actuelle |
method | get, post, dialog | get |
enctype | application/x-www-form-urlencoded, multipart/form-data, text/plain | application/x-www-form-urlencoded |
Avec method="get", les champs deviennent la chaîne de requête de l'URL : un formulaire de recherche avec name="q" va à /search?q=blue+shoes. C'est le bon choix pour les recherches et les filtres, car le résultat peut être mis en favori et partagé. Avec method="post", les champs partent dans le corps de la requête et n'apparaissent ni dans la barre d'adresse ni dans l'historique. Utilisez POST pour tout ce qui connecte, crée, modifie ou supprime quelque chose, et pour les mots de passe.
Un formulaire avec un envoi de fichier (<input type="file">) a besoin de method="post" et de enctype="multipart/form-data", sinon seul le nom du fichier est envoyé. method="dialog" sert à un formulaire placé dans un <dialog> : l'envoi ferme la boîte de dialogue au lieu d'envoyer une requête.
Ce qui est envoyé
Seuls les champs qui ont un name sont envoyés, et seulement s'ils ne sont pas disabled. Appuyez sur Submit et comparez les champs avec ce que le formulaire envoie :
Le formulaire envoie city, zip, source et action. Le champ sans nom, le champ désactivé et la case non cochée sont omis. Les champs cachés sont envoyés mais jamais affichés, et le bouton d'envoi envoie son propre name et sa value car c'est le bouton utilisé.
Regrouper des champs avec fieldset et legend
<fieldset> dessine un cadre autour de champs liés, et <legend> en est la légende. Les lecteurs d'écran annoncent la légende quand le focus entre dans le groupe, ce qui rend compréhensible un ensemble de boutons radio comme ceux ci-dessous : « Delivery, Standard, bouton radio ».
disabled sur un fieldset désactive d'un coup tous les champs qu'il contient, et aucun n'est envoyé. Retirez-le et les champs de cadeau deviennent utilisables.
Validation intégrée : required, pattern et compagnie
Les navigateurs vérifient ces attributs avant l'envoi et affichent un message sur le premier champ en échec :
| Attribut | Vérifie |
|---|---|
required | Le champ n'est pas vide (une case est cochée) |
type="email", type="url" | La valeur ressemble à une adresse e-mail ou à une URL |
minlength, maxlength | La longueur du texte |
min, max, step | L'intervalle des nombres et des dates |
pattern | La valeur entière correspond à une expression régulière |
:invalid et :valid stylisent les champs selon leur état. :user-invalid est généralement préférable : il ne s'applique qu'une fois que le lecteur a modifié le champ puis l'a quitté, ou a tenté d'envoyer, donc un formulaire vide ne s'ouvre pas couvert de rouge.
Trois choses sur pattern piègent les gens. Il doit correspondre à la valeur entière (pas besoin de ^ ni de $). Il ne s'exécute que si le champ n'est pas vide, alors associez-le à required. Et le message d'erreur du navigateur est générique, donc décrivez le format dans un texte visible à côté du champ. Chrome et Firefox ajoutent le texte de title à leur message, mais il passe facilement inaperçu.
Pour désactiver les vérifications, par exemple pendant que vous testez la validation de votre serveur, ajoutez novalidate au <form>. Un bouton d'envoi précis peut les sauter avec formnovalidate.
La validation du navigateur sert au confort du lecteur. N'importe qui peut modifier la page ou envoyer une requête sans elle, donc le serveur doit revérifier chaque valeur.
Messages personnalisés avec setCustomValidity
Quand une règle ne peut pas s'écrire sous forme d'attribut, comme « les deux mots de passe doivent correspondre », définissez le message en JavaScript. Un champ avec un message personnalisé non vide est invalide ; une chaîne vide le rend de nouveau valide :
Le champ de confirmation n'a pas de name, donc une seule copie du mot de passe est envoyée.
Gérer l'envoi en JavaScript
Pour envoyer le formulaire sans quitter la page, écoutez submit, appelez preventDefault() et lisez les champs avec FormData. Écouter submit plutôt que le click d'un bouton capte toutes les façons d'envoyer, y compris Entrée, et ne s'exécute qu'une fois la validation intégrée réussie :
Object.fromEntries(new FormData(form)) transforme les champs en objet simple. Pour les champs qui peuvent avoir plusieurs valeurs (des cases à cocher qui partagent un nom, un select multiple), utilisez plutôt formData.getAll('name'), car l'objet ne garde que la dernière valeur.
Erreurs fréquentes
- Des champs sans
name. Ils sont omis des données envoyées sans aucun avertissement. - Des placeholders au lieu de labels. L'indication disparaît dès que le lecteur tape. Utilisez un
<label>. - Un
<button>sanstypeutilisé pour autre chose que l'envoi. Dans un formulaire, c'est un bouton d'envoi. - Un formulaire dans un formulaire. Imbriquer des formulaires est invalide ; le navigateur ignore la balise
<form>intérieure. - Écouter
clicksur le bouton d'envoi au lieu desubmitsur le formulaire. Les envois avec la touche Entrée passent à la trappe. - Faire confiance à la validation du navigateur côté serveur. Validez de nouveau sur le serveur.
- GET pour des mots de passe. Ils finissent dans l'URL, l'historique et les journaux du serveur.
Questions fréquentes
Comment créer un formulaire en HTML ?
Entourez les champs de <form action="/signup" method="post">, donnez à chaque champ un name et un <label>, et terminez par <button type="submit">. Quand le formulaire est envoyé, le navigateur transmet chaque paire name=value à l'URL de action.
Quelle est la différence entre GET et POST dans un formulaire ?
method="get" (par défaut) place les champs dans l'URL, comme /search?q=shoes, ce qui convient aux recherches et aux filtres qu'on veut pouvoir mettre en favori. method="post" les envoie dans le corps de la requête, ce qu'il faut pour les connexions, les inscriptions et tout ce qui modifie des données.
Pourquoi un champ de mon formulaire n'est pas envoyé ?
Il n'a pas d'attribut name, ou il est disabled. Seuls les champs nommés et actifs sont envoyés. Une case à cocher ou un bouton radio non coché est aussi complètement omis.
À quoi servent fieldset et legend ?
<fieldset> regroupe des champs liés et <legend> est la légende du groupe. Les lecteurs d'écran annoncent la légende quand le focus entre dans le groupe, ce qui rend compréhensible un groupe de boutons radio, et disabled sur un fieldset désactive tous ses champs.
Comment valider un formulaire en HTML sans JavaScript ?
Utilisez des attributs : required, type="email", minlength, maxlength, min, max et pattern. Le navigateur bloque l'envoi et affiche un message sur le premier champ invalide. Validez toujours aussi côté serveur, car ces contrôles s'exécutent dans le navigateur du lecteur et peuvent être contournés.
Comment empêcher un formulaire de recharger la page ?
Écoutez l'événement submit du formulaire et appelez event.preventDefault(), puis envoyez les données vous-même avec fetch : form.addEventListener('submit', (e) => { e.preventDefault(); fetch(form.action, { method: 'POST', body: new FormData(form) }); }).