Data not displayed propery

Viewed 30

I'm making To Do List app using vanilla JavaScript. So far I've successfully implemented a function to render a task which is submitted through the input. However whenever I add a new task, the task will be added with all the tasks I submitted previously. e.g [1],[1,2],[1,2,3] I cannot spot the problem. How do I fix this bug and why is this happening?

const todoBlock = document.querySelector('.task__nav');
const submitForm = document.querySelector('.form');
const taskItem = document.querySelector('.task');

const taskContainer = document.querySelector('.todo__container');

const showAllTasksNav = document.querySelector('.task__nav-item.all');
const showCompletedTasksNav = document.querySelector('.task__nav-item.finished');


console.log(showAllTasksNav, showCompletedTasksNav)

taskContainer.addEventListener('click', (event) => {

  const target = event.target;
  const id = target.parentNode.parentNode.parentNode.dataset.key;

  if(target.classList.contains('ion-ios-checkmark-outline')) {
    toggleTodo(id);
  } else if (target.classList.contains('ion-ios-close-outline')) {
    console.log('Delete Btn')
  }
})

let todoList = [];
todoList = JSON.parse(localStorage.getItem("todolist")) || [];
updateUI();

function addTodo(task) {

  const todo = {
    task: taskItem.value,
    isCompleted: false,
    id: Date.now()
  };

  todoList.push(todo);
  localStorage.setItem('todolist', JSON.stringify(todoList));

  updateUI();

}

function updateUI() { 
  todoList.forEach(el => {
    showEntry(el.id, el.task);
  })
}

function showEntry(id, task) {

  const markup = `
  <div class="todo__item" data-key=${id}>
    <p>${task}</p>
    <div class="icons">
        <button class="item__complete--btn"><svg class="ion-ios-checkmark-outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M340.1 177.3L215.3 303l-47.2-47.2-17.8 17.8 56 56c2.5 2.5 5.9 4.5 8.9 4.5s6.3-2 8.8-4.4l133.7-134.4-17.6-18z" fill="#626262"/><path d="M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm0 398.7c-105.1 0-190.7-85.5-190.7-190.7 0-105.1 85.5-190.7 190.7-190.7 105.1 0 190.7 85.5 190.7 190.7 0 105.1-85.6 190.7-190.7 190.7z" fill="#626262"/></svg></button>
        <button class="item__delete--btn"><svg class="ion-ios-close-outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M403.1 108.9c-81.2-81.2-212.9-81.2-294.2 0s-81.2 212.9 0 294.2c81.2 81.2 212.9 81.2 294.2 0s81.2-213 0-294.2zm-12.3 281.9c-74.3 74.3-195.3 74.3-269.6 0-74.3-74.3-74.3-195.3 0-269.6s195.3-74.3 269.6 0c74.4 74.3 74.4 195.3 0 269.6z" fill="#626262"/><path d="M340.2 160l-84.4 84.2-84-83.8-11.8 11.8 84 83.8-84 83.8 11.8 11.8 84-83.8 84.4 84.2 11.8-11.8-84.4-84.2 84.4-84.2z" fill="#626262"/></svg></button>
    </div>
  </div>
  `;

  todoBlock.insertAdjacentHTML('afterend', markup);
}

submitForm.addEventListener('submit', (event) => {
  event.preventDefault();
  if(taskItem.value !== '') {
    addTodo(taskItem.value) 
    clearInput()
  }
});

function clearInput() {
  taskItem.value = '';
}

function toggleTodo(key) {

  const index = todoList.findIndex(item => item.id === Number(key));

  todoList[index].isCompleted = !todoList[index].isCompleted;

  const item = document.querySelector(`[data-key="${key}"]`);
  if(todoList[index].isCompleted) {
      item.classList.add('completed')
  } else {
    item.classList.remove('completed');
  }
}

function deleteTodo() {

}

showAllTasksNav.addEventListener('click', displayAllTasks);
showCompletedTasksNav.addEventListener('click', displayCompletedTask);

function displayCompletedTask() {
  todoList.forEach(el => {

    if(el.isCompleted === true) {
      showEntry(el.id, el.task);
    }

  });
}

function displayAllTasks() {

}
<div class="wrapper">
        <h1>To Do List</h1>
            <div class="input__area">
                <form class="form">
                    <input class="task" type="text" placeholder="Enter a task">
                    <input class="add" type="submit" value="ADD">
                </form>
            </div>

        <div class="todo__container">
            <ul class="task__nav">
                <li class="task__nav-item all">All Tasks</li>
                <li class="task__nav-item finished">Finished Tasks</li>
            </ul>
        </div>
    </div>

1 Answers

Problem is in function updateUI(). When this function is called, all items are appended to containter element. It need one fix - clear containter element from all previously added elements before calling elements adding.

One suggestion that could make task easier: In element with class todo__container add new element which should be used as container for elements. It would make work easier.

Related