Mini-projet — Liste de tâches interactive
Tu construis une liste courte, puis tu la défais dans l’ordre inverse du geste final : d’abord buy tea entre, ensuite tu la marques finie, enfin tu la retires. La ligne ouverte affiche buy tea. La ligne finie affiche done: buy tea.
La page d’avant s’est arrêtée aux noms
Là-bas, les savoir-faire étaient nommés et aucune liste n’apparaissait. Ici, la liste est la page. Tu t’appuies sur un tableau, un formulaire, textContent et un clic. Ajouter ne doit pas recharger la page.
Deux champs, pas une chaîne nue
tasks est un tableau d’objets. Chaque objet porte text et done. Un élément neuf part avec done à false. addTask passe les mots dans trim. S’il ne reste rien, push n’a pas lieu et l’élément n’est pas rangé.
const tasks = [];
function addTask(text) {
const clean = text.trim();
if (!clean) {
return;
}
tasks.push({ text: clean, done: false });
}
addTask("buy tea");
console.log(tasks[0].text);
console.log(tasks[0].done);
Les deux journaux se suivent : buy tea, puis false. addTask(" ") ne garde aucune lettre après trim, donc rien n’est rangé et la longueur reste 0.
Le formulaire voudrait recharger
Soumettre un formulaire recharge le document. Le tableau n’existe qu’en mémoire, alors le rechargement le lâche et la liste a l’air vide. event.preventDefault() arrête ce rechargement. Ensuite tu prends le texte, tu vides le champ et tu dessines à nouveau.
const form = document.querySelector("#add-form");
const input = document.querySelector("#task-text");
form.addEventListener("submit", (event) => {
event.preventDefault();
addTask(input.value);
input.value = "";
render();
});
Le document reste. Le champ est vide. render tourne. Un champ fait seulement d’espaces n’ajoute pas de ligne.
Deux boutons qui ne soumettent pas
render vide #tasks, puis fabrique un li par élément. Ouvert, on voit text. Fini, on voit done: suivi du texte. Chaque ligne a deux boutons, tous deux en type="button", sinon le clic soumettrait le formulaire. Done inverse le booléen. Retirer passe par splice. Les deux redessinent, parce que les anciens index viseraient le mauvais élément.
function toggleTask(index) {
tasks[index].done = !tasks[index].done;
}
function removeTask(index) {
tasks.splice(index, 1);
}
function render() {
const list = document.querySelector("#tasks");
list.textContent = "";
tasks.forEach((task, index) => {
const item = document.createElement("li");
item.textContent = task.done ? "done: " + task.text : task.text;
const doneButton = document.createElement("button");
doneButton.type = "button";
doneButton.textContent = "Done";
doneButton.addEventListener("click", () => {
toggleTask(index);
render();
});
const removeButton = document.createElement("button");
removeButton.type = "button";
removeButton.textContent = "Remove";
removeButton.addEventListener("click", () => {
removeTask(index);
render();
});
item.append(doneButton, removeButton);
list.append(item);
});
}
Enchaîne addTask("buy tea"), toggleTask(0), render. La ligne devient done: buy tea. Une autre bascule la ramène à buy tea. removeTask(0) met la longueur à 0 et le dessin suivant n’a plus de ligne. Les mots du champ entrent par textContent. Tu ne les colles pas dans la page comme du HTML.
L’index appartient à ce passage
forEach retient l’index de ce passage-là. Après splice, ces vieux numéros désignent la mauvaise tâche. Dessiner encore jette les anciens boutons et en fabrique avec les index du moment. Sans ce second dessin, Remove efface la mauvaise ligne.
Trois rôles
Le formulaire ajoute. La liste dessine. Done et Remove ne touchent que tasks, puis dessinent encore.
<!DOCTYPE html>
<html>
<body>
<form id="add-form">
<input id="task-text" type="text">
<button type="submit">Add</button>
</form>
<ul id="tasks"></ul>
<script>
const tasks = [];
function addTask(text) {
const clean = text.trim();
if (!clean) return;
tasks.push({ text: clean, done: false });
}
function toggleTask(index) {
tasks[index].done = !tasks[index].done;
}
function removeTask(index) {
tasks.splice(index, 1);
}
function render() {
const list = document.querySelector("#tasks");
list.textContent = "";
tasks.forEach((task, index) => {
const item = document.createElement("li");
item.textContent = task.done ? "done: " + task.text : task.text;
const doneButton = document.createElement("button");
doneButton.type = "button";
doneButton.textContent = "Done";
doneButton.addEventListener("click", () => {
toggleTask(index);
render();
});
const removeButton = document.createElement("button");
removeButton.type = "button";
removeButton.textContent = "Remove";
removeButton.addEventListener("click", () => {
removeTask(index);
render();
});
item.append(doneButton, removeButton);
list.append(item);
});
}
document.querySelector("#add-form").addEventListener("submit", (event) => {
event.preventDefault();
addTask(document.querySelector("#task-text").value);
document.querySelector("#task-text").value = "";
render();
});
</script>
</body>
</html>
Tape buy tea et appuie sur Add. La ligne vaut buy tea et le champ se vide. Appuie sur Done : la ligne vaut done: buy tea. Appuie sur Remove : la liste est vide. Add sur un champ vide n’ajoute rien.
Cinq gestes
- Appelle addTask("buy tea"). Le premier text est buy tea et done vaut false.
- Soumets le formulaire. La page ne se recharge pas et la ligne apparaît.
- Appuie sur Done. La ligne affiche done: buy tea.
- Appuie sur Remove. tasks.length vaut 0.
- Soumets seulement des espaces. La liste ne grandit pas.
Ce qui casse vraiment
- oublier preventDefault, et le tableau meurt à l’envoi
- faire un push d’une chaîne vide
- mettre type="submit" sur Done ou Remove
- effacer la ligne à l’écran et oublier splice, si bien que le dessin suivant la ramène
- sauter render après splice
- écrire le champ dans la page comme du HTML
À retenir
- Une tâche est { text, done } et done part à false
- addTask("buy tea") range buy tea ; un champ vide ne range rien
- preventDefault garde la page et render dessine les lignes
- Done affiche done: buy tea et Remove laisse la longueur à 0
- Redessine après chaque changement
🧠 Testez Vos Connaissances
Testez Vos Connaissances
Mettez-vous au défi avec ce quiz interactif et voyez à quel point vous comprenez le sujet
📝 Instructions
- Lisez chaque question attentivement
- Sélectionnez la meilleure réponse pour chaque question
- Vous pouvez refaire le quiz autant de fois que vous le souhaitez
- Votre progression sera affichée en haut