Guide contact niveau 2: lecon conditions (if/else, singulier/pluriel) + exos JS (submit, fonction, Date)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+205
-4
@@ -372,6 +372,198 @@ zoneMessage.addEventListener("input", function () {
|
||||
|
||||
---
|
||||
|
||||
# 🎓 Niveau 2 — Les conditions (et de nouveaux exos JS)
|
||||
|
||||
**Bravo Mélissa** 👏 — tu as fait marcher le compteur **et** le bonus couleur (le compteur qui passe en rouge). Tu es prête pour la suite : les **conditions**, c'est-à-dire apprendre au programme à **choisir** quoi faire selon la situation.
|
||||
|
||||
> 🩹 **Petite correction au passage** (vu dans ton HTML) : ton champ e-mail est `type="e_mail"`. Ce type n'existe pas → le navigateur le traite comme du texte normal. Le bon, c'est `type="email"` (sans underscore). Avec, le navigateur vérifie tout seul qu'il y a bien un `@`. 😉
|
||||
|
||||
---
|
||||
|
||||
## 🧠 La leçon : `if` / `else` — faire **choisir** le programme
|
||||
|
||||
Une **condition**, c'est une question qui n'a que deux réponses : **vrai** ou **faux**. En JavaScript on écrit :
|
||||
|
||||
```js
|
||||
if (/* une question */) {
|
||||
// ce qu'on fait SI la réponse est "vrai"
|
||||
} else {
|
||||
// ce qu'on fait SINON
|
||||
}
|
||||
```
|
||||
|
||||
Pour poser la question, on utilise des **opérateurs de comparaison** :
|
||||
|
||||
| Opérateur | Question posée | Exemple vrai |
|
||||
|---|---|---|
|
||||
| `===` | est **égal à** ? | `restant === 1` |
|
||||
| `!==` | est **différent de** ? | `restant !== 0` |
|
||||
| `>` `<` | plus grand / plus petit ? | `restant < 50` |
|
||||
| `>=` `<=` | plus grand/petit **ou égal** ? | `restant >= 1` |
|
||||
|
||||
> ⚠️ **Le piège n°1 des débutants :** `=` et `===` ne veulent PAS dire la même chose !
|
||||
> - `=` (un seul) → **ranger** une valeur : `restant = 5` (« mets 5 dans restant »).
|
||||
> - `===` (trois) → **comparer** : `restant === 5` (« est-ce que restant vaut 5 ? »).
|
||||
> Dans un `if (...)`, c'est **toujours** `===`.
|
||||
|
||||
---
|
||||
|
||||
## ✍️ Exo : afficher « caractère » au singulier
|
||||
|
||||
Aujourd'hui ton HTML affiche toujours « caractères » au pluriel, même quand il n'en reste qu'**un**. On va corriger ça avec une condition.
|
||||
|
||||
### Étape 1 — Donner une étiquette au mot dans le HTML
|
||||
|
||||
Pour pouvoir changer le **mot** tout seul, on l'enferme dans son propre `<span>` :
|
||||
|
||||
```html
|
||||
<p class="small">Il vous reste <span id="restant">500</span> <span id="mot">caractères</span>.</p>
|
||||
```
|
||||
|
||||
### Étape 2 — Choisir le bon mot en JavaScript
|
||||
|
||||
Dans `contact.js`, attrape ce nouveau `<span>` (en haut, avec les autres) :
|
||||
|
||||
```js
|
||||
const motCaractere = document.getElementById("mot");
|
||||
```
|
||||
|
||||
Puis, **à l'intérieur** de ton `addEventListener("input", …)`, ajoute la condition :
|
||||
|
||||
```js
|
||||
zoneMessage.addEventListener("input", function () {
|
||||
const dejaTape = zoneMessage.value.length;
|
||||
const restant = MAX - dejaTape; // on range le calcul dans une variable, plus lisible
|
||||
|
||||
compteur.textContent = restant;
|
||||
compteur.style.color = restant < 50 ? "red" : "black";
|
||||
|
||||
// 👇 la nouvelle condition
|
||||
if (restant === 1) {
|
||||
motCaractere.textContent = "caractère"; // singulier
|
||||
} else {
|
||||
motCaractere.textContent = "caractères"; // pluriel
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**✅ Teste maintenant :** tape jusqu'à ce qu'il reste exactement **1** → tu dois lire « Il vous reste 1 **caractère** ». À 2 ou plus → « caractères ». 🎉
|
||||
|
||||
> 🔎 **Tu connaissais déjà une condition sans le savoir !** Ton bonus couleur :
|
||||
> ```js
|
||||
> compteur.style.color = restant < 50 ? "red" : "black";
|
||||
> ```
|
||||
> C'est exactement un `if`/`else`… en **version courte** (on l'appelle le *ternaire*). La version longue équivalente serait :
|
||||
> ```js
|
||||
> if (restant < 50) {
|
||||
> compteur.style.color = "red";
|
||||
> } else {
|
||||
> compteur.style.color = "black";
|
||||
> }
|
||||
> ```
|
||||
> Les deux font la même chose. Le `? :` est juste un raccourci pratique quand il n'y a qu'**une** ligne à choisir. 👍
|
||||
|
||||
---
|
||||
|
||||
## 🧪 De nouveaux exos pour découvrir plus de JavaScript
|
||||
|
||||
Chaque exo t'apprend **une nouvelle notion**. Fais-les dans l'ordre, et teste à chaque fois.
|
||||
|
||||
### 🧪 Exo 1 — Empêcher l'envoi d'un message vide
|
||||
|
||||
> 🆕 Nouvelle notion : réagir à l'**envoi du formulaire** (`"submit"`) et **bloquer** l'action par défaut.
|
||||
|
||||
Aujourd'hui, si on clique « Envoyer » avec un message vide, le formulaire part quand même. On va l'en empêcher.
|
||||
|
||||
```js
|
||||
const formulaire = document.querySelector("form"); // on attrape le <form>
|
||||
|
||||
formulaire.addEventListener("submit", function (evenement) {
|
||||
if (zoneMessage.value.trim() === "") { // .trim() enlève les espaces autour
|
||||
evenement.preventDefault(); // ⛔ on ANNULE l'envoi
|
||||
alert("Merci d'écrire un message avant d'envoyer !");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**✅ Teste :** clique « Envoyer » sans rien écrire → une alerte apparaît et la page ne se recharge pas. Écris un message → l'envoi repart normalement.
|
||||
|
||||
> 🔎 `evenement` est une info que le navigateur passe à ta fonction (« voici ce qui s'est passé »). `evenement.preventDefault()` veut dire « n'effectue PAS l'action habituelle » (ici : ne soumets pas le formulaire). `.trim()` sert à considérer « 3 espaces » comme un message vide.
|
||||
|
||||
### 🧪 Exo 2 — Un bouton « Effacer le message »
|
||||
|
||||
> 🆕 Nouvelle notion : **ranger du code dans une fonction** pour le réutiliser (ne pas se répéter).
|
||||
|
||||
Ajoute un bouton dans le HTML, à côté de « Envoyer » :
|
||||
|
||||
```html
|
||||
<button type="button" id="effacer">Effacer</button>
|
||||
```
|
||||
|
||||
Le souci : quand on efface, il faut aussi **remettre le compteur à 500**. On a donc besoin de réafficher le compteur à **deux endroits** (à la frappe ET à l'effacement). La bonne pratique : écrire ce calcul **une seule fois** dans une fonction, et l'appeler aux deux endroits.
|
||||
|
||||
```js
|
||||
const boutonEffacer = document.getElementById("effacer");
|
||||
|
||||
// une fonction qui remet l'affichage à jour à partir du texte actuel
|
||||
function rafraichirCompteur() {
|
||||
const restant = MAX - zoneMessage.value.length;
|
||||
compteur.textContent = restant;
|
||||
compteur.style.color = restant < 50 ? "red" : "black";
|
||||
motCaractere.textContent = restant === 1 ? "caractère" : "caractères";
|
||||
}
|
||||
|
||||
// à la frappe : on rafraîchit
|
||||
zoneMessage.addEventListener("input", rafraichirCompteur);
|
||||
|
||||
// au clic sur Effacer : on vide la zone PUIS on rafraîchit
|
||||
boutonEffacer.addEventListener("click", function () {
|
||||
zoneMessage.value = ""; // on vide la textarea
|
||||
rafraichirCompteur(); // et on remet le compteur à 500
|
||||
});
|
||||
```
|
||||
|
||||
**✅ Teste :** écris du texte, clique « Effacer » → la zone se vide **et** le compteur repasse à 500.
|
||||
|
||||
> 🔎 Tu viens de **factoriser** : au lieu de recopier les mêmes lignes deux fois, tu les as mises dans `rafraichirCompteur()` et tu l'appelles. Si un jour tu changes l'affichage, tu ne le modifies **qu'à un seul endroit**. C'est exactement la même idée que le **composant réutilisable** plus bas. ♻️
|
||||
|
||||
### 🧪 Exo 3 — « FleetZen est-il joignable maintenant ? »
|
||||
|
||||
> 🆕 Nouvelle notion : lire l'**heure actuelle** (`new Date()`) et combiner deux conditions avec `&&` (ET).
|
||||
|
||||
Une page contact, ça parle d'horaires. Affichons un petit badge « ✅ Ouvert » ou « 🔴 Fermé » selon l'heure (ouvert de 9h à 18h).
|
||||
|
||||
D'abord un endroit pour l'afficher, dans le HTML :
|
||||
|
||||
```html
|
||||
<p id="statut_horaires"></p>
|
||||
```
|
||||
|
||||
Puis en JavaScript :
|
||||
|
||||
```js
|
||||
const badge = document.getElementById("statut_horaires");
|
||||
const heure = new Date().getHours(); // l'heure actuelle, de 0 à 23
|
||||
|
||||
if (heure >= 9 && heure < 18) { // && = "ET" : les DEUX doivent être vraies
|
||||
badge.textContent = "✅ Nous sommes ouverts (9h–18h)";
|
||||
badge.style.color = "green";
|
||||
} else {
|
||||
badge.textContent = "🔴 Fermé — écrivez-nous, on répond dès l'ouverture !";
|
||||
badge.style.color = "red";
|
||||
}
|
||||
```
|
||||
|
||||
**✅ Teste :** recharge la page. Selon l'heure qu'il est, tu vois « Ouvert » ou « Fermé ». (Pour tester l'autre cas sans attendre, change temporairement `9` et `18`.)
|
||||
|
||||
> 🔎 `new Date().getHours()` donne l'heure de l'ordinateur (ex. `14`). `&&` se lit « ET » : `heure >= 9 && heure < 18` n'est vrai que si l'heure est **à la fois** ≥ 9 **et** < 18. Son cousin est `||` qui se lit « OU ».
|
||||
|
||||
---
|
||||
|
||||
> 🗺️ **Où tu en es maintenant** : tu sais **sélectionner**, **réagir**, **modifier**, et maintenant **faire choisir** ton programme avec des conditions, **factoriser** dans des fonctions, et lire des infos comme l'heure. C'est déjà le cœur du JavaScript du quotidien. La suite (boucles `for`, tableaux) viendra naturellement — demande-moi quand tu veux ! 🚀
|
||||
|
||||
---
|
||||
|
||||
## ♻️ Bonus — La notion de **composant réutilisable** (la navbar)
|
||||
|
||||
Regarde : la barre du haut (`#nav_barre`) est **recopiée à l'identique** dans `index.html`, `services.html` et `contact.html`. Le jour où on change un lien, il faut le modifier **dans 3 fichiers** → source d'erreurs (c'est d'ailleurs comme ça que le Bug 2 se glisse 😉).
|
||||
@@ -407,13 +599,22 @@ document.body.insertAdjacentHTML("afterbegin", creerNavbar());
|
||||
|
||||
- [ ] Fermer `body` avec un `}` dans le CSS (Bug 1 — le plus urgent)
|
||||
- [ ] Réparer le lien vers `services.html` (Bug 2)
|
||||
- [ ] Passer le champ e-mail en `type="email"` (Bug 3)
|
||||
- [ ] Passer le champ e-mail en `type="email"` (Bug 3 — tu as mis `e_mail`, presque ! 😉)
|
||||
- [ ] Centrer l'icône SVG du bouton « retour » avec `inline-flex` (Bug 4)
|
||||
- [ ] Ajouter `rows`, `maxlength` + redimensionnement borné (`resize: vertical` + `min/max-height`)
|
||||
- [ ] Ajouter le redimensionnement borné (`resize: vertical` + `min/max-height`)
|
||||
- [ ] Centrer table et `.form` avec `margin: auto` (au lieu de `margin-left: 600px`)
|
||||
- [ ] Faire marcher le **compteur de caractères** en JavaScript
|
||||
- [x] Ajouter `rows`, `cols`, `maxlength` à la textarea ✅
|
||||
- [x] Faire marcher le **compteur de caractères** en JavaScript ✅
|
||||
- [x] Bonus couleur : compteur en rouge sous 50 caractères ✅
|
||||
- [x] Ajouter un `<footer>` ✅
|
||||
- [ ] (Bonus) Transformer la navbar en composant réutilisable
|
||||
- [ ] Penser à fermer la balise `</html>` en fin de fichier + ajouter un `<footer>`
|
||||
- [ ] Penser à fermer la balise `</html>` en fin de fichier
|
||||
|
||||
### 🎓 Niveau 2 (nouveau)
|
||||
- [ ] Afficher « caractère » au **singulier** quand il en reste 1 (leçon `if`/`else`)
|
||||
- [ ] Exo 1 — empêcher l'envoi d'un message **vide** (`submit` + `preventDefault`)
|
||||
- [ ] Exo 2 — bouton **« Effacer »** + factoriser dans une fonction
|
||||
- [ ] Exo 3 — badge **« Ouvert / Fermé »** selon l'heure (`new Date()` + `&&`)
|
||||
- [ ] Commits petits et clairs, puis `git push`
|
||||
|
||||
Pose-moi toutes tes questions. Tu gères ! 📬✨
|
||||
|
||||
Reference in New Issue
Block a user