Contenu du cours
Projet TodoList
Programmer une Todo list (liste de choses à faire) en Javascript est un excellent exercice d'apprentissage. Une Todo list couvre différents aspects et concepts que l'on retrouvera dans la majorité des projets web : Manipulation d'objets Javscript, du DOM HTML et du CSSOM, formulaire, changement d'états, animation, etc. Dans cette section, nous allons réaliser plusieurs versions d'une Todo list, en démarrant avec une version simple que nous ferons évoluer en ajoutant des fonctionnalités.
0/13
Introduction au Javascript

Dans les versions précédentes, on a instancié nos listes avec le constructeur de la class ToDo.

Par exemple :

let todo = new ToDo('My todo', [new Item('item1'), new Item('item2'), new Item('item3')]);

Maintenant que l’on a commencé à développer l’interface, il serait préférable d’avoir des champs à remplir dans l’interface pour :

  • Ajouter un nom à la liste
  • Ajouter des éléments aux listes

Ajouter un nom à la liste

  1. Dans votre projet VSCode, dupliquer le répertoire v7-dom et nommer le v8-inputs
  2. Dans le nouveau répertoire v8-inputs :
    • Renommer v7-dom.js en v8-inputs.js
    • Remplacer le contenu du index.html par celui-ci
      • On peut voir que l’on a ajouté un peu de CSS
      • Et surtout un label et un champ de formulaire pour pouvoir entrer un nom de la liste à créer
<div>
    <label for="listName">
        Nom de la liste :
        <input type="text" id="list-name" value="My Todo" placeholder="My todo">
    </label>
    <button onclick="createList()">Créer</button>
</div>

Il faut donc maintenant mettre à jour notre fonction createList pour prendre en compte ce changement. Désormais, au moment du clic on souhaite :

  1. Récupérer la valeur de l’input (qui a l’identifiant “list-name”).
  2. Créer une instance de la classe ToDo avec le nom récupéré
  3. Passer cette instance à une nouvelle instance de la classe ToDoDom
  4. Voici le code mis à jour, prenez un moment pour l’étudier :
function createList() {
    let listName = document.getElementById('list-name').value;
    let todoList = new ToDoDom(new ToDo(listName));
    let container = document.getElementById('lists-container');
    container.append(todoList.getHTML());
}

Ajouter des éléments à la liste

Notre liste est maintenant bien ajoutée avec le nom entré dans le champ du formulaire, mais on ne peut pas encore ajouter d’éléments à la liste :

Ce que l’on voudrait, c’est avoir un champ, assigné à la liste, pour pouvoir ajouter de nouvelles tâches à la liste :

Nous allons devoir modifier la classe ToDoDom.

Dans le constructor de la classe ToDoDom

Dans notre version précédente, l’élément <ul> était créé et ajouté à un <div> dans la méthode getHTML. Cela ne va plus convenir car avec cette architecture on ne pourra pas facilement manipuler notre élément <ul> pour lui ajouter ou lui retirer des éléments <li>.

On va donc créer une propriété ul dans la classe ToDoDom.

On va en faire de même avec le champ et le bouton pour “Ajouter une tâche”

Dans le constructor de la classe ToDoDom :

constructor(todo) {
    this.todo = todo;
    this.ul = document.createElement('ul');
    this.todoInput = document.createElement('input');
    this.todoButton = document.createElement('button');
    this.todoButton.textContent = 'Ajouter une tâche';
    this.todoButton.addEventListener('click', () => this.add(this.todoInput.value));
}

On a donc ajouté 3 nouvelles propriétés à la classe ToDoDom :

  • this.ul : contient l’élément HTML <ul> de la liste
  • this.todoInput : le champ du formulaire pour entrer le texte d’une nouvelle tâche
  • this.todoButton : le bouton qui va déclencher l’ajout d’une nouvelle tache
    • this.todoButton.textContent pour spécifier le texte du bouton
    • Et enfin un “écouteur d’événement”, qui :
      • déclenchera l’execution de la fonction add de la classe ToDoDom au clic du bouton
      • passera la valeur de this.todoInput à la fonction add

Les méthodes add et createLi

Implémentons tout d’abord la méthode add, précédemment appelée par l’événement attaché à this.todoButton
Dans la classe ToDoDom :

    add(itemName) {
        this.todo.add(new Item(itemName));
        this.todoInput.value = '';
        this.ul.appendChild(this.createLi(itemName));
    }
  • On récupère le nom de l’item avec lequel on crée une nouvelle instance de la classe Item. Puis on ajoute cet objet à notre propriété this.todo, qui pour rappel est une instance de la classe ToDo
  • On réinitialise la valeur de this.todoInput pour effacer la valeur entrée par l’utilisateur
  • Puis on va ajouter un nouvel élément <li> à this.ul, à traver une nouvelle méthode createLi
  • On aurait pu directement créer un élément HTML <li> ici et l’ajouter à this.ul. Cependant, par la suite ce <li> va se complexifier et ce sera plus pratique de séparer sa création

Toujours dans la méthode ToDoDom, implémentons désormais la méthode createLi :

    createLi(item) {
        let li = document.createElement('li');
        li.textContent = '( ) ' + item;
        return li;
    }

Mise à jour de la méthode getHTML

Pour finir, on doit mettre à jour la construction HTML de notre liste pour y intégrer nos nouvelles propriétés this.ul, this.todoInput et this.todoButton :

    getHTML() {
        let container = document.createElement('div');
        container.innerHTML = '<h2>' + this.todo.name + '</h2>';

        let controls = document.createElement('div');
        controls.appendChild(this.todoInput);
        controls.appendChild(this.todoButton);
        container.appendChild(controls);

        container.appendChild(this.ul);

        return container;
    }

Et voilà ! On peut désormais créer autant de listes et de tâches que l’on veut :

On commence à être vraiment pas mal !

Prochaine étape, on va ajouter des contrôles sur les tâches pour pouvoir les valider, les éditer et les supprimer