How do I the make filter option in my To-do App work?

Hello everyone, I’m writing an event handler in Javascript that will enable me to filter my to-do list with three options (all, completed & uncompleted)… I can’t seem to get it to work
maybe because I’m a newbie, I started learning JS few weeks ago… This is the codepen link to the problem

https://codepen.io/Que0/pen/WNwVgKd

When you click on the ticks, is that completed? It toggles a class of ‘mark’

If that is the case you can change your code to look for the ‘mark’ class instead

case 'completed':
  if (todo.classList.contains('mark')) {
    todo.style.display = 'flex'
  } else {
    todo.style.display = 'none'
  }
  break
case 'uncompleted':
  if (!todo.classList.contains('mark')) {
    todo.style.display = 'flex'
  } else {
    todo.style.display = 'none'
  }
  break

Thanks for your input @rpg_digital, i have updated the code, but it’s not working exactly how I want it to… When I click on:
“all” - I want all to-do list to be displayed(marked & unmarked).
“Completed” - only the marked ones should be displayed. And,
“Uncompleted”- only the unmarked should be displayed.

I did test it and it should work.

Edit. Removed comment about typo.

This is your script with the changes from above

document.addEventListener('DOMContentLoaded', function (event) {
  // selectors
  const todoInput = document.querySelector('.todo-input')
  const todoButton = document.querySelector('.todo-button')
  const todoList = document.querySelector('.todo-list')
  const filterTodo = document.querySelector('.filter-todo')

  // event listeners
  todoButton.addEventListener('click', myTodo)
  todoList.addEventListener('click', deleteItem)
  filterTodo.addEventListener('click', filterOption)

  // functions
  function myTodo (e) {
    e.preventDefault()

    // create a Todo input container
    const todo = document.createElement('div')

    todo.classList.add('todo')

    // create a child item
    const listItem = document.createElement('li')

    listItem.classList.add('list-item')
    todo.appendChild(listItem)
    listItem.innerText = todoInput.value

    // create a mark(completed) button element
    const markTodo = document.createElement('button')

    markTodo.classList.add('mark-todo')
    markTodo.innerHTML = '<i class="fas fa-check"></i>'
    todo.appendChild(markTodo)

    // create a thrash(completed) button element
    const trashTodo = document.createElement('button')

    trashTodo.classList.add('trash-todo')
    trashTodo.innerHTML = '<i class="fas fa-trash"></i>'
    todo.appendChild(trashTodo)

    // append todo to a its todoList parent
    todoList.appendChild(todo)

    // clear input field
    todoInput.value = ''
  }

  function deleteItem (e) {
    const item = e.target

    if (item.classList[0] === 'trash-todo') {
      const deleteTodo = item.parentElement

      deleteTodo.remove()
    }

    if (item.classList[0] === 'mark-todo') {
      const markTodo = item.parentElement

      markTodo.classList.toggle('mark')
    }
  }

  function filterOption (e) {
    const todos = todoList.childNodes

    todos.forEach(function (todo) {
      switch (e.target.value) {
        case 'all':
          todo.style.display = 'flex'
          break
        case 'completed':
          if (todo.classList.contains('mark')) {
            todo.style.display = 'flex'
          } else {
            todo.style.display = 'none'
          }
          break
        case 'uncompleted':
          if (!todo.classList.contains('mark')) {
            todo.style.display = 'flex'
          } else {
            todo.style.display = 'none'
          }
          break
      }
    })
  }
})

Sorry for asking this dumb question:
You advised I changed my code to target the class of ‘mark’ like this if(todo.classList.contains('mark')) and I understand your explanation for it thanks

But from the tutorial video I’m learning from, it targeted “completed” “uncompleted” even though they are not classes like this:
if(todo.classList.contains('completed')
if(todo.classList.contains('uncompleted')

Do you have any explanation why it is so, I’d be grateful

Not a dumb question, and all part of learning:)

Obviously I don’t know anything about the video tutorial, so it is kind of hard to advise.

If we do a search through your original script for the word ‘completed’ there are 6 occurrences (including the typo ‘comnpleted’).

Twice in comments
// create a mark(completed) button element

// create a thrash(completed) button element

Twice in your switch cases
case 'completed'

case 'uncompleted'

Twice in the classList checks
if(todo.classList.contains('comnpleted') <-- completed

if(todo.classList.contains('uncompleted')

There is no where, that I can see, where we are actually setting those classes e.g.

todo.classList.add('completed') or todo.classList.toggle('completed')

This would suggest you are possibly missing a block of code from the tutorial?

In conclusion I would suggest have another look through the video/s and see if you have missed something.

1 Like

I will have a thorough look once again. Thanks

1 Like