Séance n°5 : Les formulaires Web

Objectifs & Présentation

Rôle des formulaires

En conception de sites et d'applications Web, les formulaires constituent la passerelle fondamentale d'interaction entre l'utilisateur et le système d'information. Ils permettent de recueillir des données saisies par l'internaute (identifiants de connexion, coordonnées, choix d'options, commentaires, dates, téléversements de documents) et de les transmettre à un serveur Web pour traitement, enregistrement en base de données ou calcul.

🎯 Objectifs d'apprentissage :
  • Comprendre le rôle fonctionnel et l'architecture d'échange client-serveur d'un formulaire Web.
  • Déclarer et configurer le conteneur <form> avec ses attributs clés (action, method, target).
  • Distinguer avec rigueur le comportement, les atouts et les limites des méthodes HTTP GET et POST.
  • Exploiter la balise polyvalente <input> et ses multiples types (text, password, number, email, tel, date, time, range, checkbox, radio).
  • Concevoir des zones de saisie multilignes avec <textarea> et des listes de choix avec <select>, <optgroup>, <option> et <datalist>.
  • Garantir la sémantique et l'accessibilité des formulaires avec les étiquettes <label> et les regroupements <fieldset> / <legend>.
  • Appliquer les contraintes de validation natives (required, readonly, disabled, pattern, min, max, step).
  • Intégrer et styliser des formulaires web complets et esthétiques en CSS (Mini-projets : Formulaire de contact, Questionnaire BD et Fiche d'Observation des Quasars).

Composants élémentaires d'un formulaire

Un formulaire est constitué de composants interactifs variés. Parmi les plus répandus :

  • Les champs de texte monolignes :
  • Les listes déroulantes de sélection :
  • Les boutons d'action :
  • Les cases à cocher (sélection multiple) : Je veux :
  • Les boutons radio (choix exclusif) : Je suis :

Auto-évaluation & Prérequis

Vérifiez vos acquis et réflexes fondamentaux avant de détailler la syntaxe des formulaires.

1. Rôle indispensable de l'attribut name

Que se passe-t-il si un champ de saisie (ex: <input type="text">) ne possède pas d'attribut name lors de l'envoi du formulaire ?

💡 Cliquez ici pour afficher la réponse

Le champ ne sera pas transmis au serveur !

L'attribut name est obligatoire pour tout contrôle de formulaire dont on souhaite exploiter la valeur. Côté serveur, les données sont indexées sous la forme de paires clé=valeur où la clé correspond exactement à la valeur de l'attribut name. Sans cet attribut, le navigateur ignore complètement le champ lors de la soumission de la requête HTTP.

2. Quand privilégier impérativement la méthode POST ?

Pourquoi ne doit-on jamais utiliser la méthode GET pour envoyer un mot de passe ou des données confidentielles ?

💡 Cliquez ici pour afficher la réponse

Avec la méthode GET, toutes les données saisies sont concaténées en clair directement dans l'URL du navigateur (ex : page.php?login=admin&pass=secret123).

  • Le mot de passe apparaît en clair sur l'écran, accessible à toute personne à proximité.
  • L'URL reste stockée en clair dans l'historique du navigateur, les journaux serveurs et les proxys.
  • Elle peut être partagée par inadvertance lors de la copie du lien.

La méthode POST encapsule au contraire les données dans le corps (Body) de la requête HTTP, les rendant invisibles dans l'URL et assurant leur confidentialité (lorsqu'elles transitent en HTTPS).

Transmission & Méthodes HTTP

Attributs de la balise <form>

Tout formulaire Web s'encadre obligatoirement entre la balise ouvrante <form> et la balise fermante </form> :

<form action="traitement.php" method="post" target="_self">
  <!-- Contrôles de saisie, étiquettes et boutons -->
</form>

Attributs fondamentaux de la balise <form> :

  • action="URL" : spécifie l'adresse URL du script ou de la page côté serveur chargée de réceptionner et de traiter les données (ex : action="contact.php"). Si la valeur est "#" ou vide, les données sont soumises à la même page.
  • method="GET | POST" : indique la méthode HTTP employée pour transmettre les données au serveur.
  • target="_self | _blank | _parent | _top" : indique la cible d'affichage de la réponse renvoyée par le serveur (ex. _blank pour ouvrir le résultat dans un nouvel onglet).

