skip to Main Content

So this is a pretty basic list. Delete button appears next to any item when it is added.

Now when I click the list item, it opens up a text field but somehow it swallows the delete button and everything is messed up.

I think this is happening due to bubbling but I don’t know how to solve this.

const form = document.getElementById('form');
const list = document.getElementById('list');

form.addEventListener('submit', function (event) {
    event.preventDefault();
    // console.log("Form submitted");

    const taskInput = document.getElementById('task');
    const todo = taskInput.value;
    // console.log("Task:", todo);

    const listItem = document.createElement('li');
    listItem.textContent = todo;
    // console.log("List item:", listItem);

    list.appendChild(listItem);
    // console.log("List updated");

    taskInput.value = '';
    const deleteButton = document.createElement('button');
    deleteButton.innerHTML = 'Delete';
    listItem.appendChild(deleteButton);

    deleteButton.addEventListener('click', function () {
        list.removeChild(listItem);
    });
});

list.addEventListener('click', function (event) {
    const listItem = event.target;

    if (listItem.tagName === 'LI') {
        const text = listItem.textContent;
        listItem.innerHTML = ''; // Clear the list item content

        const inputElement = document.createElement('input');
        inputElement.type = 'text';
        inputElement.value = text;
        listItem.appendChild(inputElement);

        inputElement.focus();

        inputElement.addEventListener('blur', function () {
            const newText = inputElement.value;
            listItem.removeChild(inputElement);

            listItem.textContent = newText; // Update the list item text
            inputElement.removeEventListener('blur', onBlur);           
        });
       
        function onBlur() {
            const newText = inputElement.value;
            listItem.removeChild(inputElement);
            listItem.textContent = newText; // Update the list item text
            inputElement.removeEventListener('blur', onBlur);
        }
        inputElement.addEventListener('blur', onBlur);
    }
});
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>To-do List</title>
      </head>
      <body>
        <header></header>
        <main>
          <h1>To-do List</h1>
          <form action="#" id="form">
            <label for="task">Enter your task:</label>
            <input type="text" id="task" required />
            <button type="submit">Add Task</button>
          </form>
          <ul id="list"></ul>
        </main>
        <footer></footer>
        <script src="app.js"></script>
      </body>
    </html>

2

Answers


  1. You should select all the list items with document.querySelectorAll() function. This will return you a NodeList and iterate that NodeList with .forEach() function and put a argument on that and remove that item.

    It should be like this:

    
    let listItems = document.querySelectorAll(".todo-item") // add that class to all todo items.
    
    listItems.forEach(function(parameter){
      parameter.addEventListener("click", function(otherParameter){ // that parameter should be different from forEach function's parameter
    // do your other actions on there.
    })
    })
    
    
    Login or Signup to reply.
  2. Your issue is that the order and position you put your dynamically created elements.

    It also turns out that to edit the elements you just need for them to be marked as contentEditable – – no JavaScript needed!

    To make things a little easier, I made it so the new <li> will get a new <span> inserted into it and that <span> will be the thing that contentEditable is added to as well as the user’s text input. This keeps the delete <button> out of the edit equation.

    And, since you really aren’t submitting the form data anywhere, instead of handling the form.submit event, you should just have a regular button and handle the click event.

    See comments inline:

    const btn = document.querySelector('button[type="button"]');
    const list = document.getElementById('list');
    const taskInput = document.getElementById('task');
    
    btn.addEventListener('click', function (event) {
        // New <li>
        const listItem = document.createElement('li');
        
        // New <span>
        const span = document.createElement("span");
        span.contentEditable = true;
        span.textContent = taskInput.value;
        
        // New <button> for deleting the <li>
        const deleteButton = document.createElement('button');
        deleteButton.textContent = 'Delete';
        
        // Event handler for delete <button>
        deleteButton.addEventListener('click', function () {
            list.removeChild(listItem);
        });  
        
        // <span> is added to new <li>
        listItem.appendChild(span);
    
        // Delete <button> is added to new <li>
        listItem.appendChild(deleteButton);
        
        // <li> is added to static <ul>
        list.appendChild(listItem);    
    
        taskInput.value = '';   // Reset text box
    });
    <h1>To-do List</h1>
    <form action="#" id="form">
      <label for="task">Enter your task:</label>
      <input type="text" id="task" required>
      <button type="button">Add Task</button>
    </form>
    <ul id="list"></ul>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search