From d0b6e6cfe5ec0ff7ef63167b640166c87f6a688d Mon Sep 17 00:00:00 2001 From: blog Date: Tue, 17 Dec 2019 08:11:21 +0900 Subject: [PATCH 01/12] =?UTF-8?q?branch=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/css/style.css | 334 +++++++++++++++++++++++++++++++++ mission001/jisun/index.html | 61 ++++++ 2 files changed, 395 insertions(+) create mode 100644 mission001/jisun/css/style.css create mode 100644 mission001/jisun/index.html diff --git a/mission001/jisun/css/style.css b/mission001/jisun/css/style.css new file mode 100644 index 0000000..14a905e --- /dev/null +++ b/mission001/jisun/css/style.css @@ -0,0 +1,334 @@ +html, +body { + margin: 0; + padding: 10px; +} + +button { + margin: 0; + padding: 0; + border: 0; + background: none; + font-size: 100%; + vertical-align: baseline; + font-family: inherit; + font-weight: inherit; + color: inherit; + -webkit-appearance: none; + appearance: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4em; + background: #f5f5f5; + color: #4d4d4d; + min-width: 230px; + max-width: 550px; + margin: 0 auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: 300; +} + +:focus { + outline: 0; +} + +.hidden { + display: none; +} + +.todoapp { + background: #fff; + margin: 130px 0 40px 0; + position: relative; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), + 0 25px 50px 0 rgba(0, 0, 0, 0.1); +} + +.todoapp input::-webkit-input-placeholder { + font-style: italic; + font-weight: 300; + color: #e6e6e6; +} + +.todoapp h1 { + position: absolute; + top: -125px; + width: 100%; + font-size: 60px; + text-align: center; + color: dimgray; + font-weight: 100; + font-family: Helvetica Neue, Helvetica, Arial, sans-serif; +} + +.new-todo, +.edit { + position: relative; + margin: 0; + width: 100%; + font-size: 24px; + font-family: inherit; + font-weight: inherit; + line-height: 1.4em; + border: 0; + color: inherit; + padding: 6px; + box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); + box-sizing: border-box; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.new-todo { + padding: 16px 16px 16px 60px; + border: none; + background: rgba(0, 0, 0, 0.003); + box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); +} + +.main { + position: relative; + z-index: 2; + border-top: 1px solid #e6e6e6; +} + +.toggle-all { + width: 1px; + height: 1px; + border: none; + opacity: 0; + position: absolute; + right: 100%; + bottom: 100%; +} + +.toggle-all + label { + width: 60px; + height: 34px; + font-size: 0; + position: absolute; + top: -52px; + left: -13px; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} + +.toggle-all + label:before { + content: '❯'; + font-size: 22px; + color: #e6e6e6; + padding: 10px 27px 10px 27px; +} + +.toggle-all:checked + label:before { + color: #737373; +} + +.todo-list { + margin: 0; + padding: 0; + list-style: none; +} + +.todo-list li { + position: relative; + font-size: 24px; + border-bottom: 1px solid #ededed; +} + +.todo-list li:last-child { + border-bottom: none; +} + +.todo-list li.editing { + border-bottom: none; + padding: 0; +} + +.todo-list li.editing .edit { + display: block; + width: calc(100% - 43px); + padding: 12px 16px; + margin: 0 0 0 43px; +} + +.todo-list li.editing .view { + display: none; +} + +.todo-list li .toggle { + text-align: center; + width: 40px; + height: auto; + position: absolute; + top: 0; + bottom: 0; + margin: auto 0; + border: none; + -webkit-appearance: none; + appearance: none; +} + +.todo-list li .toggle { + opacity: 0; +} + +.todo-list li .toggle + label { + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); + background-repeat: no-repeat; + background-position: center left; +} + +.todo-list li .toggle:checked + label { + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); +} + +.todo-list li label { + word-break: break-all; + padding: 15px 15px 15px 60px; + display: block; + line-height: 1.2; + transition: color 0.4s; +} + +.todo-list li.completed label { + color: #d9d9d9; + text-decoration: line-through; +} + +.todo-list li .destroy { + display: none; + position: absolute; + top: 0; + right: 10px; + bottom: 0; + width: 40px; + height: 40px; + margin: auto 0; + font-size: 30px; + color: #cc9a9a; + margin-bottom: 11px; + transition: color 0.2s ease-out; + cursor: pointer; +} + +.todo-list li .destroy:hover { + color: #af5b5e; +} + +.todo-list li .destroy:after { + content: '×'; +} + +.todo-list li:hover .destroy { + display: block; +} + +.todo-list li .edit { + display: none; +} + +.todo-list li.editing:last-child { + margin-bottom: -1px; +} + +.count-container { + color: #777; + padding: 10px 15px; + height: 20px; + text-align: center; + border-top: 1px solid #e6e6e6; +} + +.count-container:before { + content: ''; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 50px; + overflow: hidden; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), + 0 8px 0 -3px #f6f6f6, + 0 9px 1px -3px rgba(0, 0, 0, 0.2), + 0 16px 0 -6px #f6f6f6, + 0 17px 2px -6px rgba(0, 0, 0, 0.2); +} + +.todo-count { + float: left; + text-align: left; +} + +.todo-count strong { + font-weight: 300; +} + +.filters { + margin: 0; + padding: 0; + list-style: none; + position: absolute; + right: 0; + left: 0; +} + +.filters li { + display: inline; +} + +.filters li a { + color: inherit; + margin: 3px; + padding: 3px 7px; + text-decoration: none; + border: 1px solid transparent; + border-radius: 3px; +} + +.filters li a:hover { + border-color: rgba(175, 47, 47, 0.1); +} + +.filters li a.selected { + border-color: rgba(175, 47, 47, 0.2); +} + +.clear-completed, html .clear-completed:active { + float: right; + position: relative; + line-height: 20px; + text-decoration: none; + cursor: pointer; +} + +.clear-completed:hover { + text-decoration: underline; +} + +.info { + margin: 65px auto 0; + color: #bfbfbf; + font-size: 10px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-align: center; +} + +.info p { + line-height: 1; +} + +.info a { + color: inherit; + text-decoration: none; + font-weight: 400; +} + +.info a:hover { + text-decoration: underline; +} diff --git a/mission001/jisun/index.html b/mission001/jisun/index.html new file mode 100644 index 0000000..b1180c7 --- /dev/null +++ b/mission001/jisun/index.html @@ -0,0 +1,61 @@ + + + + + + 이벤트 - TODOS + + + +
+
+

TODOS

+ +
+
+ +
    +
  • +
    + + + +
    + +
  • +
  • +
    + + + +
    + +
  • +
  • +
    + + + +
    + +
  • +
+
+
+ 0 + +
+
+ + + From 19b706dc04b34b3192f43a940972b98f51196c1b Mon Sep 17 00:00:00 2001 From: blog Date: Tue, 17 Dec 2019 09:39:48 +0900 Subject: [PATCH 02/12] todolist --- mission001/jisun/css/style.css | 6 ++-- mission001/jisun/index.html | 13 +++++---- mission001/jisun/js/app.js | 53 ++++++++++++++++++++++++++++++++++ mission001/jisun/package.json | 10 +++++++ 4 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 mission001/jisun/js/app.js create mode 100644 mission001/jisun/package.json diff --git a/mission001/jisun/css/style.css b/mission001/jisun/css/style.css index 14a905e..c326034 100644 --- a/mission001/jisun/css/style.css +++ b/mission001/jisun/css/style.css @@ -41,7 +41,7 @@ body { display: none; } -.todoapp { +.todo-app { background: #fff; margin: 130px 0 40px 0; position: relative; @@ -49,13 +49,13 @@ body { 0 25px 50px 0 rgba(0, 0, 0, 0.1); } -.todoapp input::-webkit-input-placeholder { +.todo-app input::-webkit-input-placeholder { font-style: italic; font-weight: 300; color: #e6e6e6; } -.todoapp h1 { +.todo-app h1 { position: absolute; top: -125px; width: 100%; diff --git a/mission001/jisun/index.html b/mission001/jisun/index.html index b1180c7..2940ecd 100644 --- a/mission001/jisun/index.html +++ b/mission001/jisun/index.html @@ -7,14 +7,15 @@ -
+

TODOS

- +
- -
    + +
      +
    - 0 +
    • 전체보기 diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js new file mode 100644 index 0000000..adee746 --- /dev/null +++ b/mission001/jisun/js/app.js @@ -0,0 +1,53 @@ +const status = { + COMPLETE: 'complete', + PROCEEDING: 'proceeding', + NEED_TODO: 'needTodo' +} + +let todoListData = [ + { text: '할일A', status: status.COMPLETE }, + { text: '할일A', status: status.PROCEEDING }, + { text: '할일A', status: status.NEED_TODO } +]; + +const todoList = document.getElementById('todoList'); + +const renderTodoList = todoListData => { + // todoList 비우기 + todoList.innerHTML = ''; + + if (todoListData.length === 0) { + todoList.innerHTML = `
    • Todo List가 비어있습니다
    • `; + } else { + todoListData.forEach(data => { + console.log(data); + todoList.innerHTML += + `
    • +
      + + + +
      + +
    • ` + }); + } +} +renderTodoList(todoListData); + +// input +const input = document.getElementById('inputTodo'); + +input.addEventListener('keypress', e => { + if (e.key === 'Enter') { + todoListData.push({ text: input.value, status: status.NEED_TODO }) + renderTodoList(todoListData); + e.target.value = ''; + + console.log(todoListData); + } +}); + +// count +const todoCount = document.getElementById('todoCount'); +todoCount.innerHTML = `총 ${todoListData.length} 개` \ No newline at end of file diff --git a/mission001/jisun/package.json b/mission001/jisun/package.json new file mode 100644 index 0000000..2d94a03 --- /dev/null +++ b/mission001/jisun/package.json @@ -0,0 +1,10 @@ +{ + "name": "mission001-jisun", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} From 037ec63c0abd19f45d5be53343b2887ecb2caf0b Mon Sep 17 00:00:00 2001 From: "cien.lee" Date: Tue, 17 Dec 2019 20:03:48 +0900 Subject: [PATCH 03/12] =?UTF-8?q?app.js=EC=97=90=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/index.html | 75 ++++++++-------- mission001/jisun/js/app.js | 136 +++++++++++++++++++++++------ mission001/jisun/package-lock.json | 5 ++ 3 files changed, 155 insertions(+), 61 deletions(-) create mode 100644 mission001/jisun/package-lock.json diff --git a/mission001/jisun/index.html b/mission001/jisun/index.html index 2940ecd..70b0e22 100644 --- a/mission001/jisun/index.html +++ b/mission001/jisun/index.html @@ -1,21 +1,26 @@ - + - - - - 이벤트 - TODOS - - - -
      -
      -

      TODOS

      - -
      -
      - -
        - + +
        +
        + +
          + -
          -
          - - -
          -
          - - +
        +
        + + +
        +
        + + diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index adee746..9582b8e 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -1,53 +1,137 @@ const status = { - COMPLETE: 'complete', - PROCEEDING: 'proceeding', - NEED_TODO: 'needTodo' -} + COMPLETE: "complete", + PROCEEDING: "proceeding", + NEED_TODO: "needTodo" +}; let todoListData = [ - { text: '할일A', status: status.COMPLETE }, - { text: '할일A', status: status.PROCEEDING }, - { text: '할일A', status: status.NEED_TODO } + { text: "할일A", status: status.COMPLETE, id: 1 }, + { text: "할일B", status: status.PROCEEDING, id: 2 }, + { text: "할일D", status: status.NEED_TODO, id: 3 } ]; -const todoList = document.getElementById('todoList'); +let todoIdCount = todoListData.length + 1; -const renderTodoList = todoListData => { - // todoList 비우기 - todoList.innerHTML = ''; +// todoList 관련 +const todoList = document.getElementById("todoList"); +// 초기 데이터에 따라 todoList render +const renderTodoList = todoListData => { if (todoListData.length === 0) { todoList.innerHTML = `
      • Todo List가 비어있습니다
      • `; } else { todoListData.forEach(data => { - console.log(data); - todoList.innerHTML += - `
      • + todoList.innerHTML += `
        - +
        -
      • ` + `; + }); + } + + const toggles = document.getElementsByClassName("toggle"); + const deleteBtns = document.getElementsByClassName("destroy"); + + for (let i = 0; i < toggles.length; ++i) { + toggles[i].addEventListener("change", e => { + onComplete(e); }); } -} + + for (let i = 0; i < deleteBtns.length; ++i) { + deleteBtns[i].addEventListener("click", e => { + deleteTodoList(e); + }); + } +}; renderTodoList(todoListData); +// TodoList에 new data 추가 +const addTodoList = data => { + const list = document.createElement("li"); + list.id = `todo-${data.id}`; + todoList.appendChild(list); + + list.innerHTML = `
        + + + +
        + `; + + const checkbox = list.firstChild.childNodes[1]; + const deleteBtn = list.firstChild.childNodes[5]; + todoIdCount++; + + checkbox.addEventListener("change", e => { + onComplete(e); + }); + + deleteBtn.addEventListener("click", e => { + deleteTodoList(e); + }); +}; + +// TodoList의 data 제거 +const deleteTodoList = e => { + const list = e.target.parentElement.parentElement; + todoList.removeChild(list); + id = list.id.replace(/[^0-9]/g, ""); + for (let i = 0; i < todoListData.length; ++i) { + if (todoListData[i].id.toString() === id) { + todoListData.splice(i, 1); + } + } + + console.log(todoListData); +}; + +// TodoList - checkbox 관련 +const onComplete = e => { + const list = e.target.parentElement.parentElement; + + if (e.target.checked) { + list.classList.add("completed"); + } else { + list.classList.remove("completed"); + } +}; + // input -const input = document.getElementById('inputTodo'); +const input = document.getElementById("inputTodo"); -input.addEventListener('keypress', e => { - if (e.key === 'Enter') { - todoListData.push({ text: input.value, status: status.NEED_TODO }) - renderTodoList(todoListData); - e.target.value = ''; +input.addEventListener("keypress", e => { + if (e.key === "Enter") { + if (input.value === "") { + alert("값을 입력해주세요 !"); + } - console.log(todoListData); + const newTodoData = { + text: input.value, + status: status.NEED_TODO, + id: todoIdCount + }; + + todoListData.push(newTodoData); + addTodoList(newTodoData); + renderCount(todoListData); + e.target.value = ""; } }); // count -const todoCount = document.getElementById('todoCount'); -todoCount.innerHTML = `총 ${todoListData.length} 개` \ No newline at end of file +const todoCount = document.getElementById("todoCount"); + +const renderCount = todoListData => { + todoCount.innerHTML = `총 ${todoListData.length} 개`; +}; + +// 초기값 랜더 +renderCount(todoListData); diff --git a/mission001/jisun/package-lock.json b/mission001/jisun/package-lock.json new file mode 100644 index 0000000..271e4c7 --- /dev/null +++ b/mission001/jisun/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "mission001-jisun", + "version": "1.0.0", + "lockfileVersion": 1 +} From f0135e3dd7e3bfd34c3ed37d221148f8e624a865 Mon Sep 17 00:00:00 2001 From: "cien.lee" Date: Wed, 18 Dec 2019 14:48:41 +0900 Subject: [PATCH 04/12] =?UTF-8?q?=EB=AA=A8=EB=93=A0=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/css/style.css | 387 +++++++++++++++++---------------- mission001/jisun/index.html | 6 +- mission001/jisun/js/app.js | 76 ++++++- 3 files changed, 270 insertions(+), 199 deletions(-) diff --git a/mission001/jisun/css/style.css b/mission001/jisun/css/style.css index c326034..0e2f0a2 100644 --- a/mission001/jisun/css/style.css +++ b/mission001/jisun/css/style.css @@ -1,334 +1,345 @@ html, body { - margin: 0; - padding: 10px; + margin: 0; + padding: 10px; } button { - margin: 0; - padding: 0; - border: 0; - background: none; - font-size: 100%; - vertical-align: baseline; - font-family: inherit; - font-weight: inherit; - color: inherit; - -webkit-appearance: none; - appearance: none; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + margin: 0; + padding: 0; + border: 0; + background: none; + font-size: 100%; + vertical-align: baseline; + font-family: inherit; + font-weight: inherit; + color: inherit; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } body { - font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; - line-height: 1.4em; - background: #f5f5f5; - color: #4d4d4d; - min-width: 230px; - max-width: 550px; - margin: 0 auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-weight: 300; + font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif; + line-height: 1.4em; + background: #f5f5f5; + color: #4d4d4d; + min-width: 230px; + max-width: 550px; + margin: 0 auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: 300; } :focus { - outline: 0; + outline: 0; } .hidden { - display: none; + display: none; } .todo-app { - background: #fff; - margin: 130px 0 40px 0; - position: relative; - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), + background: #fff; + margin: 130px 0 40px 0; + position: relative; + -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); } .todo-app input::-webkit-input-placeholder { - font-style: italic; - font-weight: 300; - color: #e6e6e6; + font-style: italic; + font-weight: 300; + color: #e6e6e6; } .todo-app h1 { - position: absolute; - top: -125px; - width: 100%; - font-size: 60px; - text-align: center; - color: dimgray; - font-weight: 100; - font-family: Helvetica Neue, Helvetica, Arial, sans-serif; + position: absolute; + top: -125px; + width: 100%; + font-size: 60px; + text-align: center; + color: dimgray; + font-weight: 100; + font-family: Helvetica Neue, Helvetica, Arial, sans-serif; } .new-todo, .edit { - position: relative; - margin: 0; - width: 100%; - font-size: 24px; - font-family: inherit; - font-weight: inherit; - line-height: 1.4em; - border: 0; - color: inherit; - padding: 6px; - box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); - box-sizing: border-box; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + position: relative; + margin: 0; + width: 100%; + font-size: 24px; + font-family: inherit; + font-weight: inherit; + line-height: 1.4em; + border: 0; + color: inherit; + padding: 6px; + -webkit-box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); + box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); + -webkit-box-sizing: border-box; + box-sizing: border-box; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } .new-todo { - padding: 16px 16px 16px 60px; - border: none; - background: rgba(0, 0, 0, 0.003); - box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); + padding: 16px 16px 16px 60px; + border: none; + background: rgba(0, 0, 0, 0.003); + -webkit-box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03); + box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03); } .main { - position: relative; - z-index: 2; - border-top: 1px solid #e6e6e6; + position: relative; + z-index: 2; + border-top: 1px solid #e6e6e6; } .toggle-all { - width: 1px; - height: 1px; - border: none; - opacity: 0; - position: absolute; - right: 100%; - bottom: 100%; + width: 1px; + height: 1px; + border: none; + opacity: 0; + position: absolute; + right: 100%; + bottom: 100%; } .toggle-all + label { - width: 60px; - height: 34px; - font-size: 0; - position: absolute; - top: -52px; - left: -13px; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); + width: 60px; + height: 34px; + font-size: 0; + position: absolute; + top: -52px; + left: -13px; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } .toggle-all + label:before { - content: '❯'; - font-size: 22px; - color: #e6e6e6; - padding: 10px 27px 10px 27px; + content: "❯"; + font-size: 22px; + color: #e6e6e6; + padding: 10px 27px 10px 27px; } .toggle-all:checked + label:before { - color: #737373; + color: #737373; } .todo-list { - margin: 0; - padding: 0; - list-style: none; + margin: 0; + padding: 0; + list-style: none; } .todo-list li { - position: relative; - font-size: 24px; - border-bottom: 1px solid #ededed; + position: relative; + font-size: 24px; + border-bottom: 1px solid #ededed; } .todo-list li:last-child { - border-bottom: none; + border-bottom: none; } .todo-list li.editing { - border-bottom: none; - padding: 0; + border-bottom: none; + padding: 0; } .todo-list li.editing .edit { - display: block; - width: calc(100% - 43px); - padding: 12px 16px; - margin: 0 0 0 43px; + display: block; + width: calc(100% - 43px); + padding: 12px 16px; + margin: 0 0 0 43px; } .todo-list li.editing .view { - display: none; + display: none; } .todo-list li .toggle { - text-align: center; - width: 40px; - height: auto; - position: absolute; - top: 0; - bottom: 0; - margin: auto 0; - border: none; - -webkit-appearance: none; - appearance: none; + text-align: center; + width: 40px; + height: auto; + position: absolute; + top: 0; + bottom: 0; + margin: auto 0; + border: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } .todo-list li .toggle { - opacity: 0; + opacity: 0; } .todo-list li .toggle + label { - background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); - background-repeat: no-repeat; - background-position: center left; + background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center left; + pointer-events: none; } .todo-list li .toggle:checked + label { - background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); + background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E"); } .todo-list li label { - word-break: break-all; - padding: 15px 15px 15px 60px; - display: block; - line-height: 1.2; - transition: color 0.4s; + word-break: break-all; + padding: 15px 15px 15px 60px; + display: block; + line-height: 1.2; + -webkit-transition: color 0.4s; + transition: color 0.4s; } .todo-list li.completed label { - color: #d9d9d9; - text-decoration: line-through; + color: #d9d9d9; + text-decoration: line-through; } .todo-list li .destroy { - display: none; - position: absolute; - top: 0; - right: 10px; - bottom: 0; - width: 40px; - height: 40px; - margin: auto 0; - font-size: 30px; - color: #cc9a9a; - margin-bottom: 11px; - transition: color 0.2s ease-out; - cursor: pointer; + display: none; + position: absolute; + top: 0; + right: 10px; + bottom: 0; + width: 40px; + height: 40px; + margin: auto 0; + font-size: 30px; + color: #cc9a9a; + margin-bottom: 11px; + -webkit-transition: color 0.2s ease-out; + transition: color 0.2s ease-out; + cursor: pointer; } .todo-list li .destroy:hover { - color: #af5b5e; + color: #af5b5e; } .todo-list li .destroy:after { - content: '×'; + content: "×"; } .todo-list li:hover .destroy { - display: block; + display: block; } .todo-list li .edit { - display: none; + display: none; } .todo-list li.editing:last-child { - margin-bottom: -1px; + margin-bottom: -1px; } .count-container { - color: #777; - padding: 10px 15px; - height: 20px; - text-align: center; - border-top: 1px solid #e6e6e6; + color: #777; + padding: 10px 15px; + height: 20px; + text-align: center; + border-top: 1px solid #e6e6e6; } .count-container:before { - content: ''; - position: absolute; - right: 0; - bottom: 0; - left: 0; - height: 50px; - overflow: hidden; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), - 0 8px 0 -3px #f6f6f6, - 0 9px 1px -3px rgba(0, 0, 0, 0.2), - 0 16px 0 -6px #f6f6f6, + content: ""; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 50px; + overflow: hidden; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, + 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, + 0 17px 2px -6px rgba(0, 0, 0, 0.2); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, + 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2); } .todo-count { - float: left; - text-align: left; + float: left; + text-align: left; } .todo-count strong { - font-weight: 300; + font-weight: 300; } .filters { - margin: 0; - padding: 0; - list-style: none; - position: absolute; - right: 0; - left: 0; + margin: 0; + padding: 0; + list-style: none; + position: absolute; + right: 0; + left: 0; } .filters li { - display: inline; + display: inline; } .filters li a { - color: inherit; - margin: 3px; - padding: 3px 7px; - text-decoration: none; - border: 1px solid transparent; - border-radius: 3px; + color: inherit; + margin: 3px; + padding: 3px 7px; + text-decoration: none; + border: 1px solid transparent; + border-radius: 3px; } .filters li a:hover { - border-color: rgba(175, 47, 47, 0.1); + border-color: rgba(175, 47, 47, 0.1); } .filters li a.selected { - border-color: rgba(175, 47, 47, 0.2); + border-color: rgba(175, 47, 47, 0.2); } -.clear-completed, html .clear-completed:active { - float: right; - position: relative; - line-height: 20px; - text-decoration: none; - cursor: pointer; +.clear-completed, +html .clear-completed:active { + float: right; + position: relative; + line-height: 20px; + text-decoration: none; + cursor: pointer; } .clear-completed:hover { - text-decoration: underline; + text-decoration: underline; } .info { - margin: 65px auto 0; - color: #bfbfbf; - font-size: 10px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - text-align: center; + margin: 65px auto 0; + color: #bfbfbf; + font-size: 10px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-align: center; } .info p { - line-height: 1; + line-height: 1; } .info a { - color: inherit; - text-decoration: none; - font-weight: 400; + color: inherit; + text-decoration: none; + font-weight: 400; } .info a:hover { - text-decoration: underline; + text-decoration: underline; } diff --git a/mission001/jisun/index.html b/mission001/jisun/index.html index 70b0e22..5e930b4 100644 --- a/mission001/jisun/index.html +++ b/mission001/jisun/index.html @@ -49,15 +49,15 @@ diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index 9582b8e..6b9d64b 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -1,11 +1,11 @@ const status = { - COMPLETE: "complete", + COMPLETED: "completed", PROCEEDING: "proceeding", NEED_TODO: "needTodo" }; let todoListData = [ - { text: "할일A", status: status.COMPLETE, id: 1 }, + { text: "할일A", status: status.COMPLETED, id: 1 }, { text: "할일B", status: status.PROCEEDING, id: 2 }, { text: "할일D", status: status.NEED_TODO, id: 3 } ]; @@ -17,16 +17,18 @@ const todoList = document.getElementById("todoList"); // 초기 데이터에 따라 todoList render const renderTodoList = todoListData => { + todoList.innerHTML = ""; + if (todoListData.length === 0) { todoList.innerHTML = `
      • Todo List가 비어있습니다
      • `; } else { todoListData.forEach(data => { todoList.innerHTML += `
        + status.COMPLETED && ` checked`}>
        @@ -50,7 +52,6 @@ const renderTodoList = todoListData => { }); } }; -renderTodoList(todoListData); // TodoList에 new data 추가 const addTodoList = data => { @@ -60,7 +61,7 @@ const addTodoList = data => { list.innerHTML = `
        + status.COMPLETED && "checked"}>
        @@ -84,13 +85,14 @@ const deleteTodoList = e => { const list = e.target.parentElement.parentElement; todoList.removeChild(list); id = list.id.replace(/[^0-9]/g, ""); + for (let i = 0; i < todoListData.length; ++i) { if (todoListData[i].id.toString() === id) { todoListData.splice(i, 1); } } - console.log(todoListData); + renderCount(todoListData); }; // TodoList - checkbox 관련 @@ -107,7 +109,7 @@ const onComplete = e => { // input const input = document.getElementById("inputTodo"); -input.addEventListener("keypress", e => { +input.addEventListener("keydown", e => { if (e.key === "Enter") { if (input.value === "") { alert("값을 입력해주세요 !"); @@ -126,6 +128,36 @@ input.addEventListener("keypress", e => { } }); +// 더블클릭시 edit 모드 +todoList.addEventListener("dblclick", e => { + const label = e.target.childNodes[3]; + const editInput = e.target.nextSibling.nextSibling; + const prevValue = editInput.value; + const id = e.target.parentElement.id.replace(/[^0-9]/g, ""); + + editInput.style.display = "block"; + editInput.addEventListener("keydown", e => { + if (e.keyCode === 27) { + editInput.style.display = "none"; + } + + if (e.keyCode === 13) { + if (prevValue !== editInput.value) { + let i = 0; + while (i < todoListData.length) { + if (todoListData[i].id.toString() === id) { + todoListData[i].text = e.target.value; + label.innerHTML = e.target.value; + break; + } + ++i; + } + } + editInput.style.display = "none"; + } + }); +}); + // count const todoCount = document.getElementById("todoCount"); @@ -133,5 +165,33 @@ const renderCount = todoListData => { todoCount.innerHTML = `총 ${todoListData.length} 개`; }; +// 선택한 텝에 따라 랜더링 다시하기 'ㅁ' +const tab = document.getElementById("tab"); +tab.addEventListener("click", e => { + const selectedTab = e.target.id; + let selectedTodoData = []; + + if (selectedTab === status.COMPLETED) { + for (let i = 0; i < todoListData.length; ++i) { + if (todoListData[i].status === status.COMPLETED) { + selectedTodoData.push(todoListData[i]); + } + } + } else if (selectedTab === status.NEED_TODO) { + for (let i = 0; i < todoListData.length; ++i) { + if (todoListData[i].status === status.NEED_TODO) { + selectedTodoData.push(todoListData[i]); + } + } + } else { + for (let i = 0; i < todoListData.length; ++i) { + selectedTodoData.push(todoListData[i]); + } + } + + renderTodoList(selectedTodoData); +}); + // 초기값 랜더 renderCount(todoListData); +renderTodoList(todoListData); From 6db05185965bed03659e0100daeec615e1c6a036 Mon Sep 17 00:00:00 2001 From: "cien.lee" Date: Wed, 18 Dec 2019 15:36:56 +0900 Subject: [PATCH 05/12] =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/js/app.js | 43 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index 6b9d64b..2eb3640 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -26,14 +26,14 @@ const renderTodoList = todoListData => { todoList.innerHTML += ` -
        - - - -
        - - `; +
        + + + +
        + + `; }); } @@ -168,28 +168,27 @@ const renderCount = todoListData => { // 선택한 텝에 따라 랜더링 다시하기 'ㅁ' const tab = document.getElementById("tab"); tab.addEventListener("click", e => { - const selectedTab = e.target.id; + const selectedTab = e.target; + const prevSelectedTab = document.querySelector(".selected"); + + prevSelectedTab.classList.remove("selected"); + selectedTab.classList.add("selected"); + let selectedTodoData = []; - if (selectedTab === status.COMPLETED) { + if ( + selectedTab.id === status.COMPLETED || + selectedTab.id === status.NEED_TODO + ) { for (let i = 0; i < todoListData.length; ++i) { - if (todoListData[i].status === status.COMPLETED) { - selectedTodoData.push(todoListData[i]); - } - } - } else if (selectedTab === status.NEED_TODO) { - for (let i = 0; i < todoListData.length; ++i) { - if (todoListData[i].status === status.NEED_TODO) { + if (todoListData[i].status === selectedTab.id) { selectedTodoData.push(todoListData[i]); } } + renderTodoList(selectedTodoData); } else { - for (let i = 0; i < todoListData.length; ++i) { - selectedTodoData.push(todoListData[i]); - } + renderTodoList(todoListData); } - - renderTodoList(selectedTodoData); }); // 초기값 랜더 From b6a8cd95b2d4a97dc180cc98c151d4aebc167e65 Mon Sep 17 00:00:00 2001 From: "cien.lee" Date: Wed, 18 Dec 2019 17:10:45 +0900 Subject: [PATCH 06/12] =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/index.html | 2 +- mission001/jisun/js/app.js | 6 +++--- mission001/jisun/js/components/TodoCount.js | 0 mission001/jisun/js/components/TodoInput.js | 0 mission001/jisun/js/components/TodoList.js | 0 mission001/jisun/js/components/index.js | 0 mission001/jisun/js/store/store.js | 11 +++++++++++ 7 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 mission001/jisun/js/components/TodoCount.js create mode 100644 mission001/jisun/js/components/TodoInput.js create mode 100644 mission001/jisun/js/components/TodoList.js create mode 100644 mission001/jisun/js/components/index.js create mode 100644 mission001/jisun/js/store/store.js diff --git a/mission001/jisun/index.html b/mission001/jisun/index.html index 5e930b4..1a9e7ac 100644 --- a/mission001/jisun/index.html +++ b/mission001/jisun/index.html @@ -13,7 +13,7 @@ diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index 2eb3640..8d6f0d5 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -5,9 +5,9 @@ const status = { }; let todoListData = [ - { text: "할일A", status: status.COMPLETED, id: 1 }, - { text: "할일B", status: status.PROCEEDING, id: 2 }, - { text: "할일D", status: status.NEED_TODO, id: 3 } + { text: "AAAAA", status: status.COMPLETED, id: 1 }, + { text: "BBBBB", status: status.PROCEEDING, id: 2 }, + { text: "DDDDD", status: status.NEED_TODO, id: 3 } ]; let todoIdCount = todoListData.length + 1; diff --git a/mission001/jisun/js/components/TodoCount.js b/mission001/jisun/js/components/TodoCount.js new file mode 100644 index 0000000..e69de29 diff --git a/mission001/jisun/js/components/TodoInput.js b/mission001/jisun/js/components/TodoInput.js new file mode 100644 index 0000000..e69de29 diff --git a/mission001/jisun/js/components/TodoList.js b/mission001/jisun/js/components/TodoList.js new file mode 100644 index 0000000..e69de29 diff --git a/mission001/jisun/js/components/index.js b/mission001/jisun/js/components/index.js new file mode 100644 index 0000000..e69de29 diff --git a/mission001/jisun/js/store/store.js b/mission001/jisun/js/store/store.js new file mode 100644 index 0000000..e7b04b5 --- /dev/null +++ b/mission001/jisun/js/store/store.js @@ -0,0 +1,11 @@ +export let initData = [ + { text: "AAAAA", status: status.COMPLETED, id: 1 }, + { text: "BBBBB", status: status.PROCEEDING, id: 2 }, + { text: "DDDDD", status: status.NEED_TODO, id: 3 } +]; + +export const setData = newData => { + initData = newData; + console.log("set data: "); + console.log(initData); +}; From bd857ecd514a50a33012561d31d41f878c376b4a Mon Sep 17 00:00:00 2001 From: blog Date: Wed, 18 Dec 2019 19:52:04 +0900 Subject: [PATCH 07/12] =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EB=A1=9C=20=EB=82=98=EB=88=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/index.html | 2 +- mission001/jisun/js/app.js | 201 +------------------- mission001/jisun/js/components/TodoCount.js | 9 + mission001/jisun/js/components/TodoInput.js | 26 +++ mission001/jisun/js/components/TodoList.js | 135 +++++++++++++ mission001/jisun/js/components/index.js | 0 mission001/jisun/js/store/store.js | 20 +- mission001/jisun/js/util/utils.js | 30 +++ 8 files changed, 227 insertions(+), 196 deletions(-) delete mode 100644 mission001/jisun/js/components/index.js create mode 100644 mission001/jisun/js/util/utils.js diff --git a/mission001/jisun/index.html b/mission001/jisun/index.html index 1a9e7ac..84930c0 100644 --- a/mission001/jisun/index.html +++ b/mission001/jisun/index.html @@ -62,6 +62,6 @@
        - + diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index 8d6f0d5..c458366 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -1,196 +1,15 @@ -const status = { - COMPLETED: "completed", - PROCEEDING: "proceeding", - NEED_TODO: "needTodo" -}; +import { todoListData, todoIdCount } from './store/store.js'; +import { TodoList } from './components/TodoList.js'; +import { TodoInput } from './components/TodoInput.js'; +import { TodoCount } from './components/TodoCount.js'; +import { onSelectTab } from './util/utils.js'; -let todoListData = [ - { text: "AAAAA", status: status.COMPLETED, id: 1 }, - { text: "BBBBB", status: status.PROCEEDING, id: 2 }, - { text: "DDDDD", status: status.NEED_TODO, id: 3 } -]; - -let todoIdCount = todoListData.length + 1; - -// todoList 관련 -const todoList = document.getElementById("todoList"); - -// 초기 데이터에 따라 todoList render -const renderTodoList = todoListData => { - todoList.innerHTML = ""; - - if (todoListData.length === 0) { - todoList.innerHTML = `
      • Todo List가 비어있습니다
      • `; - } else { - todoListData.forEach(data => { - todoList.innerHTML += ` -
        - - - -
        - - `; - }); - } - - const toggles = document.getElementsByClassName("toggle"); - const deleteBtns = document.getElementsByClassName("destroy"); - - for (let i = 0; i < toggles.length; ++i) { - toggles[i].addEventListener("change", e => { - onComplete(e); - }); - } - - for (let i = 0; i < deleteBtns.length; ++i) { - deleteBtns[i].addEventListener("click", e => { - deleteTodoList(e); - }); - } -}; - -// TodoList에 new data 추가 -const addTodoList = data => { - const list = document.createElement("li"); - list.id = `todo-${data.id}`; - todoList.appendChild(list); - - list.innerHTML = `
        - - - -
        - `; - - const checkbox = list.firstChild.childNodes[1]; - const deleteBtn = list.firstChild.childNodes[5]; - todoIdCount++; - - checkbox.addEventListener("change", e => { - onComplete(e); - }); - - deleteBtn.addEventListener("click", e => { - deleteTodoList(e); - }); -}; - -// TodoList의 data 제거 -const deleteTodoList = e => { - const list = e.target.parentElement.parentElement; - todoList.removeChild(list); - id = list.id.replace(/[^0-9]/g, ""); - - for (let i = 0; i < todoListData.length; ++i) { - if (todoListData[i].id.toString() === id) { - todoListData.splice(i, 1); - } - } - - renderCount(todoListData); -}; - -// TodoList - checkbox 관련 -const onComplete = e => { - const list = e.target.parentElement.parentElement; - - if (e.target.checked) { - list.classList.add("completed"); - } else { - list.classList.remove("completed"); - } -}; - -// input -const input = document.getElementById("inputTodo"); - -input.addEventListener("keydown", e => { - if (e.key === "Enter") { - if (input.value === "") { - alert("값을 입력해주세요 !"); - } - - const newTodoData = { - text: input.value, - status: status.NEED_TODO, - id: todoIdCount - }; - - todoListData.push(newTodoData); - addTodoList(newTodoData); - renderCount(todoListData); - e.target.value = ""; - } -}); - -// 더블클릭시 edit 모드 -todoList.addEventListener("dblclick", e => { - const label = e.target.childNodes[3]; - const editInput = e.target.nextSibling.nextSibling; - const prevValue = editInput.value; - const id = e.target.parentElement.id.replace(/[^0-9]/g, ""); - - editInput.style.display = "block"; - editInput.addEventListener("keydown", e => { - if (e.keyCode === 27) { - editInput.style.display = "none"; - } - - if (e.keyCode === 13) { - if (prevValue !== editInput.value) { - let i = 0; - while (i < todoListData.length) { - if (todoListData[i].id.toString() === id) { - todoListData[i].text = e.target.value; - label.innerHTML = e.target.value; - break; - } - ++i; - } - } - editInput.style.display = "none"; - } - }); -}); - -// count -const todoCount = document.getElementById("todoCount"); - -const renderCount = todoListData => { - todoCount.innerHTML = `총 ${todoListData.length} 개`; -}; +// 초기값 랜더 +TodoList(todoListData); +TodoInput(todoListData); +TodoCount(todoListData, todoCount); // 선택한 텝에 따라 랜더링 다시하기 'ㅁ' -const tab = document.getElementById("tab"); -tab.addEventListener("click", e => { - const selectedTab = e.target; - const prevSelectedTab = document.querySelector(".selected"); +onSelectTab(todoListData); - prevSelectedTab.classList.remove("selected"); - selectedTab.classList.add("selected"); - let selectedTodoData = []; - - if ( - selectedTab.id === status.COMPLETED || - selectedTab.id === status.NEED_TODO - ) { - for (let i = 0; i < todoListData.length; ++i) { - if (todoListData[i].status === selectedTab.id) { - selectedTodoData.push(todoListData[i]); - } - } - renderTodoList(selectedTodoData); - } else { - renderTodoList(todoListData); - } -}); - -// 초기값 랜더 -renderCount(todoListData); -renderTodoList(todoListData); diff --git a/mission001/jisun/js/components/TodoCount.js b/mission001/jisun/js/components/TodoCount.js index e69de29..385e1dc 100644 --- a/mission001/jisun/js/components/TodoCount.js +++ b/mission001/jisun/js/components/TodoCount.js @@ -0,0 +1,9 @@ +const todoCount = document.getElementById("todoCount"); + +export function TodoCount (data) { + renderCount(data, todoCount); +} + +export const renderCount = (data, selector) => { + selector.innerHTML = `총 ${data.length} 개`; +} \ No newline at end of file diff --git a/mission001/jisun/js/components/TodoInput.js b/mission001/jisun/js/components/TodoInput.js index e69de29..7d35f71 100644 --- a/mission001/jisun/js/components/TodoInput.js +++ b/mission001/jisun/js/components/TodoInput.js @@ -0,0 +1,26 @@ +import { status, todoIdCount } from '../store/store.js'; +import { addTodoList } from './TodoList.js'; +import { TodoCount } from './TodoCount.js'; + +const input = document.getElementById("inputTodo"); + +export function TodoInput (data) { + input.addEventListener("keydown", e => { + if (e.key === "Enter") { + if (input.value === "") { + alert("값을 입력해주세요 !"); + } + + const newTodoData = { + text: input.value, + status: status.NEED_TODO, + id: todoIdCount + }; + + data.push(newTodoData); + addTodoList(newTodoData); + TodoCount(data); + e.target.value = ""; + } + }); +} diff --git a/mission001/jisun/js/components/TodoList.js b/mission001/jisun/js/components/TodoList.js index e69de29..45c7cb4 100644 --- a/mission001/jisun/js/components/TodoList.js +++ b/mission001/jisun/js/components/TodoList.js @@ -0,0 +1,135 @@ +import { status, todoIdCount, setTodoIdCount, todoListData } from '../store/store.js'; +import { TodoCount } from './TodoCount.js'; + +const todoList = document.getElementById("todoList"); + +export function TodoList (data) { + renderTodoList(data); + onEditMode(data); +} + +// 초기 데이터에 따라 todoList render +export const renderTodoList = (list) => { + todoList.innerHTML = ''; + + if (list.length === 0) { + todoList.innerHTML = `
      • Todo List가 비어있습니다
      • `; + } else { + list.forEach(data => { + todoList.innerHTML += ` +
        + + + +
        + + `; + }); + } + + const toggles = document.getElementsByClassName("toggle"); + const deleteBtns = document.getElementsByClassName("destroy"); + + for (let i = 0; i < toggles.length; ++i) { + toggles[i].addEventListener("change", e => { + onComplete(e); + }); + } + + for (let i = 0; i < deleteBtns.length; ++i) { + deleteBtns[i].addEventListener("click", e => { + deleteTodoList(e, list); + }); + } +}; + +// TodoList에 new data 추가 +export const addTodoList = data => { + const list = document.createElement("li"); + list.id = `todo-${data.id}`; + todoList.appendChild(list); + + list.innerHTML = `
        + + + +
        + `; + + const checkbox = list.firstChild.childNodes[1]; + const deleteBtn = list.firstChild.childNodes[5]; + + setTodoIdCount(todoIdCount + 1); + console.log(todoListData) + + checkbox.addEventListener("change", e => { + onComplete(e); + }); + + deleteBtn.addEventListener("click", (e, data) => { + deleteTodoList(e, data); + }); +}; + +export const onComplete = e => { + const list = e.target.parentElement.parentElement; + + if (e.target.checked) { + list.classList.add("completed"); + } else { + list.classList.remove("completed"); + } +}; + + +// TodoList의 data 제거 +export const deleteTodoList = (e, data) => { + const list = e.target.parentElement.parentElement; + console.log(list.id); + const id = list.id.replace(/[^0-9]/g, ""); + todoList.removeChild(list); + + for (let i = 0; i < data.length; ++i) { + if (data[i].id.toString() === id) { + data.splice(i, 1); + } + } + + TodoCount(data); +}; + +const onEditMode = (data) => { + // 더블클릭시 edit 모드 + todoList.addEventListener("dblclick", e => { + const label = e.target.childNodes[3]; + const editInput = e.target.nextSibling.nextSibling; + const prevValue = editInput.value; + const id = e.target.parentElement.id.replace(/[^0-9]/g, ""); + + editInput.style.display = "block"; + editInput.addEventListener("keydown", e => { + if (e.keyCode === 27) { + editInput.style.display = "none"; + } + + if (e.keyCode === 13) { + if (prevValue !== editInput.value) { + let i = 0; + while (i < data.length) { + if (data[i].id.toString() === id) { + data[i].text = e.target.value; + label.innerHTML = e.target.value; + break; + } + ++i; + } + } + editInput.style.display = "none"; + } + }); + }); +} \ No newline at end of file diff --git a/mission001/jisun/js/components/index.js b/mission001/jisun/js/components/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/mission001/jisun/js/store/store.js b/mission001/jisun/js/store/store.js index e7b04b5..fa77e96 100644 --- a/mission001/jisun/js/store/store.js +++ b/mission001/jisun/js/store/store.js @@ -1,11 +1,23 @@ -export let initData = [ +export const status = { + COMPLETED: "completed", + PROCEEDING: "proceeding", + NEED_TODO: "needTodo" +}; + +export let todoListData = [ { text: "AAAAA", status: status.COMPLETED, id: 1 }, { text: "BBBBB", status: status.PROCEEDING, id: 2 }, { text: "DDDDD", status: status.NEED_TODO, id: 3 } ]; -export const setData = newData => { - initData = newData; +export const setData = value => { + todoListData = value; console.log("set data: "); - console.log(initData); + console.log(todoListData); }; + +export let todoIdCount = todoListData.length + 1; + +export const setTodoIdCount = value => { + todoIdCount = value; +} \ No newline at end of file diff --git a/mission001/jisun/js/util/utils.js b/mission001/jisun/js/util/utils.js new file mode 100644 index 0000000..0aaa0a7 --- /dev/null +++ b/mission001/jisun/js/util/utils.js @@ -0,0 +1,30 @@ +import { status } from '../store/store.js'; +import { renderTodoList } from '../components/TodoList.js'; + +export const onSelectTab = (data) => { + const tab = document.getElementById("tab"); + + tab.addEventListener("click", e => { + const selectedTab = e.target; + const prevSelectedTab = document.querySelector(".selected"); + + prevSelectedTab.classList.remove("selected"); + selectedTab.classList.add("selected"); + + let selectedTodoData = []; + + if ( + selectedTab.id === status.COMPLETED || + selectedTab.id === status.NEED_TODO + ) { + for (let i = 0; i < data.length; ++i) { + if (data[i].status === selectedTab.id) { + selectedTodoData.push(data[i]); + } + } + renderTodoList(selectedTodoData); + } else { + renderTodoList(data); + } + }); +} \ No newline at end of file From f01ba614182d29601a83f83de531463f4edc4516 Mon Sep 17 00:00:00 2001 From: "cien.lee" Date: Mon, 23 Dec 2019 10:21:00 +0900 Subject: [PATCH 08/12] =?UTF-8?q?=EC=BD=94=EB=93=9C=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20-=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EC=8B=9C=20new=EB=A1=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/index.html | 26 ----- mission001/jisun/js/app.js | 23 +++-- mission001/jisun/js/components/TodoCount.js | 13 ++- mission001/jisun/js/components/TodoInput.js | 57 ++++++---- mission001/jisun/js/components/TodoList.js | 109 +++++++++++--------- 5 files changed, 120 insertions(+), 108 deletions(-) diff --git a/mission001/jisun/index.html b/mission001/jisun/index.html index 84930c0..4a5df91 100644 --- a/mission001/jisun/index.html +++ b/mission001/jisun/index.html @@ -20,32 +20,6 @@
          -
          diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index c458366..5ed4cb7 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -1,15 +1,18 @@ -import { todoListData, todoIdCount } from './store/store.js'; -import { TodoList } from './components/TodoList.js'; -import { TodoInput } from './components/TodoInput.js'; -import { TodoCount } from './components/TodoCount.js'; -import { onSelectTab } from './util/utils.js'; +import { todoListData, todoIdCount } from "./store/store.js"; +import { TodoList } from "./components/TodoList.js"; +import { TodoInput } from "./components/TodoInput.js"; +import { TodoCount } from "./components/TodoCount.js"; +import { onSelectTab } from "./util/utils.js"; // 초기값 랜더 -TodoList(todoListData); -TodoInput(todoListData); -TodoCount(todoListData, todoCount); +const todoList = new TodoList(todoListData); +todoList.setState(todoListData); -// 선택한 텝에 따라 랜더링 다시하기 'ㅁ' -onSelectTab(todoListData); +const todoInput = new TodoInput(todoListData); +todoInput.setState(todoListData); +const todoCount = new TodoCount(todoListData); +todoCount.setState(todoListData); +// 선택한 텝에 따라 랜더링 다시하기 +onSelectTab(todoListData); diff --git a/mission001/jisun/js/components/TodoCount.js b/mission001/jisun/js/components/TodoCount.js index 385e1dc..c483657 100644 --- a/mission001/jisun/js/components/TodoCount.js +++ b/mission001/jisun/js/components/TodoCount.js @@ -1,9 +1,12 @@ const todoCount = document.getElementById("todoCount"); -export function TodoCount (data) { - renderCount(data, todoCount); +export function TodoCount(data) { + this.setState = nextData => { + data = nextData; + render(data); + }; } -export const renderCount = (data, selector) => { - selector.innerHTML = `총 ${data.length} 개`; -} \ No newline at end of file +const render = data => { + todoCount.innerHTML = `총 ${data.length} 개`; +}; diff --git a/mission001/jisun/js/components/TodoInput.js b/mission001/jisun/js/components/TodoInput.js index 7d35f71..8c9d659 100644 --- a/mission001/jisun/js/components/TodoInput.js +++ b/mission001/jisun/js/components/TodoInput.js @@ -1,26 +1,41 @@ -import { status, todoIdCount } from '../store/store.js'; -import { addTodoList } from './TodoList.js'; -import { TodoCount } from './TodoCount.js'; +import { status, todoIdCount } from "../store/store.js"; +import { addTodoList } from "./TodoList.js"; +import { TodoCount } from "./TodoCount.js"; const input = document.getElementById("inputTodo"); -export function TodoInput (data) { +export function TodoInput(data) { + this.setState = nextData => { + data = nextData; + render(data); + }; +} + +const render = data => { input.addEventListener("keydown", e => { - if (e.key === "Enter") { - if (input.value === "") { - alert("값을 입력해주세요 !"); - } - - const newTodoData = { - text: input.value, - status: status.NEED_TODO, - id: todoIdCount - }; - - data.push(newTodoData); - addTodoList(newTodoData); - TodoCount(data); - e.target.value = ""; - } + onAddData(e, data); }); -} +}; + +const onAddData = (e, data) => { + if (e.keyCode === 13) { + if (input.value === "") { + alert("값을 입력해주세요 !"); + return; + } + + const newTodoData = { + text: input.value, + status: status.NEED_TODO, + id: todoIdCount + }; + + data.push(newTodoData); + addTodoList(newTodoData); + + const todoCount = new TodoCount(data); + todoCount.setState(data); + + e.target.value = ""; + } +}; diff --git a/mission001/jisun/js/components/TodoList.js b/mission001/jisun/js/components/TodoList.js index 45c7cb4..9c46672 100644 --- a/mission001/jisun/js/components/TodoList.js +++ b/mission001/jisun/js/components/TodoList.js @@ -1,16 +1,24 @@ -import { status, todoIdCount, setTodoIdCount, todoListData } from '../store/store.js'; -import { TodoCount } from './TodoCount.js'; +import { + status, + todoIdCount, + setTodoIdCount, + todoListData +} from "../store/store.js"; +import { TodoCount } from "./TodoCount.js"; const todoList = document.getElementById("todoList"); -export function TodoList (data) { - renderTodoList(data); - onEditMode(data); +export function TodoList(data) { + this.setState = nextData => { + data = nextData; + renderTodoList(data); + onEditMode(data); + }; } // 초기 데이터에 따라 todoList render -export const renderTodoList = (list) => { - todoList.innerHTML = ''; +export const renderTodoList = list => { + todoList.innerHTML = ""; if (list.length === 0) { todoList.innerHTML = `
        • Todo List가 비어있습니다
        • `; @@ -41,7 +49,7 @@ export const renderTodoList = (list) => { for (let i = 0; i < deleteBtns.length; ++i) { deleteBtns[i].addEventListener("click", e => { - deleteTodoList(e, list); + deleteTodoList(e); }); } }; @@ -64,14 +72,14 @@ export const addTodoList = data => { const deleteBtn = list.firstChild.childNodes[5]; setTodoIdCount(todoIdCount + 1); - console.log(todoListData) + console.log(todoListData); checkbox.addEventListener("change", e => { onComplete(e); }); deleteBtn.addEventListener("click", (e, data) => { - deleteTodoList(e, data); + deleteTodoList(e); }); }; @@ -85,51 +93,60 @@ export const onComplete = e => { } }; - // TodoList의 data 제거 -export const deleteTodoList = (e, data) => { +export const deleteTodoList = e => { const list = e.target.parentElement.parentElement; - console.log(list.id); + const id = list.id.replace(/[^0-9]/g, ""); - todoList.removeChild(list); - - for (let i = 0; i < data.length; ++i) { - if (data[i].id.toString() === id) { - data.splice(i, 1); + + for (let i = 0; i < todoListData.length; ++i) { + if (todoListData[i].id.toString() === id) { + todoListData.splice(i, 1); } } - TodoCount(data); + todoList.removeChild(list); + + const todoCount = new TodoCount(todoListData); + todoCount.setState(todoListData); }; -const onEditMode = (data) => { - // 더블클릭시 edit 모드 - todoList.addEventListener("dblclick", e => { - const label = e.target.childNodes[3]; - const editInput = e.target.nextSibling.nextSibling; - const prevValue = editInput.value; - const id = e.target.parentElement.id.replace(/[^0-9]/g, ""); - - editInput.style.display = "block"; - editInput.addEventListener("keydown", e => { - if (e.keyCode === 27) { - editInput.style.display = "none"; - } - - if (e.keyCode === 13) { - if (prevValue !== editInput.value) { - let i = 0; - while (i < data.length) { - if (data[i].id.toString() === id) { - data[i].text = e.target.value; - label.innerHTML = e.target.value; - break; +// 더블클릭시 edit 모드 +const onEditMode = data => { + let clickCount = 0; + + todoList.addEventListener("click", e => { + clickCount++; + if (clickCount === 2) { + const label = e.target.childNodes[3]; + const editInput = e.target.nextSibling.nextSibling; + const prevValue = editInput.value; + const id = e.target.parentElement.id.replace(/[^0-9]/g, ""); + + editInput.style.display = "block"; + editInput.addEventListener("keydown", e => { + if (e.keyCode === 27) { + editInput.style.display = "none"; + } + + if (e.keyCode === 13) { + if (prevValue !== editInput.value) { + let i = 0; + while (i < data.length) { + if (data[i].id.toString() === id) { + data[i].text = e.target.value; + label.innerHTML = e.target.value; + break; + } + ++i; } - ++i; } + editInput.style.display = "none"; } - editInput.style.display = "none"; - } - }); + }); + } + setTimeout(() => { + clickCount = 0; + }, 200); }); -} \ No newline at end of file +}; From 4bbc8d0bbfb979cb62edbeebe7a340e8518c76be Mon Sep 17 00:00:00 2001 From: blog Date: Wed, 25 Dec 2019 21:48:25 +0900 Subject: [PATCH 09/12] =?UTF-8?q?get,=20post,=20delete=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/js/api/api.js | 38 +++++++++++++++++++++ mission001/jisun/js/app.js | 6 ++++ mission001/jisun/js/components/TodoInput.js | 9 ++--- mission001/jisun/js/components/TodoList.js | 38 +++++++++++---------- mission001/jisun/js/store/store.js | 37 ++++++++++++-------- mission001/jisun/js/util/utils.js | 5 ++- 6 files changed, 91 insertions(+), 42 deletions(-) create mode 100644 mission001/jisun/js/api/api.js diff --git a/mission001/jisun/js/api/api.js b/mission001/jisun/js/api/api.js new file mode 100644 index 0000000..7dc13d7 --- /dev/null +++ b/mission001/jisun/js/api/api.js @@ -0,0 +1,38 @@ + +const URL = 'http://todo-api.roto.codes'; + +export let isLoading = true; + +export const getData = async (username) => { + return await fetch(`${URL}/${username}`); + // return await fetch(`${URL}/${username}`).then(function(res) { + // isLoading = false; + // console.log(JSON.stringify(res)) + // }); +}; + +export const putData = async (username, id) => { + await fetch(`${URL}/${username}/${id}/toggle`, { + + + method: 'PUT', + }) +}; + +export const deleteData = async (username, id) => { + await fetch(`${URL}/${username}/${id}`, { + method: 'DELETE', + }) +}; + +export const postData = async (username, data) => { + await fetch(`${URL}/${username}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + content: data, + }), + }) +}; \ No newline at end of file diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index 5ed4cb7..e149e85 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -3,7 +3,12 @@ import { TodoList } from "./components/TodoList.js"; import { TodoInput } from "./components/TodoInput.js"; import { TodoCount } from "./components/TodoCount.js"; import { onSelectTab } from "./util/utils.js"; +import { getTodoListData } from './store/store.js'; +// 데이터 로드 +getTodoListData(); + +setTimeout(() => { // 초기값 랜더 const todoList = new TodoList(todoListData); todoList.setState(todoListData); @@ -13,6 +18,7 @@ todoInput.setState(todoListData); const todoCount = new TodoCount(todoListData); todoCount.setState(todoListData); +}, 2000) // 선택한 텝에 따라 랜더링 다시하기 onSelectTab(todoListData); diff --git a/mission001/jisun/js/components/TodoInput.js b/mission001/jisun/js/components/TodoInput.js index 8c9d659..fcf40ff 100644 --- a/mission001/jisun/js/components/TodoInput.js +++ b/mission001/jisun/js/components/TodoInput.js @@ -1,4 +1,4 @@ -import { status, todoIdCount } from "../store/store.js"; +import { todoIdCount } from "../store/store.js"; import { addTodoList } from "./TodoList.js"; import { TodoCount } from "./TodoCount.js"; @@ -24,13 +24,8 @@ const onAddData = (e, data) => { return; } - const newTodoData = { - text: input.value, - status: status.NEED_TODO, - id: todoIdCount - }; + const newTodoData = input.value; - data.push(newTodoData); addTodoList(newTodoData); const todoCount = new TodoCount(data); diff --git a/mission001/jisun/js/components/TodoList.js b/mission001/jisun/js/components/TodoList.js index 9c46672..1fb3851 100644 --- a/mission001/jisun/js/components/TodoList.js +++ b/mission001/jisun/js/components/TodoList.js @@ -1,6 +1,7 @@ import { - status, todoIdCount, + setTodoData, + deleteTodoData, setTodoIdCount, todoListData } from "../store/store.js"; @@ -25,15 +26,14 @@ export const renderTodoList = list => { } else { list.forEach(data => { todoList.innerHTML += ` + data.isCompleted ? ` class="completed"` : `` + } id="${data._id}">
          - - + +
          - + `; }); } @@ -57,20 +57,20 @@ export const renderTodoList = list => { // TodoList에 new data 추가 export const addTodoList = data => { const list = document.createElement("li"); - list.id = `todo-${data.id}`; + list.id = `${data._id}`; todoList.appendChild(list); list.innerHTML = `
          - - + +
          - `; + `; const checkbox = list.firstChild.childNodes[1]; const deleteBtn = list.firstChild.childNodes[5]; + setTodoData(data); setTodoIdCount(todoIdCount + 1); console.log(todoListData); @@ -78,7 +78,7 @@ export const addTodoList = data => { onComplete(e); }); - deleteBtn.addEventListener("click", (e, data) => { + deleteBtn.addEventListener("click", (e) => { deleteTodoList(e); }); }; @@ -96,15 +96,17 @@ export const onComplete = e => { // TodoList의 data 제거 export const deleteTodoList = e => { const list = e.target.parentElement.parentElement; + const id = list.id; - const id = list.id.replace(/[^0-9]/g, ""); - + deleteTodoData(id); + for (let i = 0; i < todoListData.length; ++i) { - if (todoListData[i].id.toString() === id) { + if (todoListData[i]._id.toString() === id) { todoListData.splice(i, 1); } } + todoList.removeChild(list); const todoCount = new TodoCount(todoListData); @@ -133,8 +135,8 @@ const onEditMode = data => { if (prevValue !== editInput.value) { let i = 0; while (i < data.length) { - if (data[i].id.toString() === id) { - data[i].text = e.target.value; + if (data[i]._id.toString() === id) { + data[i].content = e.target.value; label.innerHTML = e.target.value; break; } diff --git a/mission001/jisun/js/store/store.js b/mission001/jisun/js/store/store.js index fa77e96..fcabcb6 100644 --- a/mission001/jisun/js/store/store.js +++ b/mission001/jisun/js/store/store.js @@ -1,23 +1,32 @@ -export const status = { - COMPLETED: "completed", - PROCEEDING: "proceeding", - NEED_TODO: "needTodo" +import { getData, postData, deleteData } from '../api/api.js'; + +const username = 'jisun'; + +export let todoListData = []; + +export async function fetchData() { + const res = await getData(username); + return await res.json(); }; -export let todoListData = [ - { text: "AAAAA", status: status.COMPLETED, id: 1 }, - { text: "BBBBB", status: status.PROCEEDING, id: 2 }, - { text: "DDDDD", status: status.NEED_TODO, id: 3 } -]; +export async function getTodoListData() { + todoListData = await fetchData(); +}; -export const setData = value => { - todoListData = value; - console.log("set data: "); - console.log(todoListData); +export async function setTodoData(data) { + await postData(username, data); + getTodoListData(); + console.log('추가후: ' + todoListData); }; +export async function deleteTodoData(id) { + await deleteData(username, id); + getTodoListData(); + console.log('삭제후: ' + todoListData); +} + export let todoIdCount = todoListData.length + 1; export const setTodoIdCount = value => { todoIdCount = value; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/mission001/jisun/js/util/utils.js b/mission001/jisun/js/util/utils.js index 0aaa0a7..5d6a46c 100644 --- a/mission001/jisun/js/util/utils.js +++ b/mission001/jisun/js/util/utils.js @@ -1,4 +1,3 @@ -import { status } from '../store/store.js'; import { renderTodoList } from '../components/TodoList.js'; export const onSelectTab = (data) => { @@ -14,8 +13,8 @@ export const onSelectTab = (data) => { let selectedTodoData = []; if ( - selectedTab.id === status.COMPLETED || - selectedTab.id === status.NEED_TODO + selectedTab.id === 'completed' || + selectedTab.id === 'needTodo' ) { for (let i = 0; i < data.length; ++i) { if (data[i].status === selectedTab.id) { From 5b92667088e855cf044cc0f1623721d70c3b18af Mon Sep 17 00:00:00 2001 From: blog Date: Thu, 26 Dec 2019 00:57:34 +0900 Subject: [PATCH 10/12] =?UTF-8?q?toggle=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/jisun/js/api/api.js | 8 +-- mission001/jisun/js/app.js | 29 ++++----- mission001/jisun/js/components/TodoInput.js | 1 - mission001/jisun/js/components/TodoList.js | 68 +++++++-------------- mission001/jisun/js/components/TodoTab.js | 16 +++++ mission001/jisun/js/store/store.js | 30 +++++---- mission001/jisun/js/util/utils.js | 14 +++-- 7 files changed, 79 insertions(+), 87 deletions(-) create mode 100644 mission001/jisun/js/components/TodoTab.js diff --git a/mission001/jisun/js/api/api.js b/mission001/jisun/js/api/api.js index 7dc13d7..374d8d7 100644 --- a/mission001/jisun/js/api/api.js +++ b/mission001/jisun/js/api/api.js @@ -5,17 +5,13 @@ export let isLoading = true; export const getData = async (username) => { return await fetch(`${URL}/${username}`); - // return await fetch(`${URL}/${username}`).then(function(res) { - // isLoading = false; - // console.log(JSON.stringify(res)) - // }); }; export const putData = async (username, id) => { await fetch(`${URL}/${username}/${id}/toggle`, { - - method: 'PUT', + }).then(() => { + }) }; diff --git a/mission001/jisun/js/app.js b/mission001/jisun/js/app.js index e149e85..24aa026 100644 --- a/mission001/jisun/js/app.js +++ b/mission001/jisun/js/app.js @@ -1,24 +1,21 @@ -import { todoListData, todoIdCount } from "./store/store.js"; +import { todoListData } from "./store/store.js"; import { TodoList } from "./components/TodoList.js"; import { TodoInput } from "./components/TodoInput.js"; import { TodoCount } from "./components/TodoCount.js"; -import { onSelectTab } from "./util/utils.js"; +import { TodoTab } from "./components/TodoTab.js"; import { getTodoListData } from './store/store.js'; -// 데이터 로드 -getTodoListData(); +// 데이터 로드, 컴포넌트 랜더링 +getTodoListData(() => { + const todoList = new TodoList(todoListData); + todoList.setState(todoListData); -setTimeout(() => { -// 초기값 랜더 -const todoList = new TodoList(todoListData); -todoList.setState(todoListData); + const todoInput = new TodoInput(todoListData); + todoInput.setState(todoListData); -const todoInput = new TodoInput(todoListData); -todoInput.setState(todoListData); + const todoCount = new TodoCount(todoListData); + todoCount.setState(todoListData); -const todoCount = new TodoCount(todoListData); -todoCount.setState(todoListData); -}, 2000) - -// 선택한 텝에 따라 랜더링 다시하기 -onSelectTab(todoListData); + const todoTab = new TodoTab(todoListData); + todoTab.setState(todoListData); +}); diff --git a/mission001/jisun/js/components/TodoInput.js b/mission001/jisun/js/components/TodoInput.js index fcf40ff..11764e5 100644 --- a/mission001/jisun/js/components/TodoInput.js +++ b/mission001/jisun/js/components/TodoInput.js @@ -1,4 +1,3 @@ -import { todoIdCount } from "../store/store.js"; import { addTodoList } from "./TodoList.js"; import { TodoCount } from "./TodoCount.js"; diff --git a/mission001/jisun/js/components/TodoList.js b/mission001/jisun/js/components/TodoList.js index 1fb3851..6155140 100644 --- a/mission001/jisun/js/components/TodoList.js +++ b/mission001/jisun/js/components/TodoList.js @@ -1,8 +1,7 @@ import { - todoIdCount, setTodoData, deleteTodoData, - setTodoIdCount, + editTodoData, todoListData } from "../store/store.js"; import { TodoCount } from "./TodoCount.js"; @@ -56,61 +55,38 @@ export const renderTodoList = list => { // TodoList에 new data 추가 export const addTodoList = data => { - const list = document.createElement("li"); - list.id = `${data._id}`; - todoList.appendChild(list); - - list.innerHTML = `
          - - - -
          - `; - - const checkbox = list.firstChild.childNodes[1]; - const deleteBtn = list.firstChild.childNodes[5]; - - setTodoData(data); - setTodoIdCount(todoIdCount + 1); - console.log(todoListData); - - checkbox.addEventListener("change", e => { - onComplete(e); - }); + setTodoData(data, () => { + const todoList = new TodoList(todoListData); + todoList.setState(todoListData); - deleteBtn.addEventListener("click", (e) => { - deleteTodoList(e); + const todoCount = new TodoCount(todoListData); + todoCount.setState(todoListData); }); }; export const onComplete = e => { const list = e.target.parentElement.parentElement; - - if (e.target.checked) { - list.classList.add("completed"); - } else { - list.classList.remove("completed"); - } + const id = list.id; + editTodoData(id, () => { + if (e.target.checked) { + list.classList.add("completed"); + } else { + list.classList.remove("completed"); + } + }); }; // TodoList의 data 제거 export const deleteTodoList = e => { - const list = e.target.parentElement.parentElement; - const id = list.id; - - deleteTodoData(id); - - for (let i = 0; i < todoListData.length; ++i) { - if (todoListData[i]._id.toString() === id) { - todoListData.splice(i, 1); - } - } + const id = e.target.parentElement.parentElement.id; - - todoList.removeChild(list); + deleteTodoData(id, () => { + const todoList = new TodoList(todoListData); + todoList.setState(todoListData); - const todoCount = new TodoCount(todoListData); - todoCount.setState(todoListData); + const todoCount = new TodoCount(todoListData); + todoCount.setState(todoListData); + }); }; // 더블클릭시 edit 모드 @@ -123,7 +99,7 @@ const onEditMode = data => { const label = e.target.childNodes[3]; const editInput = e.target.nextSibling.nextSibling; const prevValue = editInput.value; - const id = e.target.parentElement.id.replace(/[^0-9]/g, ""); + const id = e.target.parentElement.id; editInput.style.display = "block"; editInput.addEventListener("keydown", e => { diff --git a/mission001/jisun/js/components/TodoTab.js b/mission001/jisun/js/components/TodoTab.js new file mode 100644 index 0000000..39d0ed9 --- /dev/null +++ b/mission001/jisun/js/components/TodoTab.js @@ -0,0 +1,16 @@ +import { onSelectTab } from "../util/utils.js"; + +const tab = document.getElementById("tab"); + +export function TodoTab(data) { + this.setState = nextData => { + data = nextData; + render(data); + }; +} + +const render = data => { + tab.addEventListener("click", () => { + onSelectTab(data); + }); +}; diff --git a/mission001/jisun/js/store/store.js b/mission001/jisun/js/store/store.js index fcabcb6..fdd9ca2 100644 --- a/mission001/jisun/js/store/store.js +++ b/mission001/jisun/js/store/store.js @@ -1,4 +1,4 @@ -import { getData, postData, deleteData } from '../api/api.js'; +import { getData, postData, deleteData, putData } from '../api/api.js'; const username = 'jisun'; @@ -9,24 +9,28 @@ export async function fetchData() { return await res.json(); }; -export async function getTodoListData() { +export async function getTodoListData(callback) { todoListData = await fetchData(); + callback(); }; -export async function setTodoData(data) { +export async function setTodoData(data, callback) { await postData(username, data); - getTodoListData(); - console.log('추가후: ' + todoListData); + getTodoListData(() => { + callback(); + }); }; -export async function deleteTodoData(id) { +export async function deleteTodoData(id, callback) { await deleteData(username, id); - getTodoListData(); - console.log('삭제후: ' + todoListData); + getTodoListData(() => { + callback(); + }); } -export let todoIdCount = todoListData.length + 1; - -export const setTodoIdCount = value => { - todoIdCount = value; -}; \ No newline at end of file +export async function editTodoData(id, callback) { + await putData(username, id); + getTodoListData(() => { + callback(); + }); +} diff --git a/mission001/jisun/js/util/utils.js b/mission001/jisun/js/util/utils.js index 5d6a46c..f7a5d2a 100644 --- a/mission001/jisun/js/util/utils.js +++ b/mission001/jisun/js/util/utils.js @@ -12,12 +12,16 @@ export const onSelectTab = (data) => { let selectedTodoData = []; - if ( - selectedTab.id === 'completed' || - selectedTab.id === 'needTodo' - ) { + if (selectedTab.id === 'completed') { for (let i = 0; i < data.length; ++i) { - if (data[i].status === selectedTab.id) { + if (data[i].isCompleted) { + selectedTodoData.push(data[i]); + } + } + renderTodoList(selectedTodoData); + } else if (selectedTab.id === 'needTodo') { + for (let i = 0; i < data.length; ++i) { + if (!data[i].isCompleted) { selectedTodoData.push(data[i]); } } From f922dc48266c7986d789b2de4a929ba88005d078 Mon Sep 17 00:00:00 2001 From: "cien.lee" Date: Fri, 27 Dec 2019 08:58:38 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {mission001 => mission002}/jisun/css/style.css | 0 {mission001 => mission002}/jisun/index.html | 0 {mission001 => mission002}/jisun/js/api/api.js | 0 {mission001 => mission002}/jisun/js/app.js | 0 {mission001 => mission002}/jisun/js/components/TodoCount.js | 0 {mission001 => mission002}/jisun/js/components/TodoInput.js | 0 {mission001 => mission002}/jisun/js/components/TodoList.js | 0 {mission001 => mission002}/jisun/js/components/TodoTab.js | 0 {mission001 => mission002}/jisun/js/store/store.js | 0 {mission001 => mission002}/jisun/js/util/utils.js | 0 {mission001 => mission002}/jisun/package-lock.json | 0 {mission001 => mission002}/jisun/package.json | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename {mission001 => mission002}/jisun/css/style.css (100%) rename {mission001 => mission002}/jisun/index.html (100%) rename {mission001 => mission002}/jisun/js/api/api.js (100%) rename {mission001 => mission002}/jisun/js/app.js (100%) rename {mission001 => mission002}/jisun/js/components/TodoCount.js (100%) rename {mission001 => mission002}/jisun/js/components/TodoInput.js (100%) rename {mission001 => mission002}/jisun/js/components/TodoList.js (100%) rename {mission001 => mission002}/jisun/js/components/TodoTab.js (100%) rename {mission001 => mission002}/jisun/js/store/store.js (100%) rename {mission001 => mission002}/jisun/js/util/utils.js (100%) rename {mission001 => mission002}/jisun/package-lock.json (100%) rename {mission001 => mission002}/jisun/package.json (100%) diff --git a/mission001/jisun/css/style.css b/mission002/jisun/css/style.css similarity index 100% rename from mission001/jisun/css/style.css rename to mission002/jisun/css/style.css diff --git a/mission001/jisun/index.html b/mission002/jisun/index.html similarity index 100% rename from mission001/jisun/index.html rename to mission002/jisun/index.html diff --git a/mission001/jisun/js/api/api.js b/mission002/jisun/js/api/api.js similarity index 100% rename from mission001/jisun/js/api/api.js rename to mission002/jisun/js/api/api.js diff --git a/mission001/jisun/js/app.js b/mission002/jisun/js/app.js similarity index 100% rename from mission001/jisun/js/app.js rename to mission002/jisun/js/app.js diff --git a/mission001/jisun/js/components/TodoCount.js b/mission002/jisun/js/components/TodoCount.js similarity index 100% rename from mission001/jisun/js/components/TodoCount.js rename to mission002/jisun/js/components/TodoCount.js diff --git a/mission001/jisun/js/components/TodoInput.js b/mission002/jisun/js/components/TodoInput.js similarity index 100% rename from mission001/jisun/js/components/TodoInput.js rename to mission002/jisun/js/components/TodoInput.js diff --git a/mission001/jisun/js/components/TodoList.js b/mission002/jisun/js/components/TodoList.js similarity index 100% rename from mission001/jisun/js/components/TodoList.js rename to mission002/jisun/js/components/TodoList.js diff --git a/mission001/jisun/js/components/TodoTab.js b/mission002/jisun/js/components/TodoTab.js similarity index 100% rename from mission001/jisun/js/components/TodoTab.js rename to mission002/jisun/js/components/TodoTab.js diff --git a/mission001/jisun/js/store/store.js b/mission002/jisun/js/store/store.js similarity index 100% rename from mission001/jisun/js/store/store.js rename to mission002/jisun/js/store/store.js diff --git a/mission001/jisun/js/util/utils.js b/mission002/jisun/js/util/utils.js similarity index 100% rename from mission001/jisun/js/util/utils.js rename to mission002/jisun/js/util/utils.js diff --git a/mission001/jisun/package-lock.json b/mission002/jisun/package-lock.json similarity index 100% rename from mission001/jisun/package-lock.json rename to mission002/jisun/package-lock.json diff --git a/mission001/jisun/package.json b/mission002/jisun/package.json similarity index 100% rename from mission001/jisun/package.json rename to mission002/jisun/package.json From 023e375892419dada840d67d2ac6ad221b0c5afa Mon Sep 17 00:00:00 2001 From: "cien.lee" Date: Tue, 7 Jan 2020 17:49:03 +0900 Subject: [PATCH 12/12] =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission002/jisun/js/api/api.js | 27 ++++++++++------------ mission002/jisun/js/app.js | 3 +-- mission002/jisun/js/components/TodoList.js | 5 ++-- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/mission002/jisun/js/api/api.js b/mission002/jisun/js/api/api.js index 374d8d7..1485d28 100644 --- a/mission002/jisun/js/api/api.js +++ b/mission002/jisun/js/api/api.js @@ -1,34 +1,31 @@ - -const URL = 'http://todo-api.roto.codes'; +const URL = "http://todo-api.roto.codes"; export let isLoading = true; -export const getData = async (username) => { +export const getData = async username => { return await fetch(`${URL}/${username}`); }; export const putData = async (username, id) => { await fetch(`${URL}/${username}/${id}/toggle`, { - method: 'PUT', - }).then(() => { - - }) + method: "PUT" + }); }; export const deleteData = async (username, id) => { await fetch(`${URL}/${username}/${id}`, { - method: 'DELETE', - }) + method: "DELETE" + }); }; export const postData = async (username, data) => { await fetch(`${URL}/${username}`, { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json" }, body: JSON.stringify({ - content: data, - }), - }) -}; \ No newline at end of file + content: data + }) + }); +}; diff --git a/mission002/jisun/js/app.js b/mission002/jisun/js/app.js index 24aa026..64c52da 100644 --- a/mission002/jisun/js/app.js +++ b/mission002/jisun/js/app.js @@ -3,9 +3,8 @@ import { TodoList } from "./components/TodoList.js"; import { TodoInput } from "./components/TodoInput.js"; import { TodoCount } from "./components/TodoCount.js"; import { TodoTab } from "./components/TodoTab.js"; -import { getTodoListData } from './store/store.js'; +import { getTodoListData } from "./store/store.js"; -// 데이터 로드, 컴포넌트 랜더링 getTodoListData(() => { const todoList = new TodoList(todoListData); todoList.setState(todoListData); diff --git a/mission002/jisun/js/components/TodoList.js b/mission002/jisun/js/components/TodoList.js index 6155140..495bbf6 100644 --- a/mission002/jisun/js/components/TodoList.js +++ b/mission002/jisun/js/components/TodoList.js @@ -16,7 +16,6 @@ export function TodoList(data) { }; } -// 초기 데이터에 따라 todoList render export const renderTodoList = list => { todoList.innerHTML = ""; @@ -28,7 +27,9 @@ export const renderTodoList = list => { data.isCompleted ? ` class="completed"` : `` } id="${data._id}">
          - +