skip to Main Content

I am trying to get the ID of the task when I click edit. The reason for this, is I want to use the ID from the data-id="${task.id}" that identifies each task created.

I have created a function that renders the task and it works:

taskArray.forEach((task) => {
        let divEl = document.createElement("div");
        divEl.classList.add("task-flex");
    
        divEl.innerHTML = `<div class="task-buttons">
            <img src="./resources/icons/edit.png" id="edit-button" alt="Edit Buttin"/>
            <img src="./resources/icons/bin.png" id="remove-button" alt="Bin Buttons" />
            <img src="./resources/icons/completed-task.png" id="complete-button" alt="Complete Task Button" />
          </div>
    
          <div class="task-to-do" data-id="${task.id}" data-value = "${task.timeStamp}">
              <div class="list" id="list-item-date">Due: ${task.date}</div>
              <div class="list" id="list-item-task">${task.task}</div>
          </div>`;
    
        taskListEl.append(divEl);
        
      });

This part I need assistance with.

I selected all of the edit-buttons, I then created a forEach loop for the edit-button in the forEach loop, I use the closest method to find the parent element of the edit button (editBtn)

This part is not working, its not doing anything in the console

// Event listener for edit buttons
    let editBtns = document.querySelectorAll(".edit-button");
    

    editBtns.forEach(editBtn => {
      let toDoTask = editBtn.closest(".task-to-do");
      let dataId = toDoTask.getAttribute("data-id");
      
      editBtn.addEventListener("click", (event) => {
          console.log(`Edit button clicked for task with data-id: ${dataId}`);
      });
  });

This is all one function

2

Answers


  1. You can add the event listeners to each task’s div (divEl) directly in the forEach loop. But instead of assigning an id to each img, you can for example use data- attribute to designate the actions. In your example, each icon image would get the same id for each task, which is not good practice. Maybe you meant class?

    You would then define functions to handle edit, remove and complete actions, where the id of the task is passed as a variable from the event listener function. Here is an example:

    const taskArray = [
      { id: 1, timeStamp: '1234', date: '01/01/01', task: 'Task 1' },
      { id: 2, timeStamp: '1234', date: '01/01/01', task: 'Task 2' },
      { id: 3, timeStamp: '1234', date: '01/01/01', task: 'Task 3' }
    ]
    
    const taskListEl = document.getElementById('taskList')
    
    taskArray.forEach((task) => {
      let divEl = document.createElement('div')
    
      divEl.classList.add('task-flex')
      divEl.innerHTML = `<div class="task-buttons">
        <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXBlbmNpbCI+PHBhdGggZD0iTTE3IDNhMi44NSAyLjgzIDAgMSAxIDQgNEw3LjUgMjAuNSAyIDIybDEuNS01LjVaIi8+PHBhdGggZD0ibTE1IDUgNCA0Ii8+PC9zdmc+"
          data-action="edit" alt="Edit Buttin"/>
        <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXRyYXNoIj48cGF0aCBkPSJNMyA2aDE4Ii8+PHBhdGggZD0iTTE5IDZ2MTRjMCAxLTEgMi0yIDJIN2MtMSAwLTItMS0yLTJWNiIvPjxwYXRoIGQ9Ik04IDZWNGMwLTEgMS0yIDItMmg0YzEgMCAyIDEgMiAydjIiLz48L3N2Zz4="
          data-action="remove" alt="Bin Buttons" />
        <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWNoZWNrIj48cGF0aCBkPSJNMjAgNiA5IDE3bC01LTUiLz48L3N2Zz4="
          data-action="complete" alt="Complete Task Button" />
      </div>
    
      <div class="task-to-do" data-id="${task.id}" data-value = "${task.timeStamp}">
          <div class="list" id="list-item-date">Due: ${task.date}</div>
          <div class="list" id="list-item-task">${task.task}</div>
      </div>`
    
      divEl.addEventListener('click', (event) => {
        switch (event.target.dataset.action) {
          case 'edit':
            editTask(task.id)
            break
          case 'remove':
            removeTask(task.id)
            break
          case 'complete':
            completeTask(task.id)
            break
        }
      })
    
      taskListEl.append(divEl)
    })
    
    function editTask(id) {
      console.log('Edit task id ' + id)
    }
    
    function removeTask(id) {
      console.log('Remove task id ' + id)
    }
    
    function completeTask(id) {
      console.log('Complete task id ' + id)
    }
    body {
     font-family: 'Arial';
     font-size: 12px;
    }
    .task-buttons img {
      height: 14px;
      width: 14px;
      cursor: pointer;
     }
     
     .task-flex {
      display: flex;
      margin-bottom: 5px;
     }
     
     .task-to-do {
      display: flex;
     }
     
     .list {
      margin-left: 20px;
     }
    <html>
    <head></head>
    <body>
      <div id="taskList"></div>
    </body>
    </html>
    Login or Signup to reply.
  2. Here are your mistakes:

    1. You can’t use more than one unique id on the page (id="edit-button");
      To fix this point just replase id="edit-button" with class="edit-button";

    2. This selector "document.querySelectorAll(".edit-button")" is supposed to select all elements with class name "edit-button". This won’t work in your current implementation. When you fix the #1 point it will work.

    3. In this line let toDoTask = editBtn.closest(".task-to-do") you are trying to get parent element with classname "task-to-do" of the "editBtn" element. But your div with "task-to-do" classname isn’t parent of it, but a sibling one.

    Here is my variant:

    1. Creating an array of tasks.
    taskArray.forEach((task) => {
      const divEl = document.createElement("div");
      const uniqueId = task.id;
      divEl.classList.add("task-flex");
      divEl.id = uniqueId;
      divEl.innerHTML = `
        <div class="task-buttons">
         <button class="edit-button" data-action="edit" data-id=`${uniqueId}`>
          <img src="./resources/icons/edit.png" alt="Edit Buttin"/>
         </button>
         <button class="remove-button" data-action="remove" data-id=`${uniqueId}`>
          <img src="./resources/icons/bin.png" alt="Bin Buttons" />
         </button>
         <button class="complete-button" data-action="complete" data-id=`${uniqueId}`>
          <img src="./resources/icons/completed-task.png" alt="Complete Task Button" />
         </button>
        </div>
        <div class="task-to-do" data-id="${task.id}" data-value="${task.timeStamp}">
          <div class="list" id=`${uniqueId}-list-item-date`>Due: ${task.date}</div>
          <div class="list" id=`${uniqueId}-list-item-task`>${task.task}</div>
        </div>`;
       taskListEl.append(divEl); 
    });
    

    2.Event Listeners.

    [...document.querySelectorAll(".task-flex")].forEach((task) => {
      [...task.querySelectorAll("button")].forEach((button) => {
        const action = button.getAttribute("data-action");
        const taskId = button.getAttribute("data-id");
        button.addEventListener("click", () => {
          console.log(`Action: ${action} for ID: ${taskId}`);
        });
      });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search