[Vanilla JS] create To do list
Web/JS

[Vanilla JS] create To do list

Setup
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value; // input의 현재 value 를 새로운 변수에 복사
  toDoInput.value = ""; // input 을 받고나면 비우기

  // toDoInput.value = "" 를 통해 input을 비우더라도 이미 저장된 값은 비워지는 것이 아님!
  // 왜냐하면 제출한 value를 newTodo 변수에 복사하는 것이기 때문에
  // 그 이후에 input에 무슨 짓을 하던 newTodo 에는 아무런 영향을 끼치지 못함
}

toDoForm.addEventListener("submit",handleToDoSubmit);

 


 

adding To Dos
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

function paintToDo(newTodo) { // todo를 그리는 역할
  const li = document.createElement("li");
  const span = document.createElement("span");
  li.appendChild(span); // li 는 span 을 자식으로 갖게 함
  span.innerText = newTodo;
  toDoList.appendChild(li);
}

function handleToDoSubmit(event) { // handelToDoSubmit 이 paimtToDo 를 쓴다
  event.preventDefault();
  const newTodo = toDoInput.value; // newToDO = intput 의 value 를 비우기 전에 나타나는 string
  toDoInput.value = "";
  paintToDo(newTodo) // newTodo 의 value 를 paintToDo 에 넣어서 호출
}

toDoForm.addEventListener("submit",handleToDoSubmit);

 


 

Deleting To dos
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

function deleteTodo(event) { // x btn 을 클릭하면 event 를 얻게되고, event 는 target 을 준다.
  // target 은 btn 이며, btn은 부모를 가지고 있고 그 부모는 li 이다.
  const li = event.target.parentElement;
  li.remove();
}

function paintToDo(newTodo) {
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newTodo;
  const button =document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteTodo)
  li.appendChild(span);
  li.appendChild(button);
  toDoList.appendChild(li);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";
  paintToDo(newTodo)
}

toDoForm.addEventListener("submit",handleToDoSubmit);

 window 이모지 단축키 : win + .

 mac 이모지 단축키 : control + cmd + space

 


 

Saving To Dos

 여기까지 진행했다면 To Do List 를 생성하고, 생성한 리스트를 제거하는 기능까지 갖추게 되었지만 하나 문제점이 있습니다. 바로 새로고침을 하면 생성한 리스트들이 모조리 초기화되어 사라지는 것이죠.

 때문에 제출한 To Do List value 를 저장하기 위해서 localStorage 를 사용했지만 문제점이 하나 더 발생합니다.

 

 왜냐면 localStorage 는 array 를 저장할 수가 없거든요. 오직 Text 만 받을 수 있습니다. 우리가 이 코드를 통해 보내고 있는 것은 배열 원소이기 때문에 localStorage 에 들어가더라도 새로고침을 하면 다시 초기화가 되버립니다. 이를 보완하기 위해 JSON.stringify 를 사용했습니다.

 

 JSON.stringify 는 Javascript object 나 array 나 어떤 것이든 string 으로 바꿔주며, 브라우저가 제공하는 기능입니다.

 

만약 name 으로 mildman 을 가진 player(object) 가 있다고 가정했을 때, 이것을 string 으로 바꾸고 싶다면 player 를 JSON.stirngify() 안에 넣기만 하면 됩니다.

 

const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

const toDos = []; // toDo 목록을 저장할 배열

function saveTodos() { // toDos array 를 localStorage 에 집어넣는 역할
  localStorage.setItem("todos", JSON.stringify(toDos));
}

function deleteTodo(event) {
  const li = event.target.parentElement;
  li.remove();
}

function paintToDo(newTodo) { // newTodo 가 웹에 그려질 때마다 그 텍스트를 array 에 push
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newTodo;
  const button =document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteTodo);
  li.appendChild(span);
  li.appendChild(button);
  toDoList.appendChild(li);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";
  toDos.push(newTodo); // Text(newToDo)를 toDos array 에 push
  paintToDo(newTodo);
  saveTodos(); // toDo 들을 저장
}

toDoForm.addEventListener("submit",handleToDoSubmit);

 


 

Loading To Dos #1 - JSON.parse로 실사용 가능한 배열 생성  /  배열의 forEach 함수

 입력한 toDos 는 현재 localStorage 에 있습니다. 하지만 아직도 새로고침할 때 마다 toDos 가 localStorage 에는 남아있지만, 화면에는 나타나지 않습니다. 이 파트에서 이것을 디버깅할 것입니다.

 

 현재 우리가 localStorage 에 갖고 있는 것은 단순한 string 이지만, 이 string 을 JSON.parse 를 통해서 Javascript 가 이해할 수 있는(실제로 무언가를 할 수 있게 만드는) 배열로 변환할 수 있습니다. 

 

const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

const TODOS_KEY = "todos";

const toDos = []; // toDo 목록을 저장할 배열

function saveTodos() { // toDos array 를 localStorage 에 집어넣는 역할
  localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}

function deleteTodo(event) {
  const li = event.target.parentElement;
  li.remove();
}

function paintToDo(newTodo) { // newTodo 가 웹에 그려질 때마다 그 텍스트를 array 에 push
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newTodo;
  const button = document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteTodo);
  li.appendChild(span);
  li.appendChild(button);
  toDoList.appendChild(li);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";
  toDos.push(newTodo); // Text(newToDo)를 toDos array 에 push
  paintToDo(newTodo);
  saveTodos(); // toDo 들을 저장
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY);

if (savedToDos != null) {
  const parsedToDos = JSON.parse(savedToDos);
  parsedToDos.forEach(paintToDo);
  // forEach = array 에 있는 각각의 item 에 대해서 fucntion 을 실행하게 해줌
}

 

Loading To Dos #2 - localStorage 배열 덮어쓰기 현상 방지
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

const TODOS_KEY = "todos";

let toDos = []; // toDo 목록을 저장할 배열
// 새로고침 시에 localStorage 를 덮어쓰는 현상을 방지하기 위해 let 으로 업데이트가 가능하도록 설정
// 덮어쓰기가 일어나는 이유는 배열이 비어있는 상태에서 value 를 저장받기 때문에 새로고침시 초기화가 됨

function saveTodos() {
  localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}

function deleteTodo(event) {
  const li = event.target.parentElement;
  li.remove();
}

function paintToDo(newTodo) {
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newTodo;
  const button = document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteTodo);
  li.appendChild(span);
  li.appendChild(button);
  toDoList.appendChild(li);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";
  toDos.push(newTodo);
  paintToDo(newTodo);
  saveTodos();
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY);

if (savedToDos != null) {
  const parsedToDos = JSON.parse(savedToDos);
  toDos = parsedToDos; // localStorage 에 toDo 들이 있으면,
  // toDos 에 parsedToDos 를 넣어서 이전에 있던 toDo 들을 복원
  parsedToDos.forEach(paintToDo);
}

 


 

Deleteing To Dos
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

const TODOS_KEY = "todos";

let toDos = [];

function saveTodos() {
  localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}

function deleteTodo(event) {
  const li = event.target.parentElement;
  li.remove();
}

function paintToDo(newTodo) {
  const li = document.createElement("li"); 
  li.id = newTodo.id;
  const span = document.createElement("span");
  span.innerText = newTodo.text; // .text = paintToDo 는 text 만 받았지만 이제는 object 로 받음
  // handleToDoSubmit에서 구성한 object 는 text 와 id 를 가지고 있기 때문에 .text 로 text만 받음
  const button = document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteTodo);
  li.appendChild(span);
  li.appendChild(button);
  toDoList.appendChild(li);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";
  const newTodoObj = {
    // newTodo가 받은 value의 이름이 같을 경우 구분하기 위해서 text 와 더불어
    //id 값을 받는 object 로 구성
    text: newTodo,
    id: Date.now(), // 랜덤한 숫자를 Date.now() 로 받아서 id에 할당
  };
  toDos.push(newTodoObj); // newTodo 를 newTodoObj 로 수정
  paintToDo(newTodoObj); // newTodo 를 newTodoObj 로 수정
  saveTodos();
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY);

if (savedToDos != null) {
  const parsedToDos = JSON.parse(savedToDos);
  toDos = parsedToDos;
  parsedToDos.forEach(paintToDo);
}

 

filter 함수 => 선택옵션 역할

새 array 를 준다.

 

const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");

const TODOS_KEY = "todos";

let toDos = [];

function saveTodos() {
  localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}

function deleteTodo(event) {
  const li = event.target.parentElement;
  li.remove();
  toDos = toDos.filter(toDo => toDo.id !== parseInt(li.id));
  // 클릭했던 li의 id 를 갖고 있는 toDo 를 지움 = toDo의 id가 li의 id와 다른걸 남김
  // = 내가 클릭한 li.id 와 다른 toDo 들은 남겨두겠다

  // toDo.id 는 number 이고 li.id 는 string이라 !== 의 호환이 안되기 때문에
  // parseInt(li.id) 로 문자열을 숫자로 바꿔줌
  saveTodos(); // toDos DB 에서 todo 를 지운 뒤에, saveToDos를 한 번더 불러줘야함
}

function paintToDo(newTodo) {
  const li = document.createElement("li"); 
  li.id = newTodo.id;
  const span = document.createElement("span");
  span.innerText = newTodo.text;
  const button = document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteTodo);
  li.appendChild(span);
  li.appendChild(button);
  toDoList.appendChild(li);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";
  const newTodoObj = {

    text: newTodo,
    id: Date.now(),
  };
  toDos.push(newTodoObj);
  paintToDo(newTodoObj);
  saveTodos();
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY);

if (savedToDos != null) {
  const parsedToDos = JSON.parse(savedToDos);
  toDos = parsedToDos;
  parsedToDos.forEach(paintToDo);
}