ISAE - GAFSA

Institut Supérieur d'Administration des Entreprises

Matière : Développement Web 2

Enseignant : KHMIL Boubaker

Niveau : 2ème Année Business Computing

Travaux Pratiques N°4

JavaScript : Manipulation des Formulaires

Valider, contrôler et exploiter les données saisies par l'utilisateur

Objectifs Pédagogiques

1

Préparation du TP

1.1 Structure du projet

Créez un nouveau dossier TP4 dans votre dossier TP-JavaScript :

TP-JavaScript/
└── TP4/
    ├── index.html
    ├── style.css
    └── script.js

1.2 Fichiers de départ

index.html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TP4 - Formulaires</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <h1>TP4 — Manipulation des Formulaires</h1>

    <!-- Les sections seront ajoutées ici au fur et à mesure -->

    <script src="script.js"></script>
</body>
</html>
style.css
body {
    font-family: Arial, sans-serif;
    max-width: 650px;
    margin: 40px auto;
    padding: 20px;
}

h1 { text-align: center; margin-bottom: 30px; }
h2 { margin-top: 40px; margin-bottom: 16px; color: #1e40af; }

form {
    background: #f9fafb;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 24px;
    margin-bottom: 24px;
}

label {
    display: block;
    font-weight: 600;
    margin-bottom: 4px;
    margin-top: 16px;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="tel"],
input[type="date"],
select,
textarea {
    width: 100%;
    padding: 10px 12px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 6px;
    margin-bottom: 4px;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
}

textarea { resize: vertical; min-height: 80px; }

button {
    padding: 10px 24px;
    font-size: 16px;
    cursor: pointer;
    border: none;
    background: #1e40af;
    color: white;
    border-radius: 6px;
    margin-top: 16px;
}

button:hover { background: #1d4ed8; }

.erreur {
    color: #dc2626;
    font-size: 0.875rem;
    min-height: 20px;
}

.input-erreur {
    border-color: #dc2626 !important;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1) !important;
}

.input-valide {
    border-color: #059669 !important;
    box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.1) !important;
}

.resultat {
    margin-top: 20px;
    padding: 16px;
    background: #f0f9ff;
    border-radius: 8px;
    font-size: 16px;
}

.groupe-radio label,
.groupe-checkbox label {
    display: inline;
    font-weight: normal;
    margin-left: 4px;
    margin-right: 16px;
}

.groupe-radio, .groupe-checkbox {
    margin: 8px 0;
}
script.js
console.log("TP4 chargé avec succès");
À faire maintenant

Créez ces 3 fichiers, lancez index.html avec Live Server, et vérifiez que le message apparaît dans la console (F12).

2

La Balise <form> et la Soumission

2.1 Pourquoi utiliser <form> ?

Au TP3, on plaçait des <input> et des <button> directement dans la page. Ça fonctionne, mais dans un vrai site, on regroupe toujours les champs dans une balise <form>.

Analogie simple

Un <form>, c'est comme un formulaire papier (inscription, commande, enquête). Il regroupe tous les champs dans un même bloc et définit ce qui se passe quand on valide : où envoyer les données, comment les envoyer.

Sans <form>, vos champs sont comme des feuilles volantes. Avec <form>, ils font partie d'un même dossier.

Les avantages concrets de <form> :

  • La touche Entrée soumet automatiquement le formulaire
  • L'événement "submit" permet d'intercepter la soumission
  • Les attributs HTML de validation (required, minlength...) ne fonctionnent qu'à l'intérieur d'un <form>
  • L'accessibilité est meilleure (lecteurs d'écran, navigation au clavier)

2.2 Structure de base d'un formulaire

Ajoutez ce code dans votre index.html :

index.html (dans le body)
<h2>Formulaire de contact</h2>
<form id="formContact">
    <label for="nom">Nom :</label>
    <input type="text" id="nom" name="nom" placeholder="Votre nom">

    <label for="email">Email :</label>
    <input type="email" id="email" name="email" placeholder="votre@email.com">

    <label for="message">Message :</label>
    <textarea id="message" name="message" placeholder="Votre message..."></textarea>

    <button type="submit">Envoyer</button>
</form>
<div id="resultatContact" class="resultat" style="display:none;"></div>
L'attribut for du label

Le for="nom" dans le <label> doit correspondre à l'id="nom" de l'input. Cela permet de cliquer sur le texte du label pour activer le champ — c'est une bonne pratique d'accessibilité.

Attention au type du bouton

Dans un <form>, un <button> sans attribut type se comporte par défaut comme type="submit". Il est recommandé de toujours préciser le type :

  • type="submit" — soumet le formulaire
  • type="button" — bouton simple, ne soumet pas le formulaire
  • type="reset" — remet tous les champs à leur valeur initiale

2.3 Intercepter la soumission avec preventDefault()

Si vous cliquez sur « Envoyer » maintenant, la page se recharge. C'est le comportement par défaut du navigateur : il essaie d'envoyer les données à un serveur. Comme on n'a pas de serveur, on doit empêcher ce comportement pour traiter les données en JavaScript.

script.js
// 1. Sélectionner le formulaire (pas le bouton !)
let formContact = document.querySelector("#formContact");

// 2. Écouter l'événement "submit" sur le formulaire
function gererSoumission(event) {
    // Empêcher le rechargement de la page
    event.preventDefault();

    // Maintenant, on peut traiter les données ici
    console.log("Formulaire intercepté !");
}

// 3. Associer
formContact.addEventListener("submit", gererSoumission);
Comprendre le paramètre event

Quand un événement se déclenche, le navigateur passe automatiquement un objet event à votre fonction. Cet objet contient des informations sur l'événement (quel élément a été cliqué, quelle touche a été pressée, etc.).

La méthode event.preventDefault() dit au navigateur : « Ne fais pas ton action par défaut » (ici : ne recharge pas la page).

À faire maintenant

Testez le code. Cliquez sur « Envoyer » : la page ne doit plus se recharger. Le message doit apparaître dans la console. Testez aussi en appuyant sur Entrée dans un champ — le comportement doit être le même.

2.4 Lire les valeurs et afficher le résultat

Complétons la fonction pour lire les valeurs saisies et les afficher :

script.js (remplacer la fonction)
let formContact = document.querySelector("#formContact");
let resultatContact = document.querySelector("#resultatContact");

function gererSoumission(event) {
    event.preventDefault();

    // Lire les valeurs des champs
    let nom = document.querySelector("#nom").value;
    let email = document.querySelector("#email").value;
    let message = document.querySelector("#message").value;

    // Afficher les données récupérées
    resultatContact.style.display = "block";
    resultatContact.innerHTML = `
        <strong>Données reçues :</strong><br>
        Nom : ${nom}<br>
        Email : ${email}<br>
        Message : ${message}
    `;
}

formContact.addEventListener("submit", gererSoumission);
Résultat

Quand l'utilisateur remplit le formulaire et clique sur « Envoyer », les données saisies s'affichent en dessous — sans rechargement de la page.

À faire maintenant

Testez le formulaire. Remplissez les trois champs et soumettez. Vérifiez que les données s'affichent correctement en dessous.

3

Lire Tous les Types de Champs

3.1 Récapitulatif des types d'input

HTML propose de nombreux types de champs. Voici ceux que vous rencontrerez le plus souvent :

Type Affichage Lecture en JS
text Champ texte libre .value → chaîne
email Champ avec validation email .value → chaîne
password Champ masqué (points) .value → chaîne
number Champ numérique Number(.value) → nombre
date Sélecteur de date .value"2026-03-31"
tel Champ téléphone .value → chaîne
checkbox Case à cocher .checkedtrue/false
radio Bouton radio (choix unique) .checkedtrue/false
Règle importante

Retenez la distinction :

  • .value → pour les champs texte (text, email, password, number, date, tel, select, textarea)
  • .checked → pour les champs à cocher (checkbox, radio)

3.2 Lire les boutons radio

Les boutons radio permettent de choisir une seule option parmi un groupe. Tous les radio d'un même groupe doivent avoir le même attribut name.

index.html (à ajouter)
<h2>Choix du genre</h2>
<form id="formGenre">
    <p><strong>Genre :</strong></p>
    <div class="groupe-radio">
        <input type="radio" id="homme" name="genre" value="Homme">
        <label for="homme">Homme</label>

        <input type="radio" id="femme" name="genre" value="Femme">
        <label for="femme">Femme</label>
    </div>
    <button type="submit">Valider</button>
</form>
<div id="resultatGenre" class="resultat" style="display:none;"></div>
script.js (à ajouter)
let formGenre = document.querySelector("#formGenre");
let resultatGenre = document.querySelector("#resultatGenre");

function gererGenre(event) {
    event.preventDefault();

    // Sélectionner le radio coché dans le groupe "genre"
    let radioSelectionne = document.querySelector('input[name="genre"]:checked');

    if (radioSelectionne === null) {
        resultatGenre.textContent = "Veuillez sélectionner un genre.";
        resultatGenre.style.display = "block";
        resultatGenre.style.color = "red";
        return;
    }

    resultatGenre.textContent = `Genre choisi : ${radioSelectionne.value}`;
    resultatGenre.style.display = "block";
    resultatGenre.style.color = "#333";
}

formGenre.addEventListener("submit", gererGenre);
Décryptage du sélecteur CSS

input[name="genre"]:checked signifie : « un <input> dont l'attribut name vaut genre ET qui est actuellement coché ». Si aucun radio n'est coché, querySelector retourne null.

À faire maintenant

Testez ce code. Soumettez sans rien cocher, puis en cochant une option. Vérifiez les deux comportements.

3.3 Lire les cases à cocher (checkbox)

Contrairement aux radio, les checkbox permettent de cocher plusieurs options. On les lit avec .checked (qui retourne true ou false).

index.html (à ajouter)
<h2>Centres d'intérêt</h2>
<form id="formInterets">
    <p><strong>Cochez vos centres d'intérêt :</strong></p>
    <div class="groupe-checkbox">
        <input type="checkbox" id="sport" name="interet" value="Sport">
        <label for="sport">Sport</label>

        <input type="checkbox" id="musique" name="interet" value="Musique">
        <label for="musique">Musique</label>

        <input type="checkbox" id="lecture" name="interet" value="Lecture">
        <label for="lecture">Lecture</label>

        <input type="checkbox" id="voyage" name="interet" value="Voyage">
        <label for="voyage">Voyage</label>
    </div>
    <button type="submit">Valider</button>
</form>
<div id="resultatInterets" class="resultat" style="display:none;"></div>
script.js (à ajouter)
let formInterets = document.querySelector("#formInterets");
let resultatInterets = document.querySelector("#resultatInterets");

function gererInterets(event) {
    event.preventDefault();

    // querySelectorAll retourne TOUS les éléments correspondants
    let caseCochees = document.querySelectorAll('input[name="interet"]:checked');

    if (caseCochees.length === 0) {
        resultatInterets.textContent = "Veuillez cocher au moins un intérêt.";
        resultatInterets.style.color = "red";
        resultatInterets.style.display = "block";
        return;
    }

    // Construire la liste des valeurs cochées
    let liste = [];
    for (let i = 0; i < caseCochees.length; i++) {
        liste.push(caseCochees[i].value);
    }

    resultatInterets.textContent = `Vos intérêts : ${liste.join(", ")}`;
    resultatInterets.style.color = "#333";
    resultatInterets.style.display = "block";
}

formInterets.addEventListener("submit", gererInterets);
querySelector vs querySelectorAll
  • querySelector() → retourne le premier élément trouvé (ou null)
  • querySelectorAll() → retourne tous les éléments trouvés (une liste, même si vide)

Pour les checkbox, on utilise querySelectorAll car l'utilisateur peut cocher plusieurs cases.

À faire maintenant

Testez avec 0, 1, puis plusieurs cases cochées. Vérifiez que la liste s'affiche correctement avec des virgules.

3.4 Lire un select et un textarea

On les lit exactement comme un input texte, avec .value. Pas de surprise :

// Pour un <select id="pays">
let pays = document.querySelector("#pays").value;
// → retourne la value de l'option sélectionnée

// Pour un <textarea id="commentaire">
let commentaire = document.querySelector("#commentaire").value;
// → retourne tout le texte saisi
4

Validation des Formulaires

4.1 Pourquoi valider ?

Analogie simple

Imaginez un guichet de poste. Avant de traiter votre courrier, l'agent vérifie : l'adresse est-elle complète ? Le timbre est-il collé ? Le poids est-il correct ? S'il manque quelque chose, il vous demande de corriger avant d'accepter le courrier.

La validation d'un formulaire, c'est exactement la même chose : on vérifie les données avant de les traiter ou de les envoyer.

Il existe deux niveaux de validation :

  • Validation HTML (attributs) — simple, rapide, mais limitée
  • Validation JavaScript — puissante, personnalisable, indispensable

4.2 Validation HTML avec les attributs

HTML fournit des attributs de validation natifs qui fonctionnent automatiquement dans un <form> :

Attribut Effet Exemple
required Champ obligatoire <input required>
minlength Longueur minimum <input minlength="3">
maxlength Longueur maximum <input maxlength="50">
min / max Valeur min/max (nombres) <input type="number" min="0" max="20">
pattern Expression régulière <input pattern="[0-9]{8}">
type="email" Vérifie le format email <input type="email">
<!-- Exemples de validation HTML -->
<input type="text" required minlength="2" maxlength="50">
<input type="email" required>
<input type="number" min="0" max="20" required>
<input type="tel" pattern="[0-9]{8}" title="8 chiffres attendus">
Limites de la validation HTML

La validation HTML affiche des messages par défaut du navigateur (en anglais selon les systèmes). Elle ne permet pas de personnaliser les messages, de comparer deux champs (ex : mot de passe et confirmation), ni de faire des vérifications complexes. C'est pour cela qu'on a besoin de JavaScript.

4.3 Validation JavaScript : les bonnes pratiques

Pour une validation professionnelle, on affiche un message d'erreur sous chaque champ qui pose problème, et on met en évidence le champ en erreur.

Créons un formulaire d'inscription complet :

index.html (à ajouter)
<h2>Inscription</h2>
<form id="formInscription">

    <label for="inscNom">Nom complet :</label>
    <input type="text" id="inscNom">
    <div class="erreur" id="erreurNom"></div>

    <label for="inscEmail">Email :</label>
    <input type="email" id="inscEmail">
    <div class="erreur" id="erreurEmail"></div>

    <label for="inscMdp">Mot de passe :</label>
    <input type="password" id="inscMdp">
    <div class="erreur" id="erreurMdp"></div>

    <label for="inscConfirm">Confirmer le mot de passe :</label>
    <input type="password" id="inscConfirm">
    <div class="erreur" id="erreurConfirm"></div>

    <button type="submit">S'inscrire</button>
</form>
<div id="resultatInscription" class="resultat" style="display:none;"></div>

Remarquez la structure : chaque champ est suivi d'un <div class="erreur"> vide qui servira à afficher le message d'erreur correspondant.

script.js (à ajouter)
let formInscription = document.querySelector("#formInscription");

// Fonction utilitaire : afficher une erreur sous un champ
function afficherErreur(champId, erreurId, message) {
    document.querySelector(champId).classList.add("input-erreur");
    document.querySelector(champId).classList.remove("input-valide");
    document.querySelector(erreurId).textContent = message;
}

// Fonction utilitaire : marquer un champ comme valide
function marquerValide(champId, erreurId) {
    document.querySelector(champId).classList.remove("input-erreur");
    document.querySelector(champId).classList.add("input-valide");
    document.querySelector(erreurId).textContent = "";
}

function validerInscription(event) {
    event.preventDefault();

    let nom = document.querySelector("#inscNom").value.trim();
    let email = document.querySelector("#inscEmail").value.trim();
    let mdp = document.querySelector("#inscMdp").value;
    let confirm = document.querySelector("#inscConfirm").value;

    let estValide = true;

    // Validation du nom
    if (nom === "") {
        afficherErreur("#inscNom", "#erreurNom", "Le nom est obligatoire.");
        estValide = false;
    } else if (nom.length < 2) {
        afficherErreur("#inscNom", "#erreurNom", "Le nom doit contenir au moins 2 caractères.");
        estValide = false;
    } else {
        marquerValide("#inscNom", "#erreurNom");
    }

    // Validation de l'email
    if (email === "") {
        afficherErreur("#inscEmail", "#erreurEmail", "L'email est obligatoire.");
        estValide = false;
    } else if (!email.includes("@") || !email.includes(".")) {
        afficherErreur("#inscEmail", "#erreurEmail", "Format email invalide.");
        estValide = false;
    } else {
        marquerValide("#inscEmail", "#erreurEmail");
    }

    // Validation du mot de passe
    if (mdp === "") {
        afficherErreur("#inscMdp", "#erreurMdp", "Le mot de passe est obligatoire.");
        estValide = false;
    } else if (mdp.length < 6) {
        afficherErreur("#inscMdp", "#erreurMdp", "Minimum 6 caractères.");
        estValide = false;
    } else {
        marquerValide("#inscMdp", "#erreurMdp");
    }

    // Validation de la confirmation
    if (confirm === "") {
        afficherErreur("#inscConfirm", "#erreurConfirm", "Veuillez confirmer le mot de passe.");
        estValide = false;
    } else if (confirm !== mdp) {
        afficherErreur("#inscConfirm", "#erreurConfirm", "Les mots de passe ne correspondent pas.");
        estValide = false;
    } else {
        marquerValide("#inscConfirm", "#erreurConfirm");
    }

    // Si tout est valide
    if (estValide) {
        let res = document.querySelector("#resultatInscription");
        res.style.display = "block";
        res.textContent = `Inscription réussie pour ${nom} (${email}).`;
        res.style.color = "green";
        formInscription.reset();  // Vider tous les champs du formulaire
    }
}

formInscription.addEventListener("submit", validerInscription);
Décryptage du code

Voici les points clés à retenir :

  • .trim() — supprime les espaces au début et à la fin (évite qu'un champ rempli d'espaces passe la validation)
  • classList.add() / classList.remove() — ajoute ou retire une classe CSS (pour changer l'apparence du champ)
  • Le drapeau estValide — commence à true. Chaque erreur le passe à false. On ne soumet que si toutes les vérifications passent
  • formInscription.reset() — remet tous les champs du formulaire à leur valeur initiale
À faire maintenant

Testez le formulaire d'inscription. Essayez : tous les champs vides, un email sans @, un mot de passe trop court, deux mots de passe différents, puis une inscription valide. Observez les bordures rouges/vertes et les messages.

5

Les Événements focus et blur

5.1 C'est quoi focus et blur ?

Analogie simple

Quand vous cliquez dans un champ texte, le curseur apparaît et le champ est prêt à recevoir votre saisie — c'est le focus (le projecteur est braqué sur ce champ).

Quand vous cliquez ailleurs ou appuyez sur Tab, le champ perd le focus — c'est le blur (le projecteur se déplace).

Événement Se déclenche quand... Usage courant
"focus" L'utilisateur entre dans un champ Afficher une aide, un indice
"blur" L'utilisateur quitte un champ Valider le champ immédiatement

5.2 Validation au blur (champ par champ)

Au lieu d'attendre que l'utilisateur clique sur « Envoyer », on peut valider chaque champ dès qu'il le quitte. C'est une meilleure expérience utilisateur.

index.html (à ajouter)
<h2>Validation au blur</h2>
<form id="formBlur">
    <label for="blurNom">Nom :</label>
    <input type="text" id="blurNom">
    <div class="erreur" id="errBlurNom"></div>

    <label for="blurAge">Âge :</label>
    <input type="number" id="blurAge">
    <div class="erreur" id="errBlurAge"></div>

    <button type="submit">Envoyer</button>
</form>
script.js (à ajouter)
// Validation du nom quand l'utilisateur quitte le champ
let blurNom = document.querySelector("#blurNom");

blurNom.addEventListener("blur", function() {
    let valeur = blurNom.value.trim();
    if (valeur === "") {
        afficherErreur("#blurNom", "#errBlurNom", "Le nom est obligatoire.");
    } else {
        marquerValide("#blurNom", "#errBlurNom");
    }
});

// Validation de l'âge quand l'utilisateur quitte le champ
let blurAge = document.querySelector("#blurAge");

blurAge.addEventListener("blur", function() {
    let age = Number(blurAge.value);
    if (blurAge.value === "") {
        afficherErreur("#blurAge", "#errBlurAge", "L'âge est obligatoire.");
    } else if (age < 1 || age > 120) {
        afficherErreur("#blurAge", "#errBlurAge", "L'âge doit être entre 1 et 120.");
    } else {
        marquerValide("#blurAge", "#errBlurAge");
    }
});

// Soumission du formulaire
document.querySelector("#formBlur").addEventListener("submit", function(event) {
    event.preventDefault();
    // Déclencher le blur sur tous les champs pour forcer la validation
    blurNom.dispatchEvent(new Event("blur"));
    blurAge.dispatchEvent(new Event("blur"));

    // Vérifier s'il reste des erreurs
    let erreurs = document.querySelectorAll("#formBlur .input-erreur");
    if (erreurs.length === 0) {
        alert("Formulaire valide !");
    }
});
Résultat

L'erreur apparaît dès que l'utilisateur quitte un champ, sans attendre la soumission. C'est plus réactif et plus agréable. Lors de la soumission, on re-déclenche le blur pour attraper les champs jamais visités.

À faire maintenant

Testez en cliquant dans le champ Nom, puis cliquez ailleurs sans rien écrire. L'erreur doit apparaître immédiatement. Faites de même avec le champ Âge.

6

Formulaires Dynamiques

6.1 Activer/désactiver un champ

On peut rendre un champ inaccessible avec la propriété disabled. C'est utile quand un champ ne doit être rempli que si une condition est remplie.

index.html (à ajouter)
<h2>Champs conditionnels</h2>
<form id="formConditionnel">
    <div class="groupe-checkbox">
        <input type="checkbox" id="aEntreprise">
        <label for="aEntreprise">Je travaille dans une entreprise</label>
    </div>

    <label for="nomEntreprise">Nom de l'entreprise :</label>
    <input type="text" id="nomEntreprise" disabled placeholder="Cochez la case ci-dessus">
</form>
script.js (à ajouter)
let caseEntreprise = document.querySelector("#aEntreprise");
let champEntreprise = document.querySelector("#nomEntreprise");

caseEntreprise.addEventListener("change", function() {
    if (caseEntreprise.checked) {
        // Activer le champ
        champEntreprise.disabled = false;
        champEntreprise.placeholder = "Nom de votre entreprise";
        champEntreprise.focus();  // Placer le curseur dans le champ
    } else {
        // Désactiver et vider le champ
        champEntreprise.disabled = true;
        champEntreprise.value = "";
        champEntreprise.placeholder = "Cochez la case ci-dessus";
    }
});
Propriétés utiles
  • element.disabled = true/false — active ou désactive un champ
  • element.focus() — place le curseur dans un champ (pratique pour guider l'utilisateur)
  • element.placeholder = "..." — modifie le texte indicatif
À faire maintenant

Testez le code. Cochez et décochez la case. Le champ entreprise doit s'activer/se désactiver dynamiquement.

6.2 Afficher/masquer une section selon un choix

Un cas très courant : afficher des champs supplémentaires selon la valeur choisie dans une liste déroulante.

index.html (à ajouter)
<h2>Mode de paiement</h2>
<form id="formPaiement">
    <label for="modePaiement">Paiement par :</label>
    <select id="modePaiement">
        <option value="">-- Choisir --</option>
        <option value="carte">Carte bancaire</option>
        <option value="virement">Virement bancaire</option>
    </select>

    <div id="sectionCarte" style="display:none;">
        <label for="numCarte">Numéro de carte :</label>
        <input type="text" id="numCarte" placeholder="1234 5678 9012 3456">
    </div>

    <div id="sectionVirement" style="display:none;">
        <label for="iban">IBAN :</label>
        <input type="text" id="iban" placeholder="TN59 1234 5678 9012 3456 78">
    </div>
</form>
script.js (à ajouter)
let modePaiement = document.querySelector("#modePaiement");
let sectionCarte = document.querySelector("#sectionCarte");
let sectionVirement = document.querySelector("#sectionVirement");

modePaiement.addEventListener("change", function() {
    let choix = modePaiement.value;

    // Masquer toutes les sections d'abord
    sectionCarte.style.display = "none";
    sectionVirement.style.display = "none";

    // Afficher la section correspondante
    if (choix === "carte") {
        sectionCarte.style.display = "block";
    } else if (choix === "virement") {
        sectionVirement.style.display = "block";
    }
});
Résultat

Quand l'utilisateur choisit « Carte bancaire », le champ numéro de carte apparaît. Quand il choisit « Virement », le champ IBAN apparaît. Quand il revient à « -- Choisir -- », tout disparaît.

À faire maintenant

Testez en changeant le mode de paiement. Vérifiez que les sections s'affichent et se masquent correctement.

6.3 Réinitialiser un formulaire

Deux méthodes pour remettre un formulaire à zéro :

// Méthode 1 : Le bouton HTML reset (automatique)
// <button type="reset">Réinitialiser</button>

// Méthode 2 : En JavaScript
document.querySelector("#monFormulaire").reset();
// → Remet TOUS les champs du formulaire à leur valeur par défaut
Quand utiliser reset() ?

Après une soumission réussie, appelez form.reset() pour vider les champs. N'oubliez pas d'effacer aussi les messages d'erreur et les classes CSS input-erreur / input-valide manuellement, car reset() ne touche pas aux classes ni au contenu des <div>.

7

Le Schéma à Retenir

Tout formulaire interactif en JavaScript suit ce schéma en 4 étapes :

// ========================================
// ÉTAPE 1 : SÉLECTIONNER le formulaire
// ========================================
let form = document.querySelector("#monFormulaire");

// ========================================
// ÉTAPE 2 : ÉCRIRE la validation
// ========================================
function valider(event) {
    event.preventDefault();  // Empêcher le rechargement

    // a) Lire les valeurs : .value, .checked
    // b) Vérifier chaque champ
    // c) Afficher les erreurs ou le succès
}

// ========================================
// ÉTAPE 3 : ASSOCIER l'événement "submit"
// ========================================
form.addEventListener("submit", valider);

// ========================================
// ÉTAPE 4 (bonus) : VALIDER en temps réel
// ========================================
// Ajouter des écouteurs "blur" ou "input"
// sur les champs individuels
Résumé en une phrase

« J'intercepte la soumission, je lis les valeurs, je vérifie tout, et j'affiche le résultat ou les erreurs. »

8

Exercices

Pour chaque exercice, créez le HTML et le JavaScript nécessaires. Suivez le schéma en 4 étapes et réutilisez les fonctions afficherErreur et marquerValide.

Exercice 1 Formulaire de réservation

Créez un formulaire de réservation de restaurant avec :

  • Nom (texte, obligatoire, min 2 caractères)
  • Date de réservation (date, obligatoire, ne doit pas être dans le passé)
  • Nombre de personnes (nombre, obligatoire, entre 1 et 20)
  • Un <select> pour l'heure (12h, 13h, 19h, 20h, 21h)
  • Un <textarea> pour les remarques (optionnel)

Validez tous les champs à la soumission. Affichez un résumé de la réservation si tout est correct.

Indice pour la date : comparez avec new Date().toISOString().split("T")[0] qui donne la date du jour au format "2026-03-31".

Exercice 2 Formulaire de commande de pizza

Créez un formulaire de commande avec :

  • Nom du client (texte, obligatoire)
  • Taille de la pizza : radio (Petite = 8 DT, Moyenne = 12 DT, Grande = 16 DT)
  • Suppléments : checkbox (Fromage +2 DT, Champignons +1.5 DT, Olives +1 DT, Viande +3 DT)
  • Un bouton « Commander »

À la soumission, affichez un récapitulatif avec le nom, la taille choisie, les suppléments, et le prix total.

Indice : associez les prix aux value de vos <input> et utilisez Number() pour les additionner.

Exercice 3 Validation en temps réel complète

Créez un formulaire d'inscription avec validation au blur sur chaque champ :

  • Nom (min 2 caractères)
  • Email (doit contenir @ et .)
  • Téléphone (exactement 8 chiffres — utilisez .length)
  • Mot de passe (min 8 caractères, doit contenir au moins un chiffre)
  • Confirmation du mot de passe (doit être identique)

Chaque champ se valide dès qu'on le quitte (blur). La soumission ne passe que si tous les champs sont valides.

Indice pour le chiffre dans le mot de passe : parcourez chaque caractère avec une boucle for et utilisez !isNaN(caractere) pour tester si c'est un chiffre.

Exercice 4 Formulaire conditionnel (sondage)

Créez un sondage qui s'adapte selon les réponses :

  • Question 1 : « Êtes-vous étudiant ? » (radio : Oui / Non)
  • Si Oui → afficher un champ « Établissement » et un <select> « Niveau d'études » (Licence 1, Licence 2, Licence 3, Master 1, Master 2)
  • Si Non → afficher un champ « Profession » et un champ « Entreprise »
  • Question 2 : « Acceptez-vous les conditions d'utilisation ? » (checkbox, obligatoire)
  • Un bouton « Envoyer » désactivé tant que les conditions ne sont pas acceptées

Indice pour le bouton : écoutez "change" sur la checkbox et modifiez bouton.disabled.

Exercice 5 Formulaire multi-étapes

Créez un formulaire en 3 étapes qui affiche une section à la fois :

  • Étape 1 : Informations personnelles (Nom, Email) + bouton « Suivant »
  • Étape 2 : Adresse (Ville, Code postal, Pays via <select>) + boutons « Précédent » et « Suivant »
  • Étape 3 : Récapitulatif de toutes les données + bouton « Confirmer »

Chaque étape est un <div> qu'on affiche ou masque. Validez les champs avant de passer à l'étape suivante. À l'étape 3, affichez un résumé de tout ce qui a été saisi.

Indices :

  • Utilisez style.display = "none" / "block" pour montrer/cacher les étapes
  • Les boutons « Suivant » et « Précédent » doivent être de type "button" (pas "submit")
  • Seul le bouton « Confirmer » à l'étape 3 sera de type "submit"

Récapitulatif

Concept Syntaxe
Intercepter la soumission form.addEventListener("submit", fn)
Empêcher le rechargement event.preventDefault()
Lire un champ texte/email/password input.value
Lire un checkbox / radio input.checkedtrue / false
Lire le radio coché d'un groupe querySelector('input[name="x"]:checked')
Lire toutes les checkbox cochées querySelectorAll('input[name="x"]:checked')
Lire un select select.value
Lire un textarea textarea.value
Supprimer les espaces inutiles chaine.trim()
Ajouter / retirer une classe CSS el.classList.add("x") / .remove("x")
Activer / désactiver un champ input.disabled = true / false
Donner le focus à un champ input.focus()
Réinitialiser un formulaire form.reset()
Validation au départ du champ input.addEventListener("blur", fn)
Afficher / masquer un élément el.style.display = "block" / "none"

Ressources complémentaires