[JS] TODO LIST - CodingNepal

윤아영·2023년 1월 18일

출처 : https://www.youtube.com/watch?v=2QIMUBilooc

1. Saving Tasks to Local Storage

// input 요소를 가져오기 위해 querySelector를 사용
const taskInput = document.querySelector(".task-input input"),
//getting local storage todo-list
// storage 저장 
todos = JSON.parse(localStorage.getItem("todo-list"));

//1.
taskInput.addEventListener("keyup", e => {
    let userTask = taskInput.value.trim();
    if(e.key == "Enter" && userTask) {
        if(!todos) { //if todos isn't exist, pass an empty array to todos
          //parse this localstorage data to js object
          let todos = JSON.parse(localStorage.getItem("todo-list")
            todos = [];
        }
        taskInput.value = "";
      let taskInfo = {name: userTask, status: "pending"};
      todos.push(taskInfo); // adding new task to todos  
      //stringify 하기전에는 [object object] 으로 나온다
      localStorage.setItem("todo-list", JSON.stringify(todos));
      showTodo();
    }
});


//2. edit 이후 
taskInput.addEventListener("keyup", e => {
    let userTask = taskInput.value.trim();
    if(e.key == "Enter" && userTask) {
        if(!isEditTask) { // if isEditedTask isn;t ture
            //if todos isn't exist, pass an empty array to todos
            todos = !todos ? [] : todos;
            let taskInfo = {name: userTask, status: "pending"};
            todos.push(taskInfo); // adding new task to todos
        } else {
            isEditTask = false;
            todos[editId].name = userTask;
        }
        taskInput.value = "";
        localStorage.setItem("todo-list", JSON.stringify(todos));
        showTodo(document.querySelector("span.active").id);
    }
});

//window.localStorage.setItem(key, value)

todos는 할 일들을 담을 배열이며 name은 각각의 할 일들이 유니크하게 구별할 수 있는 키값을 설정하기 위해 선언하며 status 값을 설정하여 진행도를 구분시킬 수 있게 한다
e.key 값이 엔터 혹은 userTask일때 todo에 빈배열을 전달 해준다

localStorage를 사용하면, 브라우저에 key-value 값을 Storage에 저장할 수 있다.
locaslstroage에 저장하기 위해서 localStorage.setItem("todo-list", JSON.stringify(todos));를 사용해준다

2. Showing All task from Local storage

const taskBox = document.querySelector(".task-box");

function showTodo(filter) {
    let liTag = "";
    if(todos) {
        todos.forEach((todo, id) => {
         //console.log(id, todo) => {name: value, status : value} 값으로 나옴 
             //if todo status is completed, set the isCompleted value to checked
            let completed = todo.status == "completed" ? "checked" : "";
          //
            if(filter == todo.status || filter == "all") {
                liTag += `<li class="task">
                            <label for="${id}">
		/*"updateStatus(this)" checked status update*/
                                <input type="checkbox" id="${id}" ${completed}>
                                <p class="${completed}">${todo.name}</p>
                            </label>
                            <div class="settings">
                                <i class="uil uil-ellipsis-h"></i>
                                <ul class="task-menu">
                                    <li onclick='editTask(${id}, "${todo.name}")'><i class="uil uil-pen"></i>Edit</li>
                                    <li onclick='deleteTask(${id}, "${filter}")'><i class="uil uil-trash"></i>Delete</li>
                                </ul>
                            </div>
                        </li>`;
            }
        });
    }
  	//taskBox가 빈값일때 보이는 값 
    taskBox.innerHTML = liTag || `<span>You don't have any task here</span>`;
    let checkTask = taskBox.querySelectorAll(".task");
    !checkTask.length ? clearAll.classList.remove("active") : clearAll.classList.add("active");
}
showTodo("all");

입력창시 task-box를 통해 보여주는 함수 값
++연산자를 통해 1씩 증가시킴으로써 id값이 중복되지 않도록 해준다
liTag +=

3. Updating status of a selected Task

function updateStatus(selectedTask) {
    //getting paragraph that contains task name
    let taskName = selectedTask.parentElement.lastElementChild;
    if(selectedTask.checked) {
        taskName.classList.add("checked");
       //updating the status of selected task to completed
      //localStorage status 값을 변경하는 방법 
      //saving the updated 
        todos[selectedTask.id].status = "completed";
    } else {
        taskName.classList.remove("checked");
         //updating the status of selected task to pending
        todos[selectedTask.id].status = "pending";
    }
    localStorage.setItem("todo-list", JSON.stringify(todos))
}

todo의 id는 "todo-itme"요소에 setAttribute로 data-id 속성 값으로 지정해서 수정 및 삭제 시 해당 todo를 구분하기 위해 사용한다. 해당 todo가 완료된 일인지 아닌지를 판단하여, "todo-list"요소에 "checked"라는 클래스 네임을 더해 CSS를 반영한다

edit css 추가

function showMenu(selectedTask) {
    //getting task menu div
    let menuDiv = selectedTask.parentElement.lastElementChild
    menuDiv.classList.add("show");
    document.addEventListener("click", e => {
      //removing show class from the task menu on the document clcik
        if(e.target.tagName != "I" || e.target != selectedTask) {
            menuDiv.classList.remove("show");
        }
    });
}

Deleting Selected Task from the List

function deleteTask(deleteId, filter) {
  	//console.log(deleteID) ==> id값이 나옴 
    isEditTask = false;
  	//removing selected task from array/todos
    todos.splice(deleteId, 1);
   //saving local hosting
    localStorage.setItem("todo-list", JSON.stringify(todos));
  	//local storage 에서 삭제되면 바로 연동되게 함수 호출
    showTodo(filter);
}

edit Selected Task from the List


let editId,
isEditTask = false,
    
function editTask(taskId, textName) {
  //console.log(taskId, textName) => "0" "My third todo"
    editId = taskId;
    isEditTask = true;
  	//input 압력창의 taextName이 뜨게 한다 
    taskInput.value = textName;
    taskInput.focus();
    taskInput.classList.add("active");
}

Deleting all Task from the List

//removing all item from array/todos
clearAll.addEventListener("click", () => {
    isEditTask = false;
    todos.splice(0, todos.length);
    localStorage.setItem("todo-list", JSON.stringify(todos));
    showTodo("all")
});

filtering Task of the List

const filters = document.querySelectorAll(".filters span"),
filters.forEach(btn => {
    btn.addEventListener("click", () => {
        document.querySelector("span.active").classList.remove("active");
        btn.classList.add("active");
        showTodo(btn.id);
    });
});


function updateStatus(selectedTask) {
    //getting paragraph that contains task name
    let taskName = selectedTask.parentElement.lastElementChild;
    if(selectedTask.checked) {
        taskName.classList.add("checked");
        //updating the status of selected task to completed
        todos[selectedTask.id].status = "completed";
    } else {
        taskName.classList.remove("checked");
         //updating the status of selected task to pending
        todos[selectedTask.id].status = "pending";
    }
    localStorage.setItem("todo-list", JSON.stringify(todos))
}

0개의 댓글