Autres attributs possibles (hors programme) :

  • autocomplete="on | off" : active ou désactive la mémorisation et la suggestion automatique des valeurs par le navigateur sur l'ensemble du formulaire.
  • enctype="..." : définit l'encodage des données envoyées. Par défaut, la valeur est application/x-www-form-urlencoded. Lors de l'envoi de fichiers (via <input type="file">), il est indispensable de spécifier enctype="multipart/form-data" avec la méthode POST.

Méthodes de transmission

Le protocole HTTP propose deux méthodes fondamentales pour transférer des données de formulaire. Le choix de la méthode influe directement sur la visibilité, la sécurité, la mise en cache et le volume des données transmises.

Critère Méthode GET Méthode POST
Emplacement des données Ajoutées à la fin de l'URL sous forme de chaîne de requête (Query String) :
page.html?nom=Ali&age=17
Encapsulées dans le corps (Body) de la requête HTTP, séparées des en-têtes.
Visibilité pour l'utilisateur Visible en clair dans la barre d'adresses du navigateur. Invisible dans l'URL.
Confidentialité & Sécurité Très faible : inadapté aux mots de passe, numéros bancaires et données personnelles sensibles. Beaucoup plus sécurisé : les données ne sont pas exposées dans l'historique ou l'écran.
Limite de volume Limitée par la taille maximale de l'URL autorisée par le serveur et le navigateur (~2048 caractères). Virtuellement illimitée (dépend de la configuration du serveur web, adapté aux gros volumes et fichiers).
Mise en cache & Favoris Peut être mise en cache, archivée dans l'historique et enregistrée en marque-page (favori). Jamais mise en cache par défaut, non enregistrable en marque-page. Le navigateur demande confirmation avant rechargement.
Cas d'usage recommandés Recherches, filtres de catalogue, pagination, consultation sans modification de données sur le serveur. Formulaires de connexion (login), inscriptions, transactions de paiement, envoi de messages et de fichiers.

Observation réseau

Pour observer concrètement la différence entre les deux méthodes, testons les deux formulaires ci-dessous qui transmettent les mêmes champs vers la même page réceptrice (assets/miniprojet07/loggedin.html).

Formulaire 1 : Méthode POST
Formulaire 2 : Méthode GET

Expérience 1 : Analyse de la méthode POST

Ouvrez les Outils de développement de votre navigateur avec la touche F12 (ou Ctrl + Shift + I), sélectionnez l'onglet Réseau (Network), puis cliquez sur le bouton Login (POST) :

Dans l'onglet Headers on observe bien que la méthode utilisée est POST
Dans l'onglet En-têtes (Headers), la méthode de requête est explicitement POST
L'adresse URL affichée lorsqu'on utilise une méthode POST pour récupérer les données
L'URL de destination ne comporte aucun paramètre visible : la confidentialité est préservée
Les données du formulaire sont disponibles dans la partie 'Request'
Dans l'onglet Charge utile (Payload / Request), les champs login et pass sont transportés dans le corps

Expérience 2 : Analyse de la méthode GET

Cliquez sur le lien « return to course... » pour revenir à cette page. Réactivez l'enregistrement dans l'onglet Réseau (Network) de F12, puis cliquez sur le bouton Login (GET) :

Dans l'onglet Headers on vérifie bien que la méthode utilisée est GET
Dans l'onglet En-têtes (Headers), la méthode de requête est bien GET
L'adresse URL affichée lorsqu'on utilise une méthode GET contient les données du formulaire
Les identifiants apparaissent directement en clair dans la barre d'adresse de l'URL !
La partie 'Request' est vide
Le corps de la requête (Request Body / Payload) reste vide car les données ont voyagé dans l'URL

Formulaire d'authentification

Examinons un formulaire complet de connexion (login) stylisé pour comprendre l'assemblage des éléments :

⚡ Rendu direct du formulaire :

Code HTML source

<form id="example01" action="#" method="post">
  <input type="text" name="login" placeholder="Login">
  <input type="password" name="pass" placeholder="Password" autocomplete="new-password">
  <label><input type="checkbox" name="rememberme" checked> Remember me</label>
  <button type="submit">Log me in</button>
</form>

Feuille de style CSS associée : 📄 Consulter le code CSS (login.txt)

Exploration détaillée du code

  • Conteneur <form> : délimite le formulaire, spécifie l'action et impose la méthode POST.
  • Champ texte (type="text") : reçoit le nom d'utilisateur. L'attribut placeholder="Login" fournit une indication textuelle temporaire.
  • Champ mot de passe (type="password") : masque la saisie par des ronds ou étoiles. L'attribut autocomplete="new-password" gère la complétion par les gestionnaires de mots de passe.
  • Case à cocher (type="checkbox") : permet de mémoriser la session. L'attribut booléen checked la coche par défaut.
  • Étiquette englobante (<label>) : rend le texte « Remember me » cliquable pour cocher ou décocher la case.
  • Bouton de soumission (<button type="submit">) : déclenche la validation et l'expédition du formulaire.

Travail demandé

  1. Créer un fichier HTML nommé login.html.
  2. Insérer la structure HTML5 minimale et recopier le code du formulaire ci-dessus.
  3. Appliquer la feuille de style CSS disponible via le lien login.txt.
  4. Tester la saisie et observer l'interaction avec le bouton et la case à cocher.

Composants de Formulaire

Champs de saisie textuels et numériques

Les champs textuels et numériques permettent à l'utilisateur de taper des valeurs libres ou encadrées par des règles de format précises.

Composant & Description Rendu interactif Code HTML5
Champ de texte
Saisie monoligne libre
<input type="text" name="np" 
       value="Mariem" placeholder="Nom &amp; Prénom">
Champ mot de passe
Masque les caractères saisis
<input type="password" name="pwd" 
       value="secret" placeholder="Mot de passe">
Zone de texte (textarea)
Saisie multiligne extensible
<textarea name="histoire" cols="20" rows="3"
          placeholder="Raconter votre histoire"></textarea>
Champ numérique
Contrôle des bornes et pas
De 0.0 à 20.0 (pas: 0.25)
<input type="number" name="note" value="10.0" 
       min="0.0" max="20.0" step="0.25">
Champ adresse courriel
Validation syntaxique automatique
<input type="email" name="mail" 
       placeholder="Votre adresse mail">
Champ numéro de téléphone
Validation par expression rationnelle
Format tunisien : 8 chiffres
<input type="tel" name="phone" 
       pattern="[2459][0-9] [0-9]{3} [0-9]{3}" 
       placeholder="Votre téléphone">

Champs temporels et intervalles

HTML5 intègre nativement des sélecteurs spécialisés pour les dates, les heures et les curseurs de réglage numérique :

Composant Rendu interactif Code HTML5
Champ date
Calendrier natif interactif
<input type="date" name="voyage" value="2026-10-01" 
       min="2026-01-01" max="2026-12-31">
Champ heure (time)
Sélecteur horaire (HH:MM)
Entre 08:00 et 18:00 (pas: 15 min)
<input type="time" name="appt" 
       min="08:00" max="18:00" step="900" value="14:00">
Date et heure locales
Combinaison calendrier + heure
<input type="datetime-local" name="exam" 
       min="2026-09-15" max="2027-06-30" 
       value="2026-09-15T08:00">
Curseur d'intervalle (range)
Avec repères gradués (datalist)
0%25%50%75%100%
<input type="range" name="volume" 
       min="0" max="100" step="5" list="ticks">
<datalist id="ticks">
  <option value="0" label="0%"></option>
  <option value="25" label="25%"></option>
  <option value="50" label="50%"></option>
  <option value="75" label="75%"></option>
  <option value="100" label="100%"></option>
</datalist>

Boutons radio, Cases à cocher et Étiquettes

La sélection d'options repose sur des composants au comportement bien distinct : choix exclusif avec les boutons radio, choix multiple avec les cases à cocher, et association ergonomique grâce aux étiquettes.

Composant & Description Rendu interactif Code HTML5
Bouton radio
Choix exclusif au sein d'un même groupe (même attribut name)
<label>
  <input type="radio" name="se" value="x86"> Windows 32bits
</label><br>
<label>
  <input type="radio" name="se" value="x64" checked> Windows 64bits
</label><br>
<label>
  <input type="radio" name="se" value="Linux"> Linux distribution
</label>
Case à cocher (checkbox)
Sélection multiple ou options indépendantes (0, 1 ou plusieurs)
<label>
  <input type="checkbox" name="media" value="Livre" checked> Livre
</label><br>
<label>
  <input type="checkbox" name="media" value="Magazine" checked> Magazine
</label><br>
<label>
  <input type="checkbox" name="media" value="Roman"> Roman
</label><br>
<label>
  <input type="checkbox" name="media" value="Encyclopédie"> Encyclopédie
</label>
Étiquette (<label>)
Liaison libellé ↔ champ : accessibilité et extension de la zone cliquable
1. Syntaxe implicite (englobante) :
2. Syntaxe explicite (via for & id) :
<!-- 1. Syntaxe implicite (englobante) -->
<label>
  <input type="checkbox" name="cgu"> J'accepte les conditions
</label>

<!-- 2. Syntaxe explicite (recommandée) -->
<label for="demo-nom">Nom d'utilisateur :</label>
<input type="text" id="demo-nom" name="demo-nom">

Importance ergonomique de l'élément <label>

L'élément <label> associe un libellé textuel à son contrôle de formulaire. Il offre deux avantages capitaux :

  1. Accessibilité : les synthèses vocales annoncent le libellé dès que le champ reçoit le focus.
  2. Zone cliquable étendue : un clic de souris sur le texte active ou coche instantanément le champ associé.

Deux syntaxes équivalentes sont possibles :

  • Syntaxe implicite (englobante) : <label><input type="checkbox" name="..."> Mon libellé</label>
  • Syntaxe explicite (via identifiant) : <label for="monId">Mon libellé</label> <input type="checkbox" id="monId" name="...">

Listes déroulantes et Suggestions

Lorsque le nombre d'options est élevé, les listes déroulantes compactent l'espace d'affichage tout en structurant les choix. La balise <datalist> permet quant à elle de suggérer des valeurs sans restreindre la saisie libre.

Composant & Description Rendu interactif Code HTML5
Liste déroulante simple
Sélection unique standard sans regroupement (balises <select> et <option>)
<select name="fruit">
  <option value="">-- Choisir un fruit --</option>
  <option value="pomme">Pomme</option>
  <option value="fraise" selected>Fraise</option>
  <option value="orange">Orange</option>
  <option value="banane">Banane</option>
</select>
Liste avec groupes (<optgroup>)
Organisation hiérarchique. La balise <optgroup> structure les options en sous-catégories non sélectionnables.
<select name="fruit_cat">
  <optgroup label="Fruits locaux">
    <option value="pomme">Pomme</option>
    <option value="fraise" selected>Fraise</option>
    <option value="orange">Orange</option>
    <option value="raisin">Raisin</option>
  </optgroup>
  <optgroup label="Fruits importés">
    <option value="banane">Banane</option>
    <option value="avocat">Avocat</option>
    <option value="kiwi">Kiwi</option>
  </optgroup>
</select>
Liste à choix multiples
Attributs multiple et size. Autorise la sélection de plusieurs éléments (Ctrl ou Shift).
<select name="fruits" size="5" multiple>
  <option value="pomme">Pomme</option>
  <option value="fraise" selected>Fraise</option>
  <option value="orange">Orange</option>
  <option value="banane" selected>Banane</option>
  <option value="kiwi">Kiwi</option>
</select>
Suggestions (<datalist>)
Champ texte libre lié à une liste de suggestions d'autocomplétion via l'attribut list
Ex: tapez 'S' ou double-cliquez pour choisir
<input type="text" name="hero" list="heroes-list">
<datalist id="heroes-list">
  <option value="Spiderman">
  <option value="Superman">
  <option value="Batman">
  <option value="Megaman">
  <option value="Catman">
</datalist>

Boutons d'action

