Menu

Formulaire HTML : champs, action, method et validation

Comment construire un formulaire en HTML : l'élément form, les attributs name, action et method (GET ou POST), le regroupement avec fieldset et legend, la validation intégrée avec required et pattern, et la gestion de l'envoi en JavaScript.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

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 :

  • action est l'URL où vont les données, et method la manière (post ici).
  • Un name sur 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).
  • required et type="email" font vérifier les champs par le navigateur avant l'envoi. Essayez d'envoyer avec un nom vide, ou avec abc comme 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

AttributValeursPar défaut
actionN'importe quelle URLL'URL de la page actuelle
methodget, post, dialogget
enctypeapplication/x-www-form-urlencoded, multipart/form-data, text/plainapplication/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 :

AttributVérifie
requiredLe 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, maxlengthLa longueur du texte
min, max, stepL'intervalle des nombres et des dates
patternLa 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> sans type utilisé 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 click sur le bouton d'envoi au lieu de submit sur 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) }); }).

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER