input 빈칸에 할일을 적으면 Pending에 리스트로 저장되었다가 ⭕를 누르면 Finished로 넘어가고
❌를 누르면 삭제됨 그리고 Finished 리스트에서 🔁를 누르면 다시 Pending으로 넘어가는 시스템
1) HTML - 화면구성
<body>
<form class="input-form">
<input type="text" placeholder="Add Task"/>
</form>
<div class="pending">
<h1>Pending</h1>
<ul class="pending-ul"></ul>
</div>
<div class="finished">
<h1>Finished</h1>
<ul class="finished-ul"></ul>
</div>
<script src="index.js"></script>
</body>
2) CSS는 일단 생략
3) JavaScript - HTML과 연결
const form = document.querySelector(".input-form");
const formInput = form.querySelector("input");
const pendingList = document.querySelector(".pending-ul");
const finishedList = document.querySelector(".finished-ul");
4) JavaScript - 로직
① loadTask( )
- 이 함수는 pending과 finished 공통으로 쓰이는 함수
- pending과 finished가 같은 맥락이므로 pending으로만 설명함
- 로컬스토리지의 value값을 변수 pendingValue에 저장
- pendingValue가 null이 아니라면의 조건문으로 parseTask 변수에 객체로 변환하여 저장
- parseTask 변수에는 pendingValue의 정보를 각각 배열객체로 저장되어있음
- parseTask 의 배열 요소 마다 paintPending 함수를 실행함
//로컬스토리지의 key값
const PENDING = "PENDING",
FINISHED = "FINISHED";
//맨처음 실행되는 함수
function loadTask(){
//로컬스토리지 value 값을 변수 pendingValue와 finishedValue에 각각 저장
const pendingValue = localStorage.getItem(PENDING);
const finishedValue = localStorage.getItem(FINISHED);
if(pendingValue !== null){
// JSON.parse : 인수로 전달받은 문자열을 자바스크립트 객체로 변환하여 반환하는 메서드
// 여기서는 pendingValue가 string이므로 객체로 변환하여 parsedTask에 저장
const parsedTask = JSON.parse(pendingValue);
//헷갈리면 콘솔찍어보기
// 찍어보면 parsedTask는 배열 객체라는 것을 알 수 있다.
console.log("parsedTask = "+parsedTask);
console.log(parsedTask);
// forEach : 주어진 함수를 배열 요소마다 실행
// 여기서 toDo는 parsedTask의 배열 요소들
parsedTask.forEach(function (toDo) {
// data 형태로 저장되어 있는 parsedTask 안에 있는 text를 불러온것
paintPending(toDo.text);
});
}
if(finishedValue !== null){
const parsedTask = JSON.parse(finishedValue);
parsedTask.forEach(function (toDo) {
paintFininshed(toDo.text);
});
}
}
function init(){
loadTask();
//input에서 엔터를 눌렀을때 실행되는 함수
form.addEventListener("submit", handleSubmitPending);
}
init();
② handleSubmitPending( )
- form 태그 안에 있는 input에 이름을 쓰고 엔터를 눌렀을때 실행되는 함수
- form.addEventListener("submit", handleSubmitPending); 로 인해 실행되는 함수
- 이번 로직에서는 input에 쓰면 무조건 pending에 먼저 저장되므로 이 함수는 pending에만 적용
//input에 쓴 text를 savePending과 paintPending 함수에 인자로 보내는 함수
function handleSubmitPending(event){
//기본 input의 디폴트값으로 엔터를 누르면 자동으로 어딘가 보내지는 기능을
//중지시키는 메서드
event.preventDefault();
//input에 쓴 text를 currentValue에 저장하고
const currentValue = formInput.value;
//함수 인자로 보낸다.
savePending(currentValue);
paintPending(currentValue);
//그리고 input의 빈칸은 다시 비워지게 만듬
formInput.value="";
}
③ paintPending( )
- handleSubmitPending( ) 함수에서 currentValue를 인자로 받아와서 loadTask( )함수로 인해 배열 요소마다 함수 실행
- 로컬스토리지에 저장된 value 배열 요소를 리스트로 만들어 출력하는 함수
// 모든 함수 가장 위에 위치하도록 해야함
// 할일목록은 배열이 되어야 여러개를 저장할 수 있으므로
//pending은 배열로 생성
let pending = [];
//로컬스토리지 value값을 화면에 출력하는 함수
function paintPending(text){
const li = document.createElement("li"); // li 태그를 만들어서 변수에 할당
const passBtn = document.createElement("button"); // button 태그를 만들어서 변수에 할당
const delBtn = document.createElement("button"); // button 태그를 만들어서 변수에 할당
const span = document.createElement("span"); // span 태그를 만들어서 변수에 할당
//pending.length는 pending 객체 안 배열 요소의 갯수를 의미함
//예를 들어 input에 숨쉬기와 밥먹기를 입력해서 넣어놨다면
//pending.length는 2가 됨
const newId=pending.length+1;
//id가 0부터 시작하므로 1부터 시작하게 하기 위해서 1을 더해준것
//const newId=pending.length;
//console.log("아이디 = "+newId);
delBtn.innerHTML="❌"; // 버튼의 텍스트는 "❌"로 설정
delBtn.addEventListener("click",delPending); //❌ 버튼을 누르면 delPending 함수 실행
passBtn.innerHTML="⭕"; // 버튼의 텍스트는 "⭕"로 설정
passBtn.addEventListener("click",moveToFinished); //⭕ 버튼을 누르면 moveToFinished 함수 실행
span.innerText=text;// 사용자가 입력한 텍스트가 span태그의 텍스트가 되도록 설정
li.appendChild(span); // li 태그의 자식 태그로 span 태그 삽입
li.id=newId; // li태그의 id 속성을 object의 id와 같게 함.
li.appendChild(delBtn);// li 태그의 자식 태그로 버튼을 삽입
li.appendChild(passBtn);// li 태그의 자식 태그로 버튼을 삽입
pendingList.appendChild(li);// 위에서 설정한 li 태그들을 최종적으로 pendingList에 삽입
//할일을 pending 배열에 추가해야하므로 객체로 만들어서 추가함
const toDoObj={
text: text,
id: newId
};
pending.push(toDoObj); // toDos라는 Array 안에 toDoObj 객체를 넣음.
savePending();
}
④ savePending( )
- handleSubmitPending( ) 함수 안 지역변수 currentValue를 인자로 받아 로컬스토리지 value값으로 저장하는 함수
- JSON.stringify 에 대한 설명 : coding-with-jina.tistory.com/125?category=781130
//로컬스토리지 value 값에 저장하는 함수
function savePending(){
//JSON.stringify : 블로그에 설명된 링크 볼것
localStorage.setItem(PENDING, JSON.stringify(pending));
}
⑤ delPending( )
- 사용자가 선택한 요소의 로컬스토리지 pending의 value값을 지우고 출력된 리스트에도 삭제되는 함수
//사용자가 선택한 요소의 로컬스토리지 pending의 value값을 지우고 출력된 리스트에도 삭제되는 함수
function delPending(event){
// event.target : 블로그 링크 설명
// 클릭된 버튼을 할당
const btn = event.target;
// console.dir(event.target) // 이 방법으로 event.target의 부모 노드를 확인가능
// event.target.parentNode
/* event.target.parentNode
-여러 개의 버튼 중 어느 버튼이 클릭됐는지 알려줌
- 클릭된 버튼 태드의 부모 태그를 불러옴 */
const li = btn.parentNode; // 할당된 버튼의 부모 태그(li)를 할당
pendingList.removeChild(li); // 해당 태그 삭제
/*filter 함수는 array의 모든 요소들에 함수를 실행하고,
값이 true인 것들만 가지고 새로운 array를 만들어 반환함 */
const cleanTask = pending.filter(function(toDo){
return toDo.id !== parseInt(li.id);
});
//값이 true인 것들만 가지고 새로운 array를 만들어 반환한 것들만 저장된 cleanTask 변수를
//다시 pending에 저장
pending=cleanTask;
savePending();
}
⑥ moveToFinished( )
- 버튼을 누르면 finished 리스트로 옮겨지는 기능
- const span1 = event.path[1].childNodes[0].innerHTML;
- [참고] event.path 에 대한 설명 : coding-with-jina.tistory.com/132
//버튼을 누르면 finished 리스트로 옮겨지는 기능
function moveToFinished(event){
//event.path[1] 블로그 링크로 설명
const span1 = event.path[1].childNodes[0].innerHTML;
console.log(span1);
delPending(event);
paintFininshed(span1);
}
⑦ finished 영역
- ③~④번까지의 같은 의미의 코드를 finished에도 똑같이 적용해서 작성
//----finished---------------------------------------------------------
//3번
//로컬스토리지에 저장된 value 배열 요소를 리스트로 만들어 출력하는 함수
function paintFininshed(text){
const li = document.createElement("li");
const delBtn = document.createElement("button");
const passBtn = document.createElement("button");
const span = document.createElement("span");
const newId=finished.length+1;
delBtn.innerHTML="❌";
delBtn.addEventListener("click",delFinished);
passBtn.innerHTML="🔁";
passBtn.addEventListener("click",moveToPending);
span.innerText=text;
li.appendChild(span);
li.id=newId;
li.appendChild(delBtn);
li.appendChild(passBtn);
finishedList.appendChild(li);
const toDoObj={
text: text,
id: newId
};
finished.push(toDoObj);
saveFinished();
}
//4번
//currentValue를 인자로 받아 로컬스토리지 value값으로 저장하는 함수
function saveFinished(){
localStorage.setItem(FINISHED, JSON.stringify(finished));
}
//5번
//사용자가 선택한 요소의 로컬스토리지 finished의 value값을 지우고 출력된 리스트에도 삭제되는 함수
function delFinished(event){
const btn = event.target;
const li = btn.parentNode;
finishedList.removeChild(li);
const cleanFinished = finished.filter(function(toFinished){
return toFinished.id !== parseInt(li.id);
});
finished=cleanFinished;
saveFinished();
}
//6번
//버튼을 누르면 pending 리스트로 옮겨지는 기능
function moveToPending(event){
const span2 = event.path[1].childNodes[0].innerHTML;
console.log(span2);
delFinished(event);
paintPending(span2);
}
5) 결과
직접 실행해보세요😀
jina-choi.github.io/coding-with-jina/mini_project/todolist_Upgrade_Ver/index.html
Day7
jina-choi.github.io
'Coding With Jina > JavaScript' 카테고리의 다른 글
[자바스크립트] Event.path / Event.composedPath (0) | 2021.01.29 |
---|---|
[자바스크립트] ToDoList 만들기 기본 Ver. - 로직 (0) | 2021.01.29 |
[자바스크립트] Event.target (0) | 2021.01.29 |
[자바스크립트] Array(배열) 객체의 메서드 forEach (0) | 2021.01.27 |
[자바스크립트] JSON.stringify( )과 JSON.parse( ) (0) | 2021.01.27 |