From 92767a90169536d0c41e92c36fe2b35e93207f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9C=A0=EC=84=B1?= Date: Wed, 11 Dec 2024 15:04:49 +0900 Subject: [PATCH 1/3] Subject of TodoList --- detail-script.js | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ detail.html | 9 +++-- simple-script.js | 16 ++++++++ simple.html | 5 ++- 4 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 detail-script.js create mode 100644 simple-script.js diff --git a/detail-script.js b/detail-script.js new file mode 100644 index 0000000..f3cfd9b --- /dev/null +++ b/detail-script.js @@ -0,0 +1,99 @@ +function dropDownList() { + var selectElem = document.getElementById("todo-filter"); + var selectValue = selectElem.value; + var notFinish = document.querySelectorAll(".cbox"); + if (selectValue == "todo") { + notFinish.forEach(element => { + // check되어있으면 + if(element.checked) { + element.parentElement.setAttribute('hidden', ''); + } else { + element.parentElement.removeAttribute('hidden'); + } + }) + } else if (selectValue == "done") { + notFinish.forEach(element => { + // check 안되어있으면 + if(element.checked) { + element.parentElement.removeAttribute('hidden'); + } else { + element.parentElement.setAttribute('hidden', ''); + } + }) + } else { + notFinish.forEach(element => { + element.parentElement.removeAttribute('hidden'); + }) + } +} + +function addTodoList() { + if (window.event.keyCode == 13) { + var todo_input = document.getElementsByClassName("todo-input"); + var input_value = todo_input[0].value; + if (input_value != 0) { + var parentElem = document.getElementById("todo-list"); + var todoListElem = createTodoElement(input_value, parentElem); + parentElem.appendChild(todoListElem); + todo_input[0].value = null; + } + } +} + +function createTodoElement(input_value, parentElem) { + var newList = document.createElement('li'); + var checkBox = checkBoxElement(); + var editBtn = editElement(); + var delBtn = delElement(); + + newList.appendChild(checkBox); + + newList.innerHTML += input_value; + + newList.appendChild(editBtn); + + + delBtn.addEventListener("click", () => { + parentElem.removeChild(newList); + }) + newList.appendChild(delBtn); + return newList; +} + +function checkBoxElement() { + var checkBox = document.createElement('input'); + checkBox.setAttribute('type', 'checkbox'); + checkBox.setAttribute('class', 'cbox'); + return checkBox; +} + +function editElement() { + var editBtn = document.createElement('input'); + editBtn.setAttribute('type', 'button'); + editBtn.setAttribute('value', 'Edit'); + editBtn.addEventListener("click", () => { + var parentElem = editBtn.parentElement; + var inputText = document.createElement('input'); + inputText.setAttribute('type', 'text'); + var saveBtn = document.createElement('input'); + saveBtn.setAttribute('type', 'button'); + saveBtn.setAttribute('value', 'Save'); + var prevElem = parentElem.getElementsByTagName('input'); + var prevCheckBox = prevElem[0]; + var prevEdit = prevElem[1]; + var prevDel = prevElem[2]; + parentElem.replaceChildren(inputText, saveBtn); + saveBtn.addEventListener("click", () => { + parentElem.replaceChildren(prevCheckBox, inputText.value, prevEdit, prevDel); + }) + }) + return editBtn; +} + +function delElement() { + var delBtn = document.createElement('input'); + delBtn.setAttribute('type', 'button'); + delBtn.setAttribute('value', 'X'); + return delBtn; +} + diff --git a/detail.html b/detail.html index 160571b..5da5fcc 100644 --- a/detail.html +++ b/detail.html @@ -9,19 +9,20 @@

TODO LIST

- +
-
-
    +
      +
    - + diff --git a/simple-script.js b/simple-script.js new file mode 100644 index 0000000..1a42a6e --- /dev/null +++ b/simple-script.js @@ -0,0 +1,16 @@ +function confirmSave() { + var todo_input = document.getElementsByClassName("todo-input"); + var input_value = todo_input[0].value; + if (!input_value) { + alert("내용을 입력해주세요."); + } else if (confirm(input_value + "를 저장하시겠습니까?")) { + var newList = document.createElement('li'); + newList.innerHTML += input_value; + document.getElementById("todo-list").appendChild(newList); + todo_input[0].value = null; + } else { + alert("저장을 취소하셨습니다."); + todo_input[0].value = null; + } + +} \ No newline at end of file diff --git a/simple.html b/simple.html index 2887e44..cecb7d2 100644 --- a/simple.html +++ b/simple.html @@ -10,7 +10,7 @@

    TODO

    - +
    - + From 06c851d6a858771f14abbce69ee60d70937fdfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9C=A0=EC=84=B1?= Date: Fri, 13 Dec 2024 17:43:59 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EC=95=A0=EB=9F=B0=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- detail-script.js | 178 +++++++++++++++++++++++++++++++++++------------ detail.html | 2 +- 2 files changed, 135 insertions(+), 45 deletions(-) diff --git a/detail-script.js b/detail-script.js index f3cfd9b..26dd255 100644 --- a/detail-script.js +++ b/detail-script.js @@ -1,45 +1,96 @@ -function dropDownList() { - var selectElem = document.getElementById("todo-filter"); - var selectValue = selectElem.value; - var notFinish = document.querySelectorAll(".cbox"); - if (selectValue == "todo") { - notFinish.forEach(element => { - // check되어있으면 - if(element.checked) { - element.parentElement.setAttribute('hidden', ''); - } else { - element.parentElement.removeAttribute('hidden'); - } - }) - } else if (selectValue == "done") { - notFinish.forEach(element => { - // check 안되어있으면 - if(element.checked) { - element.parentElement.removeAttribute('hidden'); - } else { - element.parentElement.setAttribute('hidden', ''); - } - }) +// 함수 이름 좀 더 직관적으로. +// if-for-if 말고 for-if-if로, 이런 구조일때는 항상 생각하기 +// 비슷한 기능을 가진 함수를 재사용 가능하게 나눠보기. +// function HandleOnChange() { +// var selectElem = document.getElementById("todo-filter"); +// var selectValue = selectElem.value; +// var notFinish = document.querySelectorAll(".check-box"); +// if (selectValue == "todo") { +// notFinish.forEach(element => { +// // check되어있으면 +// if(element.checked) { +// element.parentElement.setAttribute('hidden', ''); +// } else { +// element.parentElement.removeAttribute('hidden'); +// } +// }) +// } else if (selectValue == "done") { +// notFinish.forEach(element => { +// // check 안되어있으면 +// if(element.checked) { +// element.parentElement.removeAttribute('hidden'); +// } else { +// element.parentElement.setAttribute('hidden', ''); +// } +// }) +// } else { +// notFinish.forEach(element => { +// element.parentElement.removeAttribute('hidden'); +// }) +// } +// } + + +function setHiddenOrNot(parent, isShow) { + if (isShow) { + parent.setAttribute('hidden', ''); } else { - notFinish.forEach(element => { - element.parentElement.removeAttribute('hidden'); - }) + parent.removeAttribute('hidden'); } } -function addTodoList() { - if (window.event.keyCode == 13) { - var todo_input = document.getElementsByClassName("todo-input"); - var input_value = todo_input[0].value; - if (input_value != 0) { - var parentElem = document.getElementById("todo-list"); - var todoListElem = createTodoElement(input_value, parentElem); - parentElem.appendChild(todoListElem); - todo_input[0].value = null; +function HandleOnChange(event) { + const selectValue = event.target.value; + const notFinish = document.querySelectorAll(".check-box"); + notFinish.forEach(element => { + const parentList = element.parentElement; + const isChecked = element.checked; + if (selectValue === "todo") { + // check되어 있으면(true면) 숨겨야된다 + setHiddenOrNot(parentList, isChecked) + } else if (selectValue === "done") { + // check되어 있으면(true면) 보여야된다 + setHiddenOrNot(parentList, !isChecked); + } else { + // 항상 보여야된다 + setHiddenOrNot(parentList, false); } + }); +} + +// if문 쓸 때는 성공 케이스가 아니라 실패 케이스일 때를 체크하도록 +function addTodoList() { + if (window.event.keyCode !== 13) { + return ; + } + var todo_input = document.getElementsByClassName("todo-input"); + var input_value = todo_input[0].value; + /* + input_value == 0 이랑 input_value === 0이랑 기대값이 다르게 나온다. + 입력값 없이 엔터치면 return 되게 하고싶은데, ===0으로 하면 안된다. 왜일까? + */ + if (input_value == 0) { + return ; } + var parentElem = document.getElementById("todo-list"); + var todoListElem = createTodoElement(input_value, parentElem); + parentElem.appendChild(todoListElem); + todo_input[0].value = null; } +// function addTodoList() { +// if (window.event.keyCode == 13) { +// var todo_input = document.getElementsByClassName("todo-input"); +// var input_value = todo_input[0].value; +// if (input_value != 0) { +// var parentElem = document.getElementById("todo-list"); +// var todoListElem = createTodoElement(input_value, parentElem); +// parentElem.appendChild(todoListElem); +// todo_input[0].value = null; +// } +// } +// } + function createTodoElement(input_value, parentElem) { var newList = document.createElement('li'); var checkBox = checkBoxElement(); @@ -52,7 +103,6 @@ function createTodoElement(input_value, parentElem) { newList.appendChild(editBtn); - delBtn.addEventListener("click", () => { parentElem.removeChild(newList); }) @@ -63,21 +113,47 @@ function createTodoElement(input_value, parentElem) { function checkBoxElement() { var checkBox = document.createElement('input'); checkBox.setAttribute('type', 'checkbox'); - checkBox.setAttribute('class', 'cbox'); + checkBox.setAttribute('class', 'check-box'); return checkBox; } +// function editElement() { +// var editBtn = document.createElement('input'); +// editBtn.setAttribute('type', 'button'); +// editBtn.setAttribute('value', 'Edit'); +// editBtn.addEventListener("click", () => { +// // 함수로 나눠서 줄이기 +// // createEditButton = createButton({....}) +// // createinputText = createInputTesxt({....}) +// // createCheckBox = createCheckBox({....}) + +// var parentElem = editBtn.parentElement; +// var inputText = document.createElement('input'); +// inputText.setAttribute('type', 'text'); +// var saveBtn = document.createElement('input'); +// saveBtn.setAttribute('type', 'button'); +// saveBtn.setAttribute('value', 'Save'); +// var prevElem = parentElem.getElementsByTagName('input'); +// var prevCheckBox = prevElem[0]; +// var prevEdit = prevElem[1]; +// var prevDel = prevElem[2]; +// parentElem.replaceChildren(inputText, saveBtn); +// saveBtn.addEventListener("click", () => { +// parentElem.replaceChildren(prevCheckBox, inputText.value, prevEdit, prevDel); +// }) +// }) +// return editBtn; +// } + function editElement() { - var editBtn = document.createElement('input'); - editBtn.setAttribute('type', 'button'); - editBtn.setAttribute('value', 'Edit'); + var editBtn = createInputButton('Edit'); editBtn.addEventListener("click", () => { var parentElem = editBtn.parentElement; - var inputText = document.createElement('input'); - inputText.setAttribute('type', 'text'); - var saveBtn = document.createElement('input'); - saveBtn.setAttribute('type', 'button'); - saveBtn.setAttribute('value', 'Save'); + + var inputText = createInputText(); + var saveBtn = createInputButton('Save'); + + // 이전에 자식element로 존재했던 체크박스, 수정버튼, 삭제버튼을 미리 저장. var prevElem = parentElem.getElementsByTagName('input'); var prevCheckBox = prevElem[0]; var prevEdit = prevElem[1]; @@ -90,6 +166,20 @@ function editElement() { return editBtn; } +function createInputButton(inputValue) { + const btn = document.createElement('input'); + btn.setAttribute('type', 'button'); + btn.setAttribute('value', inputValue); + return btn; +} + +function createInputText() { + const inputText = document.createElement('input'); + inputText.setAttribute('type', 'text'); + return inputText; +} + +// 이것도 createInputButton으로 대신할 수 있다. function delElement() { var delBtn = document.createElement('input'); delBtn.setAttribute('type', 'button'); diff --git a/detail.html b/detail.html index 5da5fcc..cb3b2ba 100644 --- a/detail.html +++ b/detail.html @@ -12,7 +12,7 @@

    TODO LIST

    - From 6e96c273e86e0ebf52ed3eb519420ed11063ad02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9C=A0=EC=84=B1?= Date: Fri, 20 Dec 2024 17:45:38 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Local=20Storage=EB=A5=BC=20=ED=86=B5?= =?UTF-8?q?=ED=95=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=9C=A0=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- detail-script-storage.js | 235 +++++++++++++++++++++++++++++++++++++++ detail-script.js | 2 +- detail.html | 2 +- 3 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 detail-script-storage.js diff --git a/detail-script-storage.js b/detail-script-storage.js new file mode 100644 index 0000000..84eedd6 --- /dev/null +++ b/detail-script-storage.js @@ -0,0 +1,235 @@ +const storageDate = getStorageTodo(); + +if (storageDate) { + console.log("storage"); + const todo_list = document.getElementById("todo-list"); + storageDate.forEach(item => { + addStroageTodo(item, todo_list); + }) +} + +function addStroageTodo(item, parent) { + const newList = document.createElement("li"); + const checkBox = checkBoxElement(); + const editBtn = editElement(); + // const delBtn = delElement(); + const delBtn = createInputButton("X"); + delBtn.addEventListener("click", () => { + deleteStorageElement(newList.textContent); + parent.removeChild(newList); + }); + checkBox.addEventListener('click', () => { + if (checkBox.checked) { + checkStorageElement(newList.textContent, true); + } else { + checkStorageElement(newList.textContent, false); + } + }); + if (item[0] === true) { + checkBox.checked = true; + } else { + checkBox.checked = false; + } + newList.replaceChildren(checkBox, item[1], editBtn, delBtn); + parent.appendChild(newList); +} + +function setHiddenOrNot(parent, isShow) { + if (isShow) { + parent.setAttribute('hidden', ''); + } else { + parent.removeAttribute('hidden'); + } +} + +function HandleOnChange(event) { + const selectValue = event.target.value; + const notFinish = document.querySelectorAll(".check-box"); + notFinish.forEach(element => { + const parentList = element.parentElement; + const isChecked = element.checked; + if (selectValue === "todo") { + // check되어 있으면(true면) 숨겨야된다 + setHiddenOrNot(parentList, isChecked) + } else if (selectValue === "done") { + // check되어 있으면(true면) 보여야된다 + setHiddenOrNot(parentList, !isChecked); + } else { + // 항상 보여야된다 + setHiddenOrNot(parentList, false); + } + }); +} + +function addTodoList() { + if (window.event.keyCode !== 13) { + return ; + } + var todo_input = document.getElementsByClassName("todo-input"); + var input_value = todo_input[0].value; + /* + input_value == 0 이랑 input_value === 0이랑 기대값이 다르게 나온다. + 입력값 없이 엔터치면 return 되게 하고싶은데, ===0으로 하면 안된다. 왜일까? + */ + if (input_value == 0) { + return ; + } + var parentElem = document.getElementById("todo-list"); + var todoListElem = createTodoElement(input_value, parentElem); + parentElem.appendChild(todoListElem); + todo_input[0].value = null; +} + +function createTodoElement(input_value, parentElem) { + var newList = document.createElement('li'); + var checkBox = checkBoxElement(); + var editBtn = editElement(); + // var delBtn = delElement(); + const delBtn = createInputButton("X"); + const arr = getStorageTodo(); + + delBtn.addEventListener("click", () => { + deleteStorageElement(newList.textContent); + parentElem.removeChild(newList); + }); + checkBox.addEventListener('click', () => { + if (checkBox.checked) { + checkStorageElement(newList.textContent, true); + } else { + checkStorageElement(newList.textContent, false); + } + }); + newList.replaceChildren(checkBox, input_value, editBtn, delBtn); + const check_value_arr = [checkBox.checked, input_value]; + arr.push(check_value_arr); + localStorage.setItem('storagedTodo', JSON.stringify(arr)); + return newList; +} + +// LocalStorage로 부터 데이터를 받아와서 배열로 반환 +function getStorageTodo() { + const storagedTodo = localStorage.getItem('storagedTodo'); + let arr = storagedTodo === null ? [] : JSON.parse(storagedTodo); + return arr; +} + +// 배열이 비어있는지 확인 +function isStroageEmpty(arr) { + if (arr === null || arr.length === 0) { + return true; + } + return false; +} + +// 배열로부터 해당 값에 대한 인덱스가 존재하는 확인 +function getStorageIndex(value, arr) { + for (let index = 0; index < arr.length; index++) { + if (arr[index][1] === value) { + return index; + } + } + return -1; +} + +// 삭제버튼 누를경우 localstorage에서도 삭제 +function deleteStorageElement(value) { + const arr = getStorageTodo(); + if (isStroageEmpty(arr)) { + return ; + } + const index = getStorageIndex(value, arr); + if (index === -1) { + return ; + } + arr.splice(index, 1); + localStorage.setItem('storagedTodo', JSON.stringify(arr)); +} + +// 수정버튼 누를경우 localstorage에서도 값을 수정 +function editStroageElement(prev_value, after_value) { + const arr = getStorageTodo(); + if (isStroageEmpty(arr)) { + return ; + } + const index = getStorageIndex(prev_value, arr); + if (index === -1) { + return ; + } + const temp = arr[index]; + temp[1] = after_value; + arr.splice(index, 1, temp); + localStorage.setItem('storagedTodo', JSON.stringify(arr)); +} + +// 체크버튼 누를경우 localstorage에서도 check를 변경 +function checkStorageElement(value, checked) { + const arr = getStorageTodo(); + if (isStroageEmpty(arr)) { + return ; + } + const index = getStorageIndex(value, arr); + if (index === -1) { + return ; + } + const temp = arr[index]; + temp[0] = checked; + arr.splice(index, 1, temp); + localStorage.setItem('storagedTodo', JSON.stringify(arr)); +} + +/* +checkStroage, editStroage, deleteStorage 모두 중복되는 함수부분이 존재한다. +하나로 묶으면 좋을듯. +*/ + +function checkBoxElement() { + var checkBox = document.createElement('input'); + checkBox.setAttribute('type', 'checkbox'); + checkBox.setAttribute('class', 'check-box'); + return checkBox; +} + +function editElement() { + var editBtn = createInputButton('Edit'); + editBtn.addEventListener("click", () => { + var parentElem = editBtn.parentElement; + const prev_value = parentElem.textContent; + + var inputText = createInputText(); + var saveBtn = createInputButton('Save'); + + // 이전에 자식element로 존재했던 체크박스, 수정버튼, 삭제버튼을 미리 저장. + var prevElem = parentElem.getElementsByTagName('input'); + var prevCheckBox = prevElem[0]; + var prevEdit = prevElem[1]; + var prevDel = prevElem[2]; + parentElem.replaceChildren(inputText, saveBtn); + saveBtn.addEventListener("click", () => { + parentElem.replaceChildren(prevCheckBox, inputText.value, prevEdit, prevDel); + editStroageElement(prev_value, inputText.value); + }) + }) + return editBtn; +} + +function createInputButton(inputValue) { + const btn = document.createElement('input'); + btn.setAttribute('type', 'button'); + btn.setAttribute('value', inputValue); + return btn; +} + +function createInputText() { + const inputText = document.createElement('input'); + inputText.setAttribute('type', 'text'); + return inputText; +} + +// 이것도 createInputButton으로 대신할 수 있다. +// function delElement(newList, parentElem) { +// var delBtn = document.createElement('input'); +// delBtn.setAttribute('type', 'button'); +// delBtn.setAttribute('value', 'X'); +// return delBtn; +// } + diff --git a/detail-script.js b/detail-script.js index 26dd255..cbce244 100644 --- a/detail-script.js +++ b/detail-script.js @@ -183,7 +183,7 @@ function createInputText() { function delElement() { var delBtn = document.createElement('input'); delBtn.setAttribute('type', 'button'); - delBtn.setAttribute('value', 'X'); + delBtn.setAttribute('value', 'XXX'); return delBtn; } diff --git a/detail.html b/detail.html index cb3b2ba..6b15c7c 100644 --- a/detail.html +++ b/detail.html @@ -24,5 +24,5 @@

    TODO LIST

    - +