Home > Net >  Filter todo items in javascript todo list
Filter todo items in javascript todo list

Time:11-20

I tried every method to make this todo-list filter work ,but nothing seems to be helping, please help if you can with a simple solution, please help if you can come up with a solution or you can figure out what's wrong and please explain the steps too as I am a complete beginner, I'm using switch statements to select the respective blocks to be executed however I keep getting the following error "Uncaught TypeError: Cannot set property 'display' of undefined" but I don't understand what element is undefined.

thanks :)

<script>

//Selectors
const todoInput = document.querySelector(".todo-input");
const todoButton = document.querySelector(".todo-button");
const todoList = document.querySelector(".todo-list");
const filterOption = document.querySelector(".filter-todo");

//EventListener
todoButton.addEventListener('click', addtodo);
todoList.addEventListener('click', deleteCheck);
filterOption.addEventListener('click', filterTodo);

//Functions
function addtodo(e) {
    //prevent form from submitting
    e.preventDefault();
    //Todo DIV
    const todoDiv = document.createElement('div');
    todoDiv.classList.add("todo");
    //Create LI
    const newTodo = document.createElement('li');
    newTodo.innerHTML = todoInput.value;
    todoDiv.appendChild(newTodo);
    //Check button
    const completedButton = document.createElement('button');
    completedButton.classList.add("completed-btn");
    completedButton.innerHTML = ' <i > </i> ';
    todoDiv.appendChild(completedButton);
    //Delete button
    const trashButton = document.createElement('button');
    trashButton.classList.add("trash-btn");
    trashButton.innerHTML = ' <i > </i> ';
    todoDiv.appendChild(trashButton);
    //Append to List 
    todoList.appendChild(todoDiv)
    //Clear Todo Input Value
    todoInput.value = "";
}

function deleteCheck(e) {
    const item = e.target;
    //Deleting Todo
    if (item.classList[0] === "trash-btn") {
        const todo = item.parentElement;
        //Animation
        todo.classList.add('fall');
        todo.addEventListener('transitionend', function () {
            todo.remove();
        })
    }
    //Check mark
    if (item.classList[0] === "completed-btn") {
        const todo = item.parentElement;
        todo.classList.toggle("completed");
    }
}

    
function filterTodo(e) {
    const todos = todoList.childNodes;
    todos.forEach(function(todo) {
        if (todo.nodeName === "LI") {
        switch (e.target.value) {
            case "all":
                todo.style.display = "flex";
                break;
            case "completed":
                if (todo.classList.contains("completed")) {
                    todo.style.display = "flex";
                } else {
                    todo.style.display = "none";
                }

        }
    }
    })
}
</script>
<body>
 <header>
     <h1>Jash's To-Do List</h1>
 </header>
 <form >
     <input type="text" class="todo-input">
     <button class="todo-button" type="submit">
     <i class="fas fa-plus-square"></i>
    </button>
    <div class="select">
    <select name="todos" class="filter-todo">
        <option value="all">All</option>
        <option value="completed">Completed</option>
        <option value="uncompleted">Uncompleted</option>
    </select>
</div>
 </form>
 
 <div class="todo-container">
     <ul class="todo-list">
    </ul>
 </div>
</body>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

//Selectors

//EventListener

filterOption.addEventListener("change", filterTodo);

function filterTodo(e) {
  const todos = Array.from(document.querySelectorAll(".todo-list .todo"));
  todos.forEach(function (todo) {
    console.log(todo);
    switch (e.target.value) {
      case "all":
        todo.style.display = "";
        break;
      case "completed":
        if (todo.classList.contains("completed")) {
          todo.style.display = "";
        } else {
          todo.style.display = "none";
        }
    }
  });
}

Issues were:

  • Option emits event on "change".
  • You should not iterate over child nodes but instead query the elements by selector.
  • You could iterate over child nodes but your <ul> does not have any <li> children (you used <div>) so if(todo.nodeName === "LI") is always false.
  • Related