Les boutons déclenchent des actions interactives essentielles : soumettre les données saisies au serveur, réinitialiser les champs à leur état initial ou exécuter un traitement en JavaScript. En HTML5, on utilise la balise polyvalente <button> (ou l'élément <input>) avec l'attribut type adéquat :

Composant & Description Rendu interactif Code HTML5
Bouton d'envoi (submit)
Transmet les données du formulaire à l'URL cible spécifiée dans l'attribut action (type par défaut)
<!-- Balise button (recommandée) -->
<button type="submit">Soumettre</button>

<!-- Syntaxe alternative avec input -->
<input type="submit" value="Soumettre">
Bouton de réinitialisation (reset)
Rétablit instantanément tous les champs du formulaire à leurs valeurs initiales
<!-- Balise button (recommandée) -->
<button type="reset">Réinitialiser (RAZ)</button>

<!-- Syntaxe alternative avec input -->
<input type="reset" value="Réinitialiser">
Bouton neutre (button)
Bouton générique sans action native par défaut. Son comportement est programmé via JavaScript (attribut onclick ou écouteur d'événement)
<!-- Balise button (recommandée) -->
<button type="button" onclick="alert('Action !')">
  Exécuter script
</button>

<!-- Syntaxe alternative avec input -->
<input type="button" value="Exécuter script">

Différence clé entre <button> et <input type="...">

Contrairement à <input> dont l'intitulé est restreint à une simple chaîne de texte brut (attribut value), la balise <button>...</button> est un conteneur qui peut embarquer du contenu HTML riche (icônes, images, mise en gras, etc.) :

<button type="submit" class="btn btn-primary">
  <strong>✓ Valider</strong> l'inscription
</button>

Regroupement et attributs d'état

1. Regroupement logique avec <fieldset> et <legend>

Pour organiser un formulaire dense, <fieldset> trace un cadre englobant et <legend> en définit le titre sémantique :

Identité
<fieldset>
  <legend>Identité</legend>
  <label for="cin">CIN :</label> 
  <input type="text" id="cin" name="cin" size="8" maxlength="8">
  
  <label for="nom">Nom :</label> 
  <input type="text" id="nom" name="nom">
</fieldset>

2. Attributs d'état : disabled vs readonly

Règle cruciale pour la soumission :
  • readonly (lecture seule) : le champ n'est pas modifiable, mais sa valeur EST transmise au serveur lors de la soumission.
  • disabled (désactivé) : le champ est grisé, inactif, et sa valeur N'EST PAS transmise au serveur.
<!-- Lecture seule : valeur envoyée lors du submit -->
<input type="text" value="Code fixe" readonly>

<!-- Désactivé : valeur NON transmise lors du submit -->
<input type="text" value="Non modifiable" disabled>
<textarea disabled>Zone inactive</textarea>

Ateliers Pratiques

Application 7 : Formulaire de contact

Mission : Réaliser un formulaire Web de contact complet pour développeur en intégrant l'ensemble des balises, contrôles de saisie, étiquettes sémantiques et règles de mise en page CSS étudiées.

Aperçu du modèle visuel attendu

Formulaire de contact développeur
Formulaire de contact développeur avec champs requis et mise en page CSS

Cahier des charges & Spécifications

  • Les champs obligatoires doivent être signalés par un astérisque (*) et comporter l'attribut required.
  • Le champ Poste actuel est une liste déroulante organisée avec <optgroup> selon la hiérarchie suivante :
    • Web : Frontend developer, Backend developer, Fullstack developer
    • Data science : Datascience engineer
    • Autres : Python developer, C++ developer
  • Insérer une zone de texte multiligne <textarea> pour la rédaction du message.
  • Fournir les boutons de soumission (Envoyer) et de réinitialisation (Annuler).
  • Mise en forme CSS : centrer le formulaire, appliquer des espacements internes (padding) confortables, des bordures adoucies et une harmonie de couleurs élégante.

Application 8 : Personnages de bandes dessinées

Mission : Concevoir un questionnaire interactif en cinq questions portant sur l'identification de personnages de bandes dessinées, en mobilisant diverses techniques d'association de contrôles et d'étiquettes visuelles.

Question 1 : Identification par zone de liste

Question 1
Question 1 : Sélection du personnage sous chaque avatar
  1. Les images des personnages servent d'étiquettes (<label>) pour sélectionner la liste déroulante située juste en dessous.
  2. Les éléments de la zone de liste sont présentés dans la figure ci-après :
    Options de la zone de liste
  3. Chacune des quatre listes doit obligatoirement être renseignée par l'utilisateur (attribut required).

Question 2 : Boutons radio avec avatars

Question 2
Question 2 : Choix exclusif avec bouton radio au-dessus de l'image
  1. Les images des personnages sont des étiquettes (<label>) qui activent le bouton radio situé au-dessus d'elles.
  2. Les valeurs respectives transmises par les trois boutons radio sont : a, b et c.
  3. L'utilisateur doit obligatoirement sélectionner une réponse parmi les trois propositions.

Question 3 : Champ de texte avec suggestions (datalist)

Question 3
Question 3 : Saisie textuelle guidée par autocomplétion
  1. Le champ de texte est lié à une <datalist> qui propose les suggestions suivantes :
    • Spiderman
    • Superman
    • Batman
    • Megaman
    • Catman
  2. La saisie d'une réponse à cette question est obligatoire.

Question 4 : Cases à cocher multiples

Question 4
Question 4 : Sélection multiple par case à cocher sous l'image
  1. Les images des personnages sont des étiquettes (<label>) qui permettent de cocher la case correspondante.
  2. Les valeurs respectives associées aux cases sont : a, b, c et d.
  3. La réponse à cette question est facultative (aucune obligation de saisie).

Question 5 : Champ numérique borné

Question 5
Question 5 : Note numérique comprise entre 1 et 20
  1. Le champ de saisie est de type numérique (type="number").
  2. Les valeurs permises sont comprises entre 1 (minimum) et 20 (maximum). Le champ affiche la valeur 5 par défaut.
  3. La réponse à cette question est obligatoire.
Boutons de fin de formulaire : Le formulaire doit comporter un bouton d'envoi <button type="submit"> et un bouton de réinitialisation <button type="reset">.

Application 9 : Observation des Quasars

Mission : Réaliser un formulaire d'enregistrement astronomique structuré en six questions permettant d'expérimenter l'ensemble des composants HTML5 : champs temporels, curseur d'intervalle range, sélecteur de couleur color, mot de passe, champ en lecture seule readonly, liste à sélection multiple multiple et bouton d'action JavaScript button type="button".
Aperçu de l'application Quasars
Aperçu du résultat attendu pour l'observation des Quasars

Question 1 : Identification du télescope (readonly & password)

  1. Un champ de texte en lecture seule affiche la station active : VLT Paranal - Télescope 4. Sa valeur est transmise au serveur mais reste non modifiable par l'élève.
  2. Un champ mot de passe permet de saisir le code de l'opérateur. Il est obligatoire et doit comporter au moins 4 caractères (attribut minlength="4").

Question 2 : Heure d'observation (type="time")

  1. Le champ de saisie temporelle (type="time").
  2. Le champ affiche l'heure 22:30 par défaut et sa saisie est obligatoire.

Question 3 : Décalage vers le rouge (type="range" & output)

  1. Le contrôle est un curseur d'intervalle.
  2. Les bornes autorisées vont de 0 (minimum) à 8 (maximum) avec un incrément de 0.5 (step="0.5"). La valeur par défaut est 2.
  3. La valeur sélectionnée est affichée dynamiquement à côté du curseur dans une balise <output> grâce à l'attribut oninput.

Question 4 : Raie spectrale dominante (type="color")

  1. Le champ permet de choisir visuellement une couleur grâce au type sélecteur chromatique (type="color").
  2. La valeur initiale proposée est le rouge : #ff0000.

Question 5 : Bandes spectrales observées (select multiple)

  1. La zone de liste est à choix multiples (attribut multiple).
  2. Le nombre de lignes affichées simultanément est fixé à 4 (attribut size="4").
  3. La liste propose 5 bandes : Ondes radio (sélectionnée par défaut), Infrarouge, Spectre visible (sélectionnée par défaut), Ultraviolet et Rayons X.
  4. La sélection d'au moins une bande est obligatoire.

Question 6 : Données brutes & Bouton d'action (file & button)

  1. Un bouton d'action JavaScript (<button type="button">) déclenche l'affichage d'un message d'alerte lors du clic (événement onclick="alert(...)") sans recharger la page ni soumettre le formulaire.
Boutons de fin de formulaire : Le formulaire doit comporter un bouton de soumission <button type="submit">Soumettre</button> pour envoyer les données vers quasars.php et un bouton de remise à zéro <button type="reset">Effacer</button>.