-
Notifications
You must be signed in to change notification settings - Fork 12
[이어진] 중급 TodoList 구현 + 로컬스토리지 추가 완료 #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
oding01
wants to merge
5
commits into
asac-assignments:main
Choose a base branch
from
oding01:oding01
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| function enterKey(event) { | ||
| if(event.key === 'Enter') { | ||
| createTodo(); | ||
| } | ||
| } | ||
|
|
||
| function createTodo() { | ||
| const list = document.getElementById('todo-list'); | ||
| const input = document.querySelector('.todo-input'); | ||
| const inputText = input.value.trim(); | ||
|
|
||
| if (inputText === '') { | ||
| alert("내용을 입력하세요."); | ||
| return; | ||
| } | ||
|
|
||
| const isConfirm = confirm(`"${inputText}"를 저장하시겠습니까?`); | ||
| if (!isConfirm) { | ||
| return; | ||
| } | ||
|
|
||
| // 피드백) Element Create하는 부분들 모듈화(함수를 모듈화해서 객체로 전달하는 것이 좋다. 버튼을 생성할때, 생성 함수는 1개에 인자를 다르게 해서 생성하는 느낌) | ||
|
|
||
| // Create List Element | ||
| const newTodo = document.createElement('li'); | ||
|
|
||
| // Checkbox | ||
| const checkbox = createCheckbox('input', 'checkbox', 'todo-checkbox') | ||
| newTodo.appendChild(checkbox); | ||
|
|
||
| // TextContent | ||
| const todoText = document.createElement('span'); | ||
| todoText.classList.add('todo-text'); | ||
| todoText.textContent = inputText; | ||
| newTodo.appendChild(todoText); | ||
|
|
||
| // Button | ||
| const editButton = createButton('button', 'Edit', 'edit-btn'); | ||
| newTodo.appendChild(editButton); | ||
| const saveButton = createButton('button', 'Save', 'save-btn'); | ||
| newTodo.appendChild(saveButton); | ||
| const deleteButton = createButton('button', 'X', 'delete-btn'); | ||
| newTodo.appendChild(deleteButton); | ||
|
|
||
| // // 피드백) eventListener는 이벤트를 통해서 조작해야하기 때문에 editTodo ParentNode정돈 허용해야한다. | ||
| // // -> eventListener는 이벤트가 발생한 요소에 대한 파라미터를 제공함. | ||
| list.appendChild(newTodo); | ||
|
|
||
| input.value = ''; | ||
| } | ||
|
|
||
| function createCheckbox(tag, type, className) { | ||
| const checkbox = document.createElement(tag); | ||
| checkbox.type = type; | ||
| checkbox.classList.add(className); | ||
|
|
||
| return checkbox; | ||
| } | ||
|
|
||
| function createButton(tag, buttonText, className) { | ||
| const button = document.createElement(tag); | ||
| button.textContent = buttonText; | ||
| button.classList.add(className); | ||
| button.addEventListener('click', (e) => { handleButtonEvent(e) } ); | ||
|
|
||
| if (buttonText === 'Save') button.style.display = 'none'; | ||
|
|
||
| return button; | ||
| } | ||
|
|
||
| function handleButtonEvent(e) { | ||
| const buttonName = e.target.className; | ||
| switch (buttonName) { | ||
| case 'edit-btn' : | ||
| editTodo(e); | ||
| break; | ||
| case 'save-btn' : | ||
| saveTodo(e); | ||
| break; | ||
| case 'delete-btn' : | ||
| deleteTodo(e); | ||
| break; | ||
| default : | ||
| console.warn('Unknown Button Action'); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| function listFilter(event) { | ||
| const filter = event.target.value; | ||
| const todoList = document.querySelectorAll('#todo-list li'); | ||
|
|
||
| todoList.forEach(todo => { | ||
| const checkbox = todo.querySelector('.todo-checkbox'); | ||
| const isChecked = checkbox.checked; | ||
|
|
||
| if (filter === "all") { | ||
| console.log(filter); | ||
| todo.style.display = 'list-item'; | ||
| } else if (filter === 'todo' && !isChecked) { | ||
| todo.style.display = 'list-item'; | ||
| } else if (filter === 'done' && isChecked) { | ||
| todo.style.display = 'list-item'; | ||
| } else { | ||
| todo.style.display = 'none'; | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| function editTodo(event) { | ||
| // 피드백) 하나의 컴포넌트가 두 개 이상의 작업을 수행하게 되어있음. | ||
| // 역할을 나눠놓는 것이 좋다. Edit, Save | ||
| const item = event.target.parentNode; | ||
| const todo = item.querySelector('.todo-text'); | ||
| const editBtn = item.querySelector('.edit-btn'); | ||
| const saveBtn = item.querySelector('.save-btn'); | ||
| saveBtn.style.display = 'inline'; | ||
| editBtn.style.display = 'none'; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. editTodo 와 saveTodo 의 코드 흐름의 형상(?)을 유사하게 만들 수 있을거같습니다. 좀 변태같긴하지만 저 개인적으론 코드의 형상을 맞추는걸 선호하는 편입니다. |
||
|
|
||
| const input = document.createElement('input'); | ||
| // Map으로 중앙화도 가능 | ||
| input.setAttribute('type', 'text'); | ||
| input.setAttribute('class', 'todo-text'); | ||
| input.setAttribute('value', todo.textContent); | ||
| item.replaceChild(input, todo); | ||
| } | ||
|
|
||
| function saveTodo(event) { | ||
| const item = event.target.parentNode; | ||
| const editBtn = item.querySelector('.edit-btn'); | ||
| const saveBtn = item.querySelector('.save-btn'); | ||
|
|
||
| const input = item.querySelector('.todo-text'); | ||
| if (input.value.trim() === '') { | ||
| alert('내용을 입력하세요.'); | ||
| return; | ||
| } | ||
| const saveTodo = document.createElement('span'); | ||
| saveTodo.classList.add('todo-text'); | ||
| saveTodo.textContent = input.value.trim(); | ||
|
|
||
| item.replaceChild(saveTodo, input); | ||
| editBtn.style.display = 'inline'; | ||
| saveBtn.style.display = 'none'; | ||
| } | ||
|
|
||
| // 주어진 걸 최대한 쓰자 이벤트리스너의 파라미터. | ||
| function deleteTodo(event) { | ||
| const todo = event.target.parentNode; | ||
| todo.remove(); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| document.addEventListener('DOMContentLoaded', function () { | ||
| const input = document.querySelector('.todo-input'); | ||
| const saveButton = document.querySelector('.input-container input[type="button"]'); | ||
| const list = document.getElementById('todo-list'); | ||
|
|
||
| saveButton.addEventListener('click', function () { | ||
| const inputText = input.value.trim(); | ||
| if (inputText === '') { | ||
| alert("내용을 입력하세요."); | ||
| return; | ||
| } | ||
|
|
||
| const isConfirm = confirm(`"${inputText}"를 저장하시겠습니까?`); | ||
| if (!isConfirm) { | ||
| return; | ||
| } | ||
|
|
||
| const newTodo = document.createElement('li'); | ||
| newTodo.textContent = inputText; | ||
|
|
||
| list.appendChild(newTodo); | ||
|
|
||
| input.value = ''; | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 또한 파라미터로 받으면됩니다 :) 아래
handleButtonEvent에서 분기타는게 이뻐보일수도 있긴한데차라리 이런 형태로 갈거라면
createButton의 파라미터를 객체로 변경한 뒤각 버튼타입의 객체를 Enum 처럼 const 로 정의해놓아
createButton에 특정 타입의 객체 파라미터를 주면 그 객체 내 요소들 가져다가 타입 버튼을 만드는게 좋을듯해요.