-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathdetail.html
More file actions
264 lines (224 loc) · 8.79 KB
/
detail.html
File metadata and controls
264 lines (224 loc) · 8.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Detail TODO List</title>
</head>
<body>
<section id="container">
<h1 class="title">TODO LIST</h1>
<div class="input-container">
<input type="text" class="todo-input" onkeyup="submitToDo(event)" />
</div>
<div class="filter-container">
<select id="todo-filter">
<option value="all">전체</option>
<option value="todo">할일</option>
<option value="done">완료</option>
</select>
</div>
<div class="list-container">
<ul id="todo-list" class="todo-list"></ul>
</div>
</section>
</body>
<script>
//localStorage에 저장되는 유저 필터 옵션
const FilterOptions = {
ALL: "all",
TODO: "todo",
DONE: "done",
};
const localStorageToDoKey = "todos";
//현재 로컬스토리지에 저장된 할 일 리스트를 반환하는 함수
const getCurrentToDos = () => {
const currentToDos = JSON.parse(
localStorage.getItem(localStorageToDoKey)
);
return currentToDos === null ? [] : currentToDos;
};
const localStorage = window.localStorage;
let initialToDos = getCurrentToDos() || [];
// 필터 값에 따라 할 일 목록을 필터링해 반환하는 함수
const filterToDos = (listItems, filterValue) => {
const filteredItems = listItems.filter((item) => {
const checked = item.checked;
switch (filterValue) {
case FilterOptions.ALL:
return true;
case FilterOptions.TODO:
return !checked;
case FilterOptions.DONE:
return checked;
}
});
return filteredItems;
};
//할 일 목록을 UI에 초기화하는 함수
const initializeTodoListUI = () => {
if (initialToDos.length !== 0) {
const todoList = document.querySelector(".todo-list");
const filterSelect = document.querySelector("#todo-filter");
const filterValue = localStorage.getItem("filter") || FilterOptions.ALL;
filterSelect.value = filterValue;
const filteredItems = filterToDos(initialToDos, filterValue);
filteredItems.forEach((element) => {
const listElement = createContentsInsideElement(element);
todoList.appendChild(listElement);
});
}
};
//localStorage에 업데이트한 항목을 저장하는 함수
const updateToDoInLocalStorage = (itemId, propertyName, newValue) => {
initialToDos = initialToDos.map((item) => {
if (item.id === itemId) {
return { ...item, [propertyName]: newValue };
}
return item;
});
localStorage.setItem(localStorageToDoKey, JSON.stringify(initialToDos))
};
/*체크박스의 체크 상태를 토글하는 함수*/
const toggleCheck = (event) => {
const selectedItem = event.target.parentNode;
const itemId = selectedItem.id;
const propertyNameToUpdate = "checked";
const isChecked = event.target.checked;
updateToDoInLocalStorage(itemId, propertyNameToUpdate, isChecked);
};
/*편집 폼을 보여주기 위한 함수
선택된 항목의 텍스트를 제거하고 편집 폼을 표시*/
const revealEditForm = (event) => {
const selectedItem = event.target.parentElement;
selectedItem.removeChild(selectedItem.childNodes[1]);
const buttonsToHide = selectedItem.childNodes;
buttonsToHide.forEach((element) => {
toggleHidden(element);
});
selectedItem.querySelector("input[type='text']").focus();
};
/*수정된 내용을 저장하기 위한 함수
입력된 내용을 텍스트 노드로 변환하여 항목에 삽입*/
const saveEditedContent = (event) => {
const elementToSave = event.target.parentNode;
const elementId = elementToSave.id;
const contentToSave =
elementToSave.querySelector("input[type='text']").value;
const contentText = document.createTextNode(contentToSave);
updateToDoInLocalStorage(elementId, "content", contentToSave);
const butttons = elementToSave.childNodes;
butttons.forEach((element) => {
toggleHidden(element);
});
elementToSave.insertBefore(
contentText,
elementToSave.querySelector(".edit")
);
};
/*HTML 요소의 숨김 상태를 토글하는 함수
요소의 hidden속성을 변경*/
const toggleHidden = (element) => {
if (element.getAttribute("hidden") !== null) {
element.removeAttribute("hidden");
} else {
element.setAttribute("hidden", true);
}
};
/*할일 항목을 삭제하는 함수
선택된 할일 항목을 UI상 리스트에서 제거하고 로컬스토리지에도 반영*/
const handleDelete = (event) => {
const listItem = event.target.parentNode;
const itemId = listItem.id;
initialToDos = initialToDos.filter((item) => item.id !== itemId);
listItem.remove();
localStorage.setItem(
localStorageToDoKey,
JSON.stringify(initialToDos)
)
};
/*새로운 할일 항목의 내용을 담은 li element를 생성하는 함수
입력으로 추가할 아이템을 받고고, 체크박스와 버튼 등을 포함하는 HTML요소를 만들어 반환 */
const createContentsInsideElement = (item) => {
const content = item.content;
const id = item.id;
const isChecked = item.checked;
const listElement = document.createElement("li");
const toDoCheckbox = document.createElement("input");
toDoCheckbox.type = "checkbox";
toDoCheckbox.className = "checkbox";
toDoCheckbox.addEventListener("click", toggleCheck);
if (item.checked) {
toDoCheckbox.setAttribute("checked", true);
}
const toDoContent = document.createTextNode(content);
const editButton = document.createElement("button");
editButton.innerHTML = "Edit";
editButton.className = "edit";
editButton.addEventListener("click", revealEditForm);
const editForm = document.createElement("input");
editForm.type = "text";
editForm.value = content;
editForm.setAttribute("hidden", true);
const saveButton = document.createElement("button");
saveButton.innerHTML = "Save";
saveButton.setAttribute("hidden", true);
saveButton.addEventListener("click", saveEditedContent);
const deleteButton = document.createElement("button");
deleteButton.innerHTML = "X";
deleteButton.addEventListener("click", handleDelete);
listElement.appendChild(toDoCheckbox);
listElement.appendChild(toDoContent);
listElement.appendChild(editButton);
listElement.appendChild(deleteButton);
listElement.appendChild(editForm);
listElement.appendChild(saveButton);
listElement.setAttribute("id", id);
return listElement;
};
/*선택된 필터 값 변경 시 호출되는 함수
필터에 따라 리스트 항목을 표시하거나 숨김*/
const onClickFilter = (event) => {
const filterValue = event.target.value;
localStorage.setItem("filter", filterValue);
const listItems = filterToDos(initialToDos, filterValue);
const todoList = document.querySelector(".todo-list");
todoList.innerHTML = "";
if (listItems.length != 0) {
listItems.forEach((item) => {
const listElement = createContentsInsideElement(item);
todoList.appendChild(listElement);
});
}
};
initializeTodoListUI();
document
.querySelector("#todo-filter")
.addEventListener("change", onClickFilter);
/*새로운 할일 항목을 추가하기 위한 함수
Enter키가 눌리면 새로운 할일을 생성하여 리스트에 추가*/
const submitToDo = (event) => {
if (event.keyCode == 13) {
const userInput = document.querySelector(".todo-input");
const userInputValue = userInput.value;
const newToDOId = crypto.randomUUID();
const newToDoData = {
id: newToDOId,
content: userInputValue,
checked: false,
};
const currentToDos = document.querySelector(".todo-list");
const newToDo = createContentsInsideElement(newToDoData);
currentToDos.appendChild(newToDo);
initialToDos.push(newToDoData);
localStorage.setItem(localStorageToDoKey, JSON.stringify(initialToDos));
userInput.value = "";
const filterValue = document.querySelector("#todo-filter").value;
//선택된 필터 값이 "done"인 경우, 새로 생성된 할일 항목을 숨김
if (filterValue == "done") {
newToDo.setAttribute("hidden", "true");
}
}
};
</script>
</html>