To-Do List

김민재·2021년 7월 2일
0

Gotcha JavaScript!

목록 보기
11/45

Set up

To-Do List는 greeting을 만든 것과 동일하다.
form 태그를 만들고 그 안에 할 일을 받아낼text 타입의 input을 만들어주고
그 밑에 ul 태그를 만든 뒤 나중에 JS로 li 태그를 추가해준다.

<body>
  <form id="toDoForm">
    <input type="text" placeholder="Write a To Do and Press Enter" Required>
  </form>
  <ul id="toDoList">
  </ul>
</body>

주의 할 점은 newToDoinput 변수는 toDoInput에 입력한 value를 새로운 변수에 담아서 저장한 것이고 toDoInput.value는 기존의 값을 공백으로 만드는 것이기 때문에 별개의 변수라고 생각해야한다.

<script>
const toDoForm = document.getElementById("toDoForm");
const toDoInput = toDoForm.querySelector("#toDoForm input");
const toDoList = document.getElementById("toDoList");

function handleToDoSubmit(event){
  event.preventDefault();
  const newToDoInput = toDoInput.value;
  toDoInput.value="";
}
toDoForm.addEventListener("submit", handleToDoSubmit);
</script>

Adding to Dos

<script>
const toDoForm = document.getElementById("toDoForm");
const toDoInput = toDoForm.querySelector("#toDoForm input");
const toDoList = document.getElementById("toDoList");
function paintToDo(newToDo){
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newToDo;
  li.appendChild(span);
  toDoList.appendChild(li);
}
function handleToDoSubmit(event){
  event.preventDefault();
  const newToDo = toDoInput.value;
  toDoInput.value="";
  paintToDo(newToDo)
}
toDoForm.addEventListener("submit", handleToDoSubmit);
</script>

Deleting to Dos

추가된 todo list를 삭제할려면 어떤 리스트의 버튼을 눌렀는지 알 수 있어야한다. 그러기 위해 필요한 속성이 event의 target이다.
그리고 target의 부모인 li태그를 찾기위해 parentElement를 사용하고 이를 변수에 저장해준다.
마지막으로 그 변수에 .remove()메소드를 사용하면 선택받은 태그가 삭제된다.

<script>
const toDoForm = document.getElementById("toDoForm");
const toDoInput = toDoForm.querySelector("#toDoForm input");
const toDoList = document.getElementById("toDoList");
function deleteTodoList(event){
  const removeList = event.target.parentElement;
  removeList.remove();
}
function paintToDo(newToDo){
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newToDo;
  const btn = document.createElement("button");
  btn.innerText = "✔"
  btn.addEventListener("click", deleteTodoList)
  li.appendChild(span);
  li.appendChild(btn); 
  toDoList.appendChild(li);
}
function handleToDoSubmit(event){
  event.preventDefault();
  const newToDo = toDoInput.value;
  toDoInput.value="";
  paintToDo(newToDo)
}
toDoForm.addEventListener("submit", handleToDoSubmit);
</script>

Saving to Dos

JSON.stringifY()를 이용해 JS object나 array나 어떤 것이든 string으로 바꿔줄 수 있다.

Loading To Dos

JSON.parse()를 활용하면 string을 인자로 넣으면 이를 배열로 반환해준다.
배열로 반환한다면 각각의 item에 대해서 다양한 활용이 가능하다.
핵심은 array에 각각 item에 대해서 function을 실행하는 것이다. array는 리스트이기 때문에 forEach 메소드를 사용할 수 있는데 이것은 function을 실행해주는 건데 array에 있는 각각의 item에 대해서 실행을 시켜준다.
.forEach()에 인자값으로 함수를 넣어주면 array의 item들이 각각 한개의 fuction만을 실행할 있게 해준다.

처리되고 있는 itemd 어떤 것인지 알아야한다. submit 이벤트리스터가 인자를 그냥 제공해주는 것처럼 JS는 처리되고 있는 item또한 제공해준다. 따라서 각각의 item이 실행할 함수에 인자, item을 전달해주면 처리되는 item들이 구별이된다.

<script>
function sayHello(item){
  console.log("this is turn off item", item);
}
parsedToDos.forEach(sayHello);
</script>

함수 작성 없이 한줄에 이렇게 작성할 수 도 있다. parsedToDos 배열에 있는 각각의 item에 대해서 console.log를 각각 한다는 의미이다. 이러한 표현법을 arrow function이라고한다.

<script>
parsedToDos.forEach((item) => console.log("this is turn off item", item));
</script>

Loading To Dos

우리는 이제 foreach를 활용하여 함수로 미리 만들어놓은 painToDo함수만 전달해주면된다. 그러면 배열에 있는 각각의 아이템, 즉 newToDo를 작성하여 local storage에 저장한 값이 null이 아닐 때 그대로 화면에 남게된다. 그러나 새로운 newToDo를 입력하고 새로고침을 하면 이전의 값은 사라지고 새로운 값만 남게되는 오류가 발생한다. 그 이유는 app이 실행될 때 항상 toDos 배열이 비어져있는 상태이기 때문이다. newToDo를 작성한 뒤 form을 submit 할 때마다 newToDo를 toDos 배열, 빈 배열에 그냥 push하게 된다. 그리고 그 toDo들을 저장할 때 새로운 toDo들만 포함하고 있는 array를 저장하고 있다. 따라서 toDos는 배열은 이전의 toDo를 가지고 있지 않게된다.

한마디로 우리가 갖고있는 toDos의 이전 복사본을 잊어버리고 있는 것이다. 따라서 app이 시작될 때 빈 toDos 배열로 시작하는 대신 let 변수로 바꿔주어 localStorage에서 발견되는 이전의 toDo들 값으로 넣어준다.

let toDos = [];

const savedToDos = localStorage.getItem(TODOLIST_KEY);
console.log(savedToDos)
if(savedToDos !== null) {
  const parsedToDos = JSON.parse(savedToDos); 
  toDos = parsedToDos;
  parsedToDos.forEach(paintToDo);
}

Deleteing To Dos

로컬 스토리지에 저장된 값들을 지워야한다. 그러기 위해선 text로 localstroage에 toDos를 저장하는 것이 아닌 object로 저장하여 각각의 item에 id를 지정해줘야한다.

첫째로 우리 toDos DB를 비워야한다.
랜덤으로 ID를 만들어야하는데 Date.now()는 밀리초를 주는 함수로 임의로 지정해준다. id를 활용하여 각각의 list item을 구별하려한다.


function handleToDoSubmit(event){
  event.preventDefault();
  const newToDo = toDoInput.value;
  toDoInput.value="";
  const newToDoObj={
    text:newToDo,
    id:Date.now()
  }
  toDos.push(newToDoObj);
  paintToDo(newToDo);
  saveToDo();
}

toDos 배열에 text와 id를 가진 객체 배열을 만들어 push를 사용해 array에 이 oject를 전달해준다,

function paintToDo(newToDo){
  const li = document.createElement("li");
    li.id = newToDo.id;
  const span = document.createElement("span");
  span.innerText = newToDo.text; //텍스트를 받아야한다.
  const btn = document.createElement("button");
  btn.innerText = "✔"
  btn.addEventListener("click", deleteTodoList)
  li.appendChild(span);
  li.appendChild(btn); 
  toDoList.appendChild(li);
}

function deleteTodoList(event){
  const removeList = event.target.parentElement;
  console.log(removeList.id)
  removeList.remove();
}

또한 화면에 text내용만 받기 위해서는 객체.text를 불러와야한다.
//우리는 각 리스트에 새롭게 지정한 id 값을 주고 삭제 됬을 때 그 삭제한 list의 id 값도 함께 콘솔에 표시되도록 하면 어떠한 목록이 삭제되었는지 확인할 수 있다.

Deleteing To Dos

array 에 어떻게 elemet를 삭제하는 지 알기 위해서
paintToDo에서 어떤일 일어나는지 먼저 꼭 이해야한다.
array에서 item을 지운다는 건 사실 item을 제외시키는 것이다. 즉 예전 array는 그대로 있고
새 array를 만들어 저장한다는 뜻이다. 이때 filter메소드를 사용한다.

function sexyFilter(){
// 반드시 true를 리턴할 것 새 array에서 이 object를 유지하고 싶다면
// 만약 false 리턴하면 새 array에 object가 포함되지 않을것이다.
}
[1,2,3,4].filter(sexyFilter)

filter은 새로운 array를 준다는 걸 기억하는게 중요하다. 예전 array가 아닌 새로운 array를 준다는 뜻이다.

profile
자기 신뢰의 힘을 믿고 실천하는 개발자가 되고자합니다.

0개의 댓글