diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..501dfaf --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/../../../../../../../../:\Users\yjwdb\OneDrive\바탕 화면\우아한 테크코스\js-todo-list-step1\.idea/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/js-todo-list-step1.iml b/.idea/js-todo-list-step1.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/js-todo-list-step1.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3a37236 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e92d622 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 36372ce..f5fcf49 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,12 @@ ## 🎯 요구사항 -- [ ] todo list에 todoItem을 키보드로 입력하여 추가하기 -- [ ] todo list의 체크박스를 클릭하여 complete 상태로 변경. (li tag 에 completed class 추가, input 태그에 checked 속성 추가) -- [ ] todo list의 x버튼을 이용해서 해당 엘리먼트를 삭제 -- [ ] todo list를 더블클릭했을 때 input 모드로 변경. (li tag 에 editing class 추가) 단 이때 수정을 완료하지 않은 상태에서 esc키를 누르면 수정되지 않은 채로 다시 view 모드로 복귀 -- [ ] todo list의 item갯수를 count한 갯수를 리스트의 하단에 보여주기 -- [ ] todo list의 상태값을 확인하여, 해야할 일과, 완료한 일을 클릭하면 해당 상태의 아이템만 보여주기 +- [x] todo list에 todoItem을 키보드로 입력하여 추가하기 +- [x] todo list의 체크박스를 클릭하여 complete 상태로 변경. (li tag 에 completed class 추가, input 태그에 checked 속성 추가) +- [x] todo list의 x버튼을 이용해서 해당 엘리먼트를 삭제 +- [x] todo list를 더블클릭했을 때 input 모드로 변경. (li tag 에 editing class 추가) 단 이때 수정을 완료하지 않은 상태에서 esc키를 누르면 수정되지 않은 채로 다시 view 모드로 복귀 +- [x] todo list의 item갯수를 count한 갯수를 리스트의 하단에 보여주기 +- [x] todo list의 상태값을 확인하여, 해야할 일과, 완료한 일을 클릭하면 해당 상태의 아이템만 보여주기 - [ ] localStorage에 데이터를 저장하여, TodoItem의 CRUD를 반영하기. 따라서 새로고침하여도 저장된 데이터를 확인할 수 있어야 함
diff --git a/index.html b/index.html index c1d9095..3e7175f 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + @@ -19,10 +19,10 @@

TODOS

- 0 + 0
+ - + \ No newline at end of file diff --git a/src/css/style.css b/src/css/style.css index 7dcbc6d..1a3e4bf 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -331,4 +331,4 @@ main { .info a:hover { text-decoration: underline; -} +} \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..ca7a62a --- /dev/null +++ b/src/index.js @@ -0,0 +1,154 @@ +const $todoInput = document.querySelector("#new-todo-title"); +const $toDoList = document.querySelector(".todo-list"); +const $filter = document.querySelector(".filters"); + +$todoInput.addEventListener("keyup", onAddTodoItem); +$toDoList.addEventListener("click", onToggleTodoItem); +$toDoList.addEventListener("click", onDestoryItem); +$toDoList.addEventListener("dblclick", edit); +$filter.addEventListener("click", filterTodo); + +state = 0; + +function onAddTodoItem(event) { + const todoTitle = event.target.value; + const todoList = document.getElementById("todo-list"); + if (event.key === "Enter" && todoTitle !== "") { + todoList.insertAdjacentHTML("beforeend", renderTodoItemTemplate(todoTitle)); + event.target.value = ""; + updateCount(); + } +} + +function onToggleTodoItem(event) { + if(event.target.className == "toggle"){ + event.target.closest("li").classList.toggle("completed"); + } +} + +function renderTodoItemTemplate(title) { + return `
  • +
    + + + +
    + +
  • `; +} + +function onDestoryItem(event) { + if(event.target.className == "destroy"){ + const destroy = event.target.parentNode.parentNode + destroy.remove() + updateCount(); + } +} + +function edit(event) { + if(event.target.className == "label"){ + const $TodoItem = event.target.closest('li') + const editInput = $TodoItem.querySelector('.edit') + + if(!$TodoItem.classList.contains('editing')) { + $TodoItem.classList.toggle('editing'); + } + + editInput.addEventListener('keyup', (e) => { + if(e.key == 'Enter') { + $TodoItem.classList.remove('editing') + event.target.textContent = editInput.value + } + if(e.key == 'Esc' || e.key == 'Escape') { + editInput.value = event.target.textContent + $TodoItem.classList.remove('editing') + return; + } + }) + } +} + +function updateCount() { + const todoItems = document.querySelectorAll(".todo-item"); + if(state == 0) { + document.querySelector('.count').innerHTML = document.querySelectorAll(".todo-item").length; + return; + } + if(state == 1) { + count = 0; + todoItems.forEach(element => { + if(element.classList.contains("completed")){ + count = count + 1; + } + }); + document.querySelector('.count').innerHTML = count; + return; + } + if(state == 2) { + count = 0; + todoItems.forEach(element => { + if(!element.classList.contains("completed")){ + count = count + 1; + } + }); + document.querySelector('.count').innerHTML = count; + return; + } +} + +function filterTodo(event) { + const buttonName = event.target.className; + const todoItems = document.querySelectorAll(".todo-item"); + const count = 0; + if(buttonName == "active") { + onlyToDo(todoItems); + } + + if(buttonName == "completed") { + completed(todoItems); + } + + if(buttonName == "all selected") { + allSelect(todoItems); + } +} + +function completed(todoItems) { + count = 0; + todoItems.forEach(element => { + if(element.classList.contains("completed")){ + element.style.display = "block"; + count = count + 1; + } + else { + element.style.display = "none"; + } + }); + state = 1; + updateCount(); +} + +function onlyToDo(todoItems) { + count = 0; + todoItems.forEach(element => { + if(element.classList.contains("completed")){ + element.style.display = "none"; + } + else { + element.style.display = "block"; + count = count + 1; + } + }); + state = 2; + updateCount(); +} + +function allSelect(todoItems) { + count = 0; + todoItems.forEach(element => { + element.style.display = "block"; + count = count + 1; + }); + state = 0; + updateCount(); +} \ No newline at end of file