Search code examples
javascriptclassmethodsaddeventlistener

In a Class call an element HTML in a method for an addEventlistener in an other method


(i'm french, i going to try to explain in english but if you can't understand i'm sorry). I had looking on MDN and i had tried to find the answer here but i think i don't use the good keywords.

So, i'm learning JS, and i have a exercice to do for my first classes (\o/). But I'm blocked step 3.

I need to add in my classe a method (changeStatut) with a addEventListener on a "click" of a button create whith an other method (addToDOM()) of this class . And i don't understand how to indicate THIS.

Do i need to use a "this" in the second method ? but how ?

this button "on click" need to change sur value of my bolean "done".

class Task {
    title;
    priority;
    done=false;

    constructor(title,priority){
        this.title=title;
        this.priority=priority;
    }

    addToDOM(){
    const tasklist = document.getElementById("tasks");
    const newTask = document.createElement("li");
    newTask.classList.add("task-item");

    const taskTitle = document.createElement("span");
    taskTitle.classList.add("task-title");
    taskTitle.textContent = `${this.title}`;

    const taskPriority = document.createElement("span");
    taskPriority.classList.add("task-priority");
    taskPriority.textContent = `${this.priority}`;
    taskPriority.classList.add(`task-priority--${this.priority}`);

    const taskButton = document.createElement("button");
    taskButton.classList.add("task-action");
    taskButton.textContent = "Changer le statut";

    tasklist.prepend(newTask);
    newTask.append(taskTitle,taskPriority,taskButton);

    }

    changeStatut(){

         let statut = this.done;
             statut = !statut;
             return statut;
        }

    }   

const task2 = new Task("Tailler la haie",3);
task2.addToDOM();

i had try to point on the same ID of the DOM.


Solution

  • I suppose your are looking for something like that ?

    class Task
      {
      _tasklist = document.getElementById('tasks')
        ;
      constructor(title, priority) 
        {
        this.title    = title;
        this.priority = priority;
        this.done     = false;
        }
      addToDOM()
        {
        const
          newTask      = this._tasklist.appendChild( document.createElement('li') )
        , taskTitle    = newTask.appendChild( document.createElement('span'))
        , taskPriority = newTask.appendChild( document.createElement('span'))
        , taskButton   = newTask.appendChild( document.createElement('button'))
          ;
        newTask     .className = 'task-item';
        taskTitle   .className = 'task-title';
        taskPriority.className = `task-priority task-priority--${this.priority}`;
        taskButton  .className = 'task-action';    
        
        taskTitle   .textContent = this.title;
        taskPriority.textContent = this.priority;
        taskButton  .textContent = 'Changer le statut';
    
        taskButton.addEventListener('click', ()=>
          {
          this.done = !this.done;
          console.log( 'this.done :' , this.done )
          return this.done;
          });
      } }
      
    const task2 = new Task('Tailler la haie', 3);
    task2.addToDOM();
    

    following Peter Seliger's comment:

    What is the reason for using a pseudo private _tasklist instead of the available true private #tasklist ?

    I realized that I had missed this good evolution of language. so here is a fix:

    class Task
      {
      static #tasklist = document.getElementById('tasks')
        ;
      constructor(title, priority) 
        {
        let fragHTML = new Range().createContextualFragment( 
         `<li class="task-item">
            <span class="task-title">${title}</span>
            <span class="task-priority task-priority--${priority}">${priority}</span>
            <span>...</span>
            <button class="task-action">Changer le statut</button>
          </li>`);
        this.done       = false;
        this.statut_elm = fragHTML.querySelector('li > span:nth-of-type(3)');
    
        fragHTML.querySelector('button.task-action').addEventListener('click', () =>
          {
          this.done                   = !this.done;
          this.statut_elm.textContent = this.done ? 'done' : '...';
          });
        
        Task.#tasklist.prepend(fragHTML);
      } }
    
    const
      task2 = new Task('Tailler la haie', 3)
    , taskZ = new Task('éplucher les carottes', 15)
      ;
    #tasks { list-style-type: none; padding: 0; }
    #tasks li { width: 30em; height: 1.8em; margin: .2em 0; }
    #tasks li span { display: inline-block; padding: 0.4em .5em 0 .5em; }
    #tasks li span:first-of-type { width: 12em; } 
    #tasks li span:nth-of-type(2) { width: 2em; text-align: right; } 
    #tasks li button { float: right; }
    <ul id="tasks"></ul>