From 394196436d49ca3fddf8b07ccbe087d98fd48ef7 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Mon, 16 Dec 2019 16:09:54 +0900 Subject: [PATCH 01/10] =?UTF-8?q?todolist=EC=97=90=20todoitem=EC=9D=84=20?= =?UTF-8?q?=EC=97=94=ED=84=B0=ED=82=A4=EB=A1=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/ganeodolu/css/style.css | 334 +++++++++++++++++++++++++++ mission001/ganeodolu/index.html | 65 ++++++ mission001/ganeodolu/js/App.js | 37 +++ mission001/ganeodolu/js/TodoCount.js | 0 mission001/ganeodolu/js/TodoInput.js | 14 ++ mission001/ganeodolu/js/TodoList.js | 55 +++++ mission001/ganeodolu/js/index.js | 19 ++ 7 files changed, 524 insertions(+) create mode 100644 mission001/ganeodolu/css/style.css create mode 100644 mission001/ganeodolu/index.html create mode 100644 mission001/ganeodolu/js/App.js create mode 100644 mission001/ganeodolu/js/TodoCount.js create mode 100644 mission001/ganeodolu/js/TodoInput.js create mode 100644 mission001/ganeodolu/js/TodoList.js create mode 100644 mission001/ganeodolu/js/index.js diff --git a/mission001/ganeodolu/css/style.css b/mission001/ganeodolu/css/style.css new file mode 100644 index 0000000..14a905e --- /dev/null +++ b/mission001/ganeodolu/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/ganeodolu/index.html b/mission001/ganeodolu/index.html new file mode 100644 index 0000000..d362cce --- /dev/null +++ b/mission001/ganeodolu/index.html @@ -0,0 +1,65 @@ + + + + + + 이벤트 - TODOS + + + +
+
+

TODOS

+ +
+
+ +
    +
  • +
    + +
    + +
  • +
  • +
    + + + +
    + +
  • +
  • +
    + + + +
    + +
  • +
+
+
+ 0 + +
+
+ + + + + + + diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js new file mode 100644 index 0000000..ff165a7 --- /dev/null +++ b/mission001/ganeodolu/js/App.js @@ -0,0 +1,37 @@ +function App(data) { + this.data = data; + // console.log(data) + const $todoList = document.querySelector('.view') + const todoList = new TodoList($todoList, this.data, + (index) => { + const nextData = [...this.data] + nextData[index].isComplete = !nextData[index].isComplete + this.setState(nextData) + }, + (index) => { + const nextData = [...this.data] + nextData.splice(index, 1) + this.setState(nextData) + } + ); + + // const $todoCount = document.querySelector('.todo-count'); + // const todoCount = new TodoCount($todoCount, this.data); + const $todoInput = document.querySelector('.new-todo') + const todoInput = new TodoInput($todoInput, (text) => { + this.data.push({ + text: text, // 키,값이 같으므로 text로 생략가능함 + isCompleted: false, + }) + todoList.setState(this.data) + // todoCount.setState(this.data) + + }) + $todoInput.focus() + + this.setState = function (nextData) { + this.data = nextData; + this.todoList.setState(this.data) + // this.todoCount.setState(this.data) + } +} \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js new file mode 100644 index 0000000..e69de29 diff --git a/mission001/ganeodolu/js/TodoInput.js b/mission001/ganeodolu/js/TodoInput.js new file mode 100644 index 0000000..f440d42 --- /dev/null +++ b/mission001/ganeodolu/js/TodoInput.js @@ -0,0 +1,14 @@ +function TodoInput($target, onAdd) { + + // 할일추가버튼 위치 + // const $todoAddBtn = document.getElementById('todo-add-button'); // 할일추가버튼 연결변수 + + // 입력창에서 엔터키 입력시 할일추가 + $target.addEventListener('keyup', (e) => { + const ENTER_KEY_CODE = 13; + if (e.keyCode === ENTER_KEY_CODE) { + onAdd($target.value) + $target.value = ''; // 입력 후 입력란이 공란이 되도록 함 + } + }) +} \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js new file mode 100644 index 0000000..de87c90 --- /dev/null +++ b/mission001/ganeodolu/js/TodoList.js @@ -0,0 +1,55 @@ +function TodoList($target, data, onTodoClick, onRemoveClick){ + this.$target = $target; + this.data = data; + // console.log(data) + this.setState = function (nextData){ + this.data = nextData; + this.render() + } + + if (this === window) { + throw new Error(error.NO_USED_NEW_KEYWORD) + } + else if (Array.isArray(this.data) == false) { + throw new Error(error.NOARRAY_DATA) + } + + this.$target.addEventListener('click', (e) => { + const { className, dataset } = e.target; + console.log(e.target) + console.log(className) + console.log(dataset) + const { index } = dataset; + // console.log(index) + if (className.includes('todo-text')) { + onTodoClick(index) + } else if (className === 'remove') { + onRemoveClick(index) + } + }) + + this.render = function (){ + const INPUT_VIEW = ''; + const BUTTON_VIEW = ''; + // renderHTMLText 변수 안에 data객체안의 text의 value 값에 태그를 붙여서 저장 + const renderHTMLText = this.data.map((val, idx) => { + if (!val.text) { // data.text 값이 있는지 확인 + throw new Error(error.NOT_DATA) + } + // data.text 내용이 문자열이 아닌 경우를 데이터가 이상하다고 가정 + else if (typeof (val.text) != "string") { + throw new Error(error.INVALID_DATA) + } + // // isCompleted 가 참이면 태그를 넣어서 저장(완료되었다는 의미), false면
만 넣어서 저장 + // return val.isCompleted ? `
  • ${val.text}
  • ` : `
  • ${val.text}
  • `; + return `${INPUT_VIEW}${BUTTON_VIEW}`; + }).join(''); + // console.log("renderHTMLText", renderHTMLText); + this.$target.innerHTML = `${renderHTMLText}` + } + + + + this.render() + +} \ No newline at end of file diff --git a/mission001/ganeodolu/js/index.js b/mission001/ganeodolu/js/index.js new file mode 100644 index 0000000..b50f89b --- /dev/null +++ b/mission001/ganeodolu/js/index.js @@ -0,0 +1,19 @@ +const error = { + NO_USED_NEW_KEYWORD: "함수 선언시 new를 사용해주세요.", + NOARRAY_DATA: "data타입이 Array가 아닙니다.", + NOT_DATA: "data가 null 또는 undefined 입니다.", + INVALID_DATA: "data타입이 문자열이 아닙니다.", +}; + +const data = [ + // { + // text: 'JS 공부하기', + // isCompleted : false + // }, + // { + // text: 'JS 복습하기', + // isCompleted: true + // }, +] + +new App(data); \ No newline at end of file From 217a5fcfd9783286a7a1231dc3ed9a0c09ef4937 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Mon, 16 Dec 2019 16:32:28 +0900 Subject: [PATCH 02/10] =?UTF-8?q?M1-1=20todolist=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS형식에 맞게 todolist의 타겟 변경, innerHTML 태그 추가 --- mission001/ganeodolu/js/App.js | 2 +- mission001/ganeodolu/js/TodoList.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index ff165a7..031acb8 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -1,7 +1,7 @@ function App(data) { this.data = data; // console.log(data) - const $todoList = document.querySelector('.view') + const $todoList = document.querySelector('.todo-list') const todoList = new TodoList($todoList, this.data, (index) => { const nextData = [...this.data] diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index de87c90..4af7e23 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -42,7 +42,7 @@ function TodoList($target, data, onTodoClick, onRemoveClick){ } // // isCompleted 가 참이면 태그를 넣어서 저장(완료되었다는 의미), false면
    만 넣어서 저장 // return val.isCompleted ? `
  • ${val.text}
  • ` : `
  • ${val.text}
  • `; - return `${INPUT_VIEW}${BUTTON_VIEW}`; + return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; }).join(''); // console.log("renderHTMLText", renderHTMLText); this.$target.innerHTML = `${renderHTMLText}` From 2521ce99672253d2e4ef4fc41a6839291cc87440 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Wed, 18 Dec 2019 17:16:18 +0900 Subject: [PATCH 03/10] =?UTF-8?q?M1=202~5=20=EA=B8=B0=EB=8A=A5=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2. 토글버튼으로 할일 completed상태변경 3. 삭제버튼으로 할일 삭제 4. 할일 더블클릭시 에디트모드 5. 할일 개수 하단에 표시 --- mission001/ganeodolu/js/App.js | 65 +++++++++++++++++-------- mission001/ganeodolu/js/TodoCount.js | 31 ++++++++++++ mission001/ganeodolu/js/TodoInput.js | 13 ++--- mission001/ganeodolu/js/TodoList.js | 57 +++++++++++++--------- mission001/ganeodolu/js/TodoList.txt | 56 +++++++++++++++++++++ mission001/ganeodolu/js/index.js | 20 +++++--- mission001/origin/.vscode/settings.json | 3 ++ mission001/origin/index.html | 2 +- 8 files changed, 187 insertions(+), 60 deletions(-) create mode 100644 mission001/ganeodolu/js/TodoList.txt create mode 100644 mission001/origin/.vscode/settings.json diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index 031acb8..10b15c4 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -1,37 +1,62 @@ function App(data) { this.data = data; - // console.log(data) + this.setState = function (nextData) { + this.data = nextData; + todoList.setState(this.data) + todoCount.setState({ + totalCount: this.data.length, + completedCount: this.data.filter(todo => todo.isComplete).length + }) + } + const $todoList = document.querySelector('.todo-list') const todoList = new TodoList($todoList, this.data, (index) => { const nextData = [...this.data] - nextData[index].isComplete = !nextData[index].isComplete + nextData[index].isCompleted = !nextData[index].isCompleted + this.setState(nextData) + }, + (index) => { + const nextData = [...this.data] + if (!nextData[index].isCompleted) { + nextData[index].isEditing = nextData[index].isEditing ? false : true; + } this.setState(nextData) }, (index) => { const nextData = [...this.data] nextData.splice(index, 1) this.setState(nextData) - } + }, + (index, value) => { + const nextData = [...this.data] + nextData[index] = { + text: value, + isCompleted: false, + isEditing: false + }; + this.setState(nextData) + }, ); - // const $todoCount = document.querySelector('.todo-count'); - // const todoCount = new TodoCount($todoCount, this.data); - const $todoInput = document.querySelector('.new-todo') - const todoInput = new TodoInput($todoInput, (text) => { - this.data.push({ - text: text, // 키,값이 같으므로 text로 생략가능함 - isCompleted: false, - }) - todoList.setState(this.data) - // todoCount.setState(this.data) - + const $todoCount = document.querySelector('.todo-count'); + const $todoCountFilter = document.querySelector('.filters'); + const todoCount = new TodoCount($todoCount, $todoCountFilter, { + totalCount: this.data.length, + completedCount: this.data.filter(todo => todo.isCompleted).length }) - $todoInput.focus() - this.setState = function (nextData) { - this.data = nextData; - this.todoList.setState(this.data) - // this.todoCount.setState(this.data) - } + const $todoInput = document.querySelector('.new-todo') + const $todoEdit = document.querySelector('.todo-list') + const todoInput = new TodoInput($todoInput, $todoEdit, + (text) => { + const nextData = [...this.data] + nextData.push({ + text: text, + isCompleted: false, + isEditing: false, + }) + this.setState(nextData) + } + ) } \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js index e69de29..5e82095 100644 --- a/mission001/ganeodolu/js/TodoCount.js +++ b/mission001/ganeodolu/js/TodoCount.js @@ -0,0 +1,31 @@ +function TodoCount($targetCount, $targetCountFilter, data) { + this.data = data; + this.$targetCount = $targetCount; + this.$targetCountFilter = $targetCountFilter; + + // 새로운 데이터를 불러서 다시 렌더링하는 setState함수 + this.setState = function (nextData) { + this.data = nextData; + this.render(); + } + // // 상태별 아이템 골라서 보여주기 미구현 + // this.$targetCountFilter.addEventListener('click', (e) => { + // const { className, dataset } = e.target; + // const { index } = dataset + // console.log(e.target) + // if (className === 'all selected') { + // onAllClick() + // } else if (className === 'active') { + // onActiveClick() + // } else if (className === 'completed') { + // onCompletedClick() + // } + // }) + + this.render = function () { + const { totalCount, completedCount } = this.data + $targetCount.innerHTML = `총 ${totalCount}개` + } + this.render(); + +} \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoInput.js b/mission001/ganeodolu/js/TodoInput.js index f440d42..a54cac3 100644 --- a/mission001/ganeodolu/js/TodoInput.js +++ b/mission001/ganeodolu/js/TodoInput.js @@ -1,14 +1,9 @@ -function TodoInput($target, onAdd) { - - // 할일추가버튼 위치 - // const $todoAddBtn = document.getElementById('todo-add-button'); // 할일추가버튼 연결변수 - +function TodoInput($targetInput, $targetEdit, onAdd) { // 입력창에서 엔터키 입력시 할일추가 - $target.addEventListener('keyup', (e) => { - const ENTER_KEY_CODE = 13; + $targetInput.addEventListener('keydown', (e) => { if (e.keyCode === ENTER_KEY_CODE) { - onAdd($target.value) - $target.value = ''; // 입력 후 입력란이 공란이 되도록 함 + onAdd($targetInput.value) + $targetInput.value = ''; // 입력 후 입력란이 공란이 되도록 함 } }) } \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index 4af7e23..736eda2 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -1,8 +1,8 @@ -function TodoList($target, data, onTodoClick, onRemoveClick){ +function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange) { this.$target = $target; this.data = data; - // console.log(data) - this.setState = function (nextData){ + + this.setState = function (nextData) { this.data = nextData; this.render() } @@ -13,26 +13,45 @@ function TodoList($target, data, onTodoClick, onRemoveClick){ else if (Array.isArray(this.data) == false) { throw new Error(error.NOARRAY_DATA) } - + // 토글버튼과 삭제버튼 기능구현 this.$target.addEventListener('click', (e) => { const { className, dataset } = e.target; - console.log(e.target) - console.log(className) - console.log(dataset) - const { index } = dataset; - // console.log(index) - if (className.includes('todo-text')) { - onTodoClick(index) - } else if (className === 'remove') { + const { index } = dataset + if (className === 'toggle') { + onToggleClick(index) + } else if (className === 'destroy') { onRemoveClick(index) } }) + // 할일 더블클릭시 에디트 모드로 변경 + this.$target.addEventListener('dblclick', (e) => { + const { className } = e.target; + const { dataset } = e.target.previousSibling; + const { index } = dataset + if (className === 'label') { + onTodoEdit(index) + } + }) + + // 에디트 모드에서 엔터키 또는 ESC 키 클릭시 기능 구현 + this.$target.addEventListener('keydown', (e) => { + const { className } = e.target; + const { index } = e.target.previousSibling.firstChild.dataset + if (className === 'edit') { + if (e.keyCode === ENTER_KEY_CODE) { + onTodoChange(index, e.target.value) + } else if (e.keyCode === ESC_KEY_CODE) { + onTodoEdit(index) + } + } + }) - this.render = function (){ - const INPUT_VIEW = ''; - const BUTTON_VIEW = ''; + this.render = function () { // renderHTMLText 변수 안에 data객체안의 text의 value 값에 태그를 붙여서 저장 const renderHTMLText = this.data.map((val, idx) => { + const TOGGLE_INPUT = ``; + const DESTROY_BUTTON = ''; + const EDIT_INPUT = `` if (!val.text) { // data.text 값이 있는지 확인 throw new Error(error.NOT_DATA) } @@ -41,15 +60,9 @@ function TodoList($target, data, onTodoClick, onRemoveClick){ throw new Error(error.INVALID_DATA) } // // isCompleted 가 참이면 태그를 넣어서 저장(완료되었다는 의미), false면
    만 넣어서 저장 - // return val.isCompleted ? `
  • ${val.text}
  • ` : `
  • ${val.text}
  • `; - return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; + return `
  • ${TOGGLE_INPUT}${DESTROY_BUTTON}
    ${EDIT_INPUT}
  • `; }).join(''); - // console.log("renderHTMLText", renderHTMLText); this.$target.innerHTML = `${renderHTMLText}` } - - - this.render() - } \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoList.txt b/mission001/ganeodolu/js/TodoList.txt new file mode 100644 index 0000000..1931282 --- /dev/null +++ b/mission001/ganeodolu/js/TodoList.txt @@ -0,0 +1,56 @@ +function TodoList($target, data, onToggleClick, onTodoDoubleClick, onRemoveClick){ + this.$target = $target; + this.data = data; + // console.log(data) + this.setState = function (nextData){ + this.data = nextData; + this.render() + } + + if (this === window) { + throw new Error(error.NO_USED_NEW_KEYWORD) + } + else if (Array.isArray(this.data) == false) { + throw new Error(error.NOARRAY_DATA) + } + + this.$target.addEventListener('click', (e) => { + // const {className, dataset} = e.target; + const {className, dataset, checked} = e.target; + const {index} = dataset + if (className === 'toggle') { + console.log("ch",checked) + // checked ? e.target = false : e.target = true; + onToggleClick(index) + } else if (className === 'destroy') { + onRemoveClick(index) + } + }) + + this.render = function (){ + // renderHTMLText 변수 안에 data객체안의 text의 value 값에 태그를 붙여서 저장 + const renderHTMLText = this.data.map((val, idx) => { + const INPUT_VIEW = ``; + const BUTTON_VIEW = ''; + + if (!val.text) { // data.text 값이 있는지 확인 + throw new Error(error.NOT_DATA) + } + // data.text 내용이 문자열이 아닌 경우를 데이터가 이상하다고 가정 + else if (typeof (val.text) != "string") { + throw new Error(error.INVALID_DATA) + } + // // isCompleted 가 참이면 태그를 넣어서 저장(완료되었다는 의미), false면
    만 넣어서 저장 + // return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; + return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; + // return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; + }).join(''); + // console.log("renderHTMLText", renderHTMLText); + this.$target.innerHTML = `${renderHTMLText}` + } + + + + this.render() + +} \ No newline at end of file diff --git a/mission001/ganeodolu/js/index.js b/mission001/ganeodolu/js/index.js index b50f89b..beb5b2d 100644 --- a/mission001/ganeodolu/js/index.js +++ b/mission001/ganeodolu/js/index.js @@ -4,16 +4,20 @@ const error = { NOT_DATA: "data가 null 또는 undefined 입니다.", INVALID_DATA: "data타입이 문자열이 아닙니다.", }; +const ENTER_KEY_CODE = 13; +const ESC_KEY_CODE = 27; const data = [ - // { - // text: 'JS 공부하기', - // isCompleted : false - // }, - // { - // text: 'JS 복습하기', - // isCompleted: true - // }, + { + text: 'JS 공부하기', + isCompleted : false, + isEditing : false, + }, + { + text: 'JS 복습하기', + isCompleted: true, + isEditing : false, + }, ] new App(data); \ No newline at end of file diff --git a/mission001/origin/.vscode/settings.json b/mission001/origin/.vscode/settings.json new file mode 100644 index 0000000..6f3a291 --- /dev/null +++ b/mission001/origin/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/mission001/origin/index.html b/mission001/origin/index.html index b1180c7..3cdcfdd 100644 --- a/mission001/origin/index.html +++ b/mission001/origin/index.html @@ -56,6 +56,6 @@

    TODOS

    - + From 129e4930b49e60f2a3aa66eb709504445f4688ce Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Wed, 18 Dec 2019 18:41:55 +0900 Subject: [PATCH 04/10] =?UTF-8?q?M1=20=EC=82=AD=EC=A0=9C=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit data index 위치를 toggle 태그안에서 li 태그로 변경 --- mission001/ganeodolu/js/TodoList.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index 736eda2..19e05a0 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -15,8 +15,8 @@ function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTod } // 토글버튼과 삭제버튼 기능구현 this.$target.addEventListener('click', (e) => { - const { className, dataset } = e.target; - const { index } = dataset + const { className } = e.target; + const { index } = e.target.parentNode.parentNode.dataset if (className === 'toggle') { onToggleClick(index) } else if (className === 'destroy') { @@ -26,8 +26,7 @@ function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTod // 할일 더블클릭시 에디트 모드로 변경 this.$target.addEventListener('dblclick', (e) => { const { className } = e.target; - const { dataset } = e.target.previousSibling; - const { index } = dataset + const { index } = e.target.parentNode.parentNode.dataset if (className === 'label') { onTodoEdit(index) } @@ -49,7 +48,8 @@ function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTod this.render = function () { // renderHTMLText 변수 안에 data객체안의 text의 value 값에 태그를 붙여서 저장 const renderHTMLText = this.data.map((val, idx) => { - const TOGGLE_INPUT = ``; + // const TOGGLE_INPUT = ``; + const TOGGLE_INPUT = ``; const DESTROY_BUTTON = ''; const EDIT_INPUT = `` if (!val.text) { // data.text 값이 있는지 확인 @@ -60,7 +60,7 @@ function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTod throw new Error(error.INVALID_DATA) } // // isCompleted 가 참이면 태그를 넣어서 저장(완료되었다는 의미), false면
    만 넣어서 저장 - return `
  • ${TOGGLE_INPUT}${DESTROY_BUTTON}
    ${EDIT_INPUT}
  • `; + return `
  • ${TOGGLE_INPUT}${DESTROY_BUTTON}
    ${EDIT_INPUT}
  • `; }).join(''); this.$target.innerHTML = `${renderHTMLText}` } From b5ed6cef82886fd4283872b51b452f776701da84 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Fri, 20 Dec 2019 18:41:57 +0900 Subject: [PATCH 05/10] =?UTF-8?q?M1=20=EB=A6=AC=EB=B7=B0=20=EC=9D=BC?= =?UTF-8?q?=EB=B6=80=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 객체화, e.code 변경, 주석삭제 --- .gitignore | 3 ++ mission001/ganeodolu/js/App.js | 32 +++++++++------- mission001/ganeodolu/js/TodoCount.js | 1 - mission001/ganeodolu/js/TodoInput.js | 7 ++-- mission001/ganeodolu/js/TodoList.js | 23 +++++------- mission001/ganeodolu/js/TodoList.txt | 56 ---------------------------- mission001/ganeodolu/js/index.js | 2 - 7 files changed, 33 insertions(+), 91 deletions(-) delete mode 100644 mission001/ganeodolu/js/TodoList.txt diff --git a/.gitignore b/.gitignore index 6704566..74de17d 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,6 @@ dist # TernJS port file .tern-port + +# VScode +.vscode/* \ No newline at end of file diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index 10b15c4..3388cbb 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -10,25 +10,27 @@ function App(data) { } const $todoList = document.querySelector('.todo-list') - const todoList = new TodoList($todoList, this.data, - (index) => { + const todoList = new TodoList({ + $target: $todoList, + data: this.data, + onToggleClick: (index) => { const nextData = [...this.data] nextData[index].isCompleted = !nextData[index].isCompleted this.setState(nextData) }, - (index) => { + onTodoEdit: (index) => { const nextData = [...this.data] if (!nextData[index].isCompleted) { nextData[index].isEditing = nextData[index].isEditing ? false : true; } this.setState(nextData) }, - (index) => { + onRemoveClick: (index) => { const nextData = [...this.data] nextData.splice(index, 1) this.setState(nextData) }, - (index, value) => { + onTodoChange: (index, value) => { const nextData = [...this.data] nextData[index] = { text: value, @@ -37,7 +39,7 @@ function App(data) { }; this.setState(nextData) }, - ); + }); const $todoCount = document.querySelector('.todo-count'); const $todoCountFilter = document.querySelector('.filters'); @@ -49,14 +51,16 @@ function App(data) { const $todoInput = document.querySelector('.new-todo') const $todoEdit = document.querySelector('.todo-list') const todoInput = new TodoInput($todoInput, $todoEdit, - (text) => { - const nextData = [...this.data] - nextData.push({ - text: text, - isCompleted: false, - isEditing: false, - }) - this.setState(nextData) + { + onAdd: (text) => { + const nextData = [...this.data] + nextData.push({ + text: text, + isCompleted: false, + isEditing: false, + }) + this.setState(nextData) + } } ) } \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js index 5e82095..74edd28 100644 --- a/mission001/ganeodolu/js/TodoCount.js +++ b/mission001/ganeodolu/js/TodoCount.js @@ -3,7 +3,6 @@ function TodoCount($targetCount, $targetCountFilter, data) { this.$targetCount = $targetCount; this.$targetCountFilter = $targetCountFilter; - // 새로운 데이터를 불러서 다시 렌더링하는 setState함수 this.setState = function (nextData) { this.data = nextData; this.render(); diff --git a/mission001/ganeodolu/js/TodoInput.js b/mission001/ganeodolu/js/TodoInput.js index a54cac3..1f0280a 100644 --- a/mission001/ganeodolu/js/TodoInput.js +++ b/mission001/ganeodolu/js/TodoInput.js @@ -1,9 +1,8 @@ -function TodoInput($targetInput, $targetEdit, onAdd) { - // 입력창에서 엔터키 입력시 할일추가 +function TodoInput($targetInput, $targetEdit, {onAdd}) { $targetInput.addEventListener('keydown', (e) => { - if (e.keyCode === ENTER_KEY_CODE) { + if (e.code === "Enter") { onAdd($targetInput.value) - $targetInput.value = ''; // 입력 후 입력란이 공란이 되도록 함 + $targetInput.value = ''; } }) } \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index 19e05a0..9ac6454 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -1,4 +1,4 @@ -function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange) { +function TodoList({$target, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange}) { this.$target = $target; this.data = data; @@ -10,10 +10,10 @@ function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTod if (this === window) { throw new Error(error.NO_USED_NEW_KEYWORD) } - else if (Array.isArray(this.data) == false) { + else if (Array.isArray(this.data) === false) { throw new Error(error.NOARRAY_DATA) } - // 토글버튼과 삭제버튼 기능구현 + this.$target.addEventListener('click', (e) => { const { className } = e.target; const { index } = e.target.parentNode.parentNode.dataset @@ -23,46 +23,41 @@ function TodoList($target, data, onToggleClick, onTodoEdit, onRemoveClick, onTod onRemoveClick(index) } }) - // 할일 더블클릭시 에디트 모드로 변경 + this.$target.addEventListener('dblclick', (e) => { const { className } = e.target; - const { index } = e.target.parentNode.parentNode.dataset + const { index } = e.target.closest('li').dataset if (className === 'label') { onTodoEdit(index) } }) - // 에디트 모드에서 엔터키 또는 ESC 키 클릭시 기능 구현 this.$target.addEventListener('keydown', (e) => { const { className } = e.target; - const { index } = e.target.previousSibling.firstChild.dataset + const { index } = e.target.parentNode.dataset; if (className === 'edit') { - if (e.keyCode === ENTER_KEY_CODE) { + if (e.code === "Enter") { onTodoChange(index, e.target.value) - } else if (e.keyCode === ESC_KEY_CODE) { + } else if (e.code === "Escape") { onTodoEdit(index) } } }) this.render = function () { - // renderHTMLText 변수 안에 data객체안의 text의 value 값에 태그를 붙여서 저장 const renderHTMLText = this.data.map((val, idx) => { - // const TOGGLE_INPUT = ``; const TOGGLE_INPUT = ``; const DESTROY_BUTTON = ''; const EDIT_INPUT = `` if (!val.text) { // data.text 값이 있는지 확인 throw new Error(error.NOT_DATA) } - // data.text 내용이 문자열이 아닌 경우를 데이터가 이상하다고 가정 else if (typeof (val.text) != "string") { throw new Error(error.INVALID_DATA) } - // // isCompleted 가 참이면 태그를 넣어서 저장(완료되었다는 의미), false면
    만 넣어서 저장 return `
  • ${TOGGLE_INPUT}${DESTROY_BUTTON}
    ${EDIT_INPUT}
  • `; }).join(''); - this.$target.innerHTML = `${renderHTMLText}` + this.$target.innerHTML = renderHTMLText } this.render() } \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoList.txt b/mission001/ganeodolu/js/TodoList.txt deleted file mode 100644 index 1931282..0000000 --- a/mission001/ganeodolu/js/TodoList.txt +++ /dev/null @@ -1,56 +0,0 @@ -function TodoList($target, data, onToggleClick, onTodoDoubleClick, onRemoveClick){ - this.$target = $target; - this.data = data; - // console.log(data) - this.setState = function (nextData){ - this.data = nextData; - this.render() - } - - if (this === window) { - throw new Error(error.NO_USED_NEW_KEYWORD) - } - else if (Array.isArray(this.data) == false) { - throw new Error(error.NOARRAY_DATA) - } - - this.$target.addEventListener('click', (e) => { - // const {className, dataset} = e.target; - const {className, dataset, checked} = e.target; - const {index} = dataset - if (className === 'toggle') { - console.log("ch",checked) - // checked ? e.target = false : e.target = true; - onToggleClick(index) - } else if (className === 'destroy') { - onRemoveClick(index) - } - }) - - this.render = function (){ - // renderHTMLText 변수 안에 data객체안의 text의 value 값에 태그를 붙여서 저장 - const renderHTMLText = this.data.map((val, idx) => { - const INPUT_VIEW = ``; - const BUTTON_VIEW = ''; - - if (!val.text) { // data.text 값이 있는지 확인 - throw new Error(error.NOT_DATA) - } - // data.text 내용이 문자열이 아닌 경우를 데이터가 이상하다고 가정 - else if (typeof (val.text) != "string") { - throw new Error(error.INVALID_DATA) - } - // // isCompleted 가 참이면 태그를 넣어서 저장(완료되었다는 의미), false면
    만 넣어서 저장 - // return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; - return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; - // return `
  • ${INPUT_VIEW}${BUTTON_VIEW}
  • `; - }).join(''); - // console.log("renderHTMLText", renderHTMLText); - this.$target.innerHTML = `${renderHTMLText}` - } - - - - this.render() - -} \ No newline at end of file diff --git a/mission001/ganeodolu/js/index.js b/mission001/ganeodolu/js/index.js index beb5b2d..a211895 100644 --- a/mission001/ganeodolu/js/index.js +++ b/mission001/ganeodolu/js/index.js @@ -4,8 +4,6 @@ const error = { NOT_DATA: "data가 null 또는 undefined 입니다.", INVALID_DATA: "data타입이 문자열이 아닙니다.", }; -const ENTER_KEY_CODE = 13; -const ESC_KEY_CODE = 27; const data = [ { From 41636795bd3e6df7bdd2b83aedb897b4e9378fa1 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Mon, 23 Dec 2019 15:43:49 +0900 Subject: [PATCH 06/10] =?UTF-8?q?M1=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit html string 수정, 예외처리 프로토타입제외 --- mission001/ganeodolu/js/App.js | 5 ++--- mission001/ganeodolu/js/TodoCount.js | 4 ++++ mission001/ganeodolu/js/TodoInput.js | 3 ++- mission001/ganeodolu/js/TodoList.js | 17 +++++++++++------ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index 3388cbb..3f92b41 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -21,7 +21,7 @@ function App(data) { onTodoEdit: (index) => { const nextData = [...this.data] if (!nextData[index].isCompleted) { - nextData[index].isEditing = nextData[index].isEditing ? false : true; + nextData[index].isEditing = !nextData[index].isEditing } this.setState(nextData) }, @@ -49,8 +49,7 @@ function App(data) { }) const $todoInput = document.querySelector('.new-todo') - const $todoEdit = document.querySelector('.todo-list') - const todoInput = new TodoInput($todoInput, $todoEdit, + const todoInput = TodoInput($todoInput, { onAdd: (text) => { const nextData = [...this.data] diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js index 74edd28..6287305 100644 --- a/mission001/ganeodolu/js/TodoCount.js +++ b/mission001/ganeodolu/js/TodoCount.js @@ -7,6 +7,10 @@ function TodoCount($targetCount, $targetCountFilter, data) { this.data = nextData; this.render(); } + + if (this === window) { + throw new Error(error.NO_USED_NEW_KEYWORD) + } // // 상태별 아이템 골라서 보여주기 미구현 // this.$targetCountFilter.addEventListener('click', (e) => { // const { className, dataset } = e.target; diff --git a/mission001/ganeodolu/js/TodoInput.js b/mission001/ganeodolu/js/TodoInput.js index 1f0280a..da7dfdb 100644 --- a/mission001/ganeodolu/js/TodoInput.js +++ b/mission001/ganeodolu/js/TodoInput.js @@ -1,4 +1,5 @@ -function TodoInput($targetInput, $targetEdit, {onAdd}) { +function TodoInput($targetInput, {onAdd}) { + $targetInput.addEventListener('keydown', (e) => { if (e.code === "Enter") { onAdd($targetInput.value) diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index 9ac6454..83717b4 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -1,4 +1,4 @@ -function TodoList({$target, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange}) { +function TodoList({ $target, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange }) { this.$target = $target; this.data = data; @@ -46,16 +46,21 @@ function TodoList({$target, data, onToggleClick, onTodoEdit, onRemoveClick, onTo this.render = function () { const renderHTMLText = this.data.map((val, idx) => { - const TOGGLE_INPUT = ``; - const DESTROY_BUTTON = ''; - const EDIT_INPUT = `` - if (!val.text) { // data.text 값이 있는지 확인 + if (!val.text) { throw new Error(error.NOT_DATA) } else if (typeof (val.text) != "string") { throw new Error(error.INVALID_DATA) } - return `
  • ${TOGGLE_INPUT}${DESTROY_BUTTON}
    ${EDIT_INPUT}
  • `; + return ` +
  • +
    + + + +
    + +
  • ` }).join(''); this.$target.innerHTML = renderHTMLText } From 41c18f0207b587e9e1db8e1b313436f64ffcd620 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Tue, 24 Dec 2019 22:05:09 +0900 Subject: [PATCH 07/10] =?UTF-8?q?M1-6=ED=95=84=ED=84=B0=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/ganeodolu/js/App.js | 48 +++++++++++++++++++++++++--- mission001/ganeodolu/js/TodoCount.js | 20 ++++++------ mission001/ganeodolu/js/TodoList.js | 17 +++++++++- mission001/ganeodolu/js/index.js | 2 ++ 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index 3f92b41..f8036fb 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -1,5 +1,10 @@ function App(data) { this.data = data; + // this.render = function (filteredData){ + // console.log(filteredData) + // todoList.render(filteredData) + // todoCount.render(filteredData) + // } this.setState = function (nextData) { this.data = nextData; todoList.setState(this.data) @@ -10,8 +15,11 @@ function App(data) { } const $todoList = document.querySelector('.todo-list') + const $todoFilter = document.querySelector('.filters'); + const todoList = new TodoList({ $target: $todoList, + $targetFilter: $todoFilter, data: this.data, onToggleClick: (index) => { const nextData = [...this.data] @@ -35,17 +43,46 @@ function App(data) { nextData[index] = { text: value, isCompleted: false, - isEditing: false + isEditing: false, + // isFiltered: false }; this.setState(nextData) }, + onFilterClick: (filterBoolean) => { + // let filteredData = [...this.data] + // console.log(this.data) + // console.log(filterBoolean) + // // filteredData = this.data.filter(todo => todo.isCompleted !== filterBoolean) + // filteredData = this.data.map((todo, idx) => { + // (todo.isCompleted !== filterBoolean) && todo[idx].isFiltered = true; + // }) + // console.log(filteredData) + // this.setState(filteredData) + // // this.setState(nextData) + } }); const $todoCount = document.querySelector('.todo-count'); - const $todoCountFilter = document.querySelector('.filters'); - const todoCount = new TodoCount($todoCount, $todoCountFilter, { - totalCount: this.data.length, - completedCount: this.data.filter(todo => todo.isCompleted).length + // const $todoFilter = document.querySelector('.filters'); + const todoCount = new TodoCount({ + $targetCount: $todoCount, + $targetFilter: $todoFilter, + data: { + totalCount: this.data.length, + completedCount: this.data.filter(todo => todo.isComplete).length + }, + // onFilterClick: (filterBoolean) => { + // let filteredData = [...this.data] + // console.log(this.data) + // console.log(filterBoolean) + // filteredData = this.data.filter(todo => todo.isCompleted !== filterBoolean) + // console.log(filteredData) + // this.render(filteredData) + // // this.setState(nextData) + // } + + // totalCount: this.data.length, + // completedCount: this.data.filter(todo => todo.isCompleted).length }) const $todoInput = document.querySelector('.new-todo') @@ -57,6 +94,7 @@ function App(data) { text: text, isCompleted: false, isEditing: false, + // isFiltered: false }) this.setState(nextData) } diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js index 6287305..7133b4e 100644 --- a/mission001/ganeodolu/js/TodoCount.js +++ b/mission001/ganeodolu/js/TodoCount.js @@ -1,7 +1,7 @@ -function TodoCount($targetCount, $targetCountFilter, data) { +function TodoCount({$targetCount, $targetFilter, data, onFilterClick}) { this.data = data; this.$targetCount = $targetCount; - this.$targetCountFilter = $targetCountFilter; + this.$targetFilter = $targetFilter; this.setState = function (nextData) { this.data = nextData; @@ -11,17 +11,17 @@ function TodoCount($targetCount, $targetCountFilter, data) { if (this === window) { throw new Error(error.NO_USED_NEW_KEYWORD) } - // // 상태별 아이템 골라서 보여주기 미구현 - // this.$targetCountFilter.addEventListener('click', (e) => { - // const { className, dataset } = e.target; - // const { index } = dataset - // console.log(e.target) + + // this.$targetFilter.addEventListener('click', (e) => { + // const { className } = e.target; + // // const { index } = dataset + // // console.log(e.target) // if (className === 'all selected') { - // onAllClick() + // onFilterClick() // } else if (className === 'active') { - // onActiveClick() + // onFilterClick(true) // } else if (className === 'completed') { - // onCompletedClick() + // onFilterClick(false) // } // }) diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index 83717b4..6d5d866 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -1,5 +1,6 @@ -function TodoList({ $target, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange }) { +function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange, onFilterClick }) { this.$target = $target; + this.$targetFilter = $targetFilter this.data = data; this.setState = function (nextData) { @@ -44,6 +45,19 @@ function TodoList({ $target, data, onToggleClick, onTodoEdit, onRemoveClick, onT } }) + this.$targetFilter.addEventListener('click', (e) => { + const { className } = e.target; + // const { index } = dataset + // console.log(e.target) + if (className === 'all selected') { + onFilterClick() + } else if (className === 'active') { + onFilterClick(true) + } else if (className === 'completed') { + onFilterClick(false) + } + }) + this.render = function () { const renderHTMLText = this.data.map((val, idx) => { if (!val.text) { @@ -62,6 +76,7 @@ function TodoList({ $target, data, onToggleClick, onTodoEdit, onRemoveClick, onT ` }).join(''); + // console.log("list",renderHTMLText) this.$target.innerHTML = renderHTMLText } this.render() diff --git a/mission001/ganeodolu/js/index.js b/mission001/ganeodolu/js/index.js index a211895..06d37c5 100644 --- a/mission001/ganeodolu/js/index.js +++ b/mission001/ganeodolu/js/index.js @@ -10,11 +10,13 @@ const data = [ text: 'JS 공부하기', isCompleted : false, isEditing : false, + // isFiltered: false }, { text: 'JS 복습하기', isCompleted: true, isEditing : false, + // isFiltered: false }, ] From fe53a4673ec6565b6b0079419d2815ac451ccab3 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Wed, 1 Jan 2020 00:00:06 +0900 Subject: [PATCH 08/10] =?UTF-8?q?M1-6=20=ED=95=84=ED=84=B0=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Happy 2020 Year !!! --- mission001/ganeodolu/index.html | 1 + mission001/ganeodolu/js/App.js | 47 +++++++--------------------- mission001/ganeodolu/js/TodoCount.js | 15 +-------- mission001/ganeodolu/js/TodoInput.js | 2 +- mission001/ganeodolu/js/TodoList.js | 30 +++++++++++------- mission001/ganeodolu/js/constant.js | 19 +++++++++++ mission001/ganeodolu/js/index.js | 22 ------------- 7 files changed, 53 insertions(+), 83 deletions(-) create mode 100644 mission001/ganeodolu/js/constant.js diff --git a/mission001/ganeodolu/index.html b/mission001/ganeodolu/index.html index d362cce..6d17d43 100644 --- a/mission001/ganeodolu/index.html +++ b/mission001/ganeodolu/index.html @@ -60,6 +60,7 @@

    TODOS

    + diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index f8036fb..cf78cf6 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -1,22 +1,22 @@ function App(data) { this.data = data; - // this.render = function (filteredData){ - // console.log(filteredData) - // todoList.render(filteredData) - // todoCount.render(filteredData) - // } + this.render = function (filteredData) { + todoList.setState(filteredData) + todoCount.render(filteredData) + todoCount.setState({ + totalCount: filteredData.length, + }) + } this.setState = function (nextData) { this.data = nextData; todoList.setState(this.data) todoCount.setState({ totalCount: this.data.length, - completedCount: this.data.filter(todo => todo.isComplete).length }) } const $todoList = document.querySelector('.todo-list') const $todoFilter = document.querySelector('.filters'); - const todoList = new TodoList({ $target: $todoList, $targetFilter: $todoFilter, @@ -43,46 +43,24 @@ function App(data) { nextData[index] = { text: value, isCompleted: false, - isEditing: false, - // isFiltered: false + isEditing: false }; this.setState(nextData) }, onFilterClick: (filterBoolean) => { - // let filteredData = [...this.data] - // console.log(this.data) - // console.log(filterBoolean) - // // filteredData = this.data.filter(todo => todo.isCompleted !== filterBoolean) - // filteredData = this.data.map((todo, idx) => { - // (todo.isCompleted !== filterBoolean) && todo[idx].isFiltered = true; - // }) - // console.log(filteredData) - // this.setState(filteredData) - // // this.setState(nextData) + let filteredData = [...this.data] + filteredData = this.data.filter(todo => todo.isCompleted !== filterBoolean) + this.render(filteredData) } }); const $todoCount = document.querySelector('.todo-count'); - // const $todoFilter = document.querySelector('.filters'); const todoCount = new TodoCount({ $targetCount: $todoCount, $targetFilter: $todoFilter, data: { totalCount: this.data.length, - completedCount: this.data.filter(todo => todo.isComplete).length }, - // onFilterClick: (filterBoolean) => { - // let filteredData = [...this.data] - // console.log(this.data) - // console.log(filterBoolean) - // filteredData = this.data.filter(todo => todo.isCompleted !== filterBoolean) - // console.log(filteredData) - // this.render(filteredData) - // // this.setState(nextData) - // } - - // totalCount: this.data.length, - // completedCount: this.data.filter(todo => todo.isCompleted).length }) const $todoInput = document.querySelector('.new-todo') @@ -93,8 +71,7 @@ function App(data) { nextData.push({ text: text, isCompleted: false, - isEditing: false, - // isFiltered: false + isEditing: false }) this.setState(nextData) } diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js index 7133b4e..dd00a52 100644 --- a/mission001/ganeodolu/js/TodoCount.js +++ b/mission001/ganeodolu/js/TodoCount.js @@ -12,21 +12,8 @@ function TodoCount({$targetCount, $targetFilter, data, onFilterClick}) { throw new Error(error.NO_USED_NEW_KEYWORD) } - // this.$targetFilter.addEventListener('click', (e) => { - // const { className } = e.target; - // // const { index } = dataset - // // console.log(e.target) - // if (className === 'all selected') { - // onFilterClick() - // } else if (className === 'active') { - // onFilterClick(true) - // } else if (className === 'completed') { - // onFilterClick(false) - // } - // }) - this.render = function () { - const { totalCount, completedCount } = this.data + const { totalCount } = this.data $targetCount.innerHTML = `총 ${totalCount}개` } this.render(); diff --git a/mission001/ganeodolu/js/TodoInput.js b/mission001/ganeodolu/js/TodoInput.js index da7dfdb..7cf19c6 100644 --- a/mission001/ganeodolu/js/TodoInput.js +++ b/mission001/ganeodolu/js/TodoInput.js @@ -1,7 +1,7 @@ function TodoInput($targetInput, {onAdd}) { $targetInput.addEventListener('keydown', (e) => { - if (e.code === "Enter") { + if (e.key === "Enter") { onAdd($targetInput.value) $targetInput.value = ''; } diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index 6d5d866..4d81606 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -8,6 +8,8 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR this.render() } + const filterTypes = document.querySelectorAll(".filters li a") + if (this === window) { throw new Error(error.NO_USED_NEW_KEYWORD) } @@ -18,6 +20,8 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR this.$target.addEventListener('click', (e) => { const { className } = e.target; const { index } = e.target.parentNode.parentNode.dataset + if(!filterTypes[0].classList.contains("selected")) return + if (className === 'toggle') { onToggleClick(index) } else if (className === 'destroy') { @@ -37,9 +41,9 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR const { className } = e.target; const { index } = e.target.parentNode.dataset; if (className === 'edit') { - if (e.code === "Enter") { + if (e.key === "Enter") { onTodoChange(index, e.target.value) - } else if (e.code === "Escape") { + } else if (e.key === "Escape") { onTodoEdit(index) } } @@ -47,23 +51,28 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR this.$targetFilter.addEventListener('click', (e) => { const { className } = e.target; - // const { index } = dataset - // console.log(e.target) - if (className === 'all selected') { + for (let val of filterTypes) { + if (val.classList.contains("selected")) { + val.classList.remove("selected") + } + } + e.target.classList.add("selected"); + + if (className.includes('all')) { onFilterClick() - } else if (className === 'active') { + } else if (className.includes('active')) { onFilterClick(true) - } else if (className === 'completed') { + } else if (className.includes('completed')) { onFilterClick(false) } }) this.render = function () { - const renderHTMLText = this.data.map((val, idx) => { + const renderedHTMLText = this.data.map((val, idx) => { if (!val.text) { throw new Error(error.NOT_DATA) } - else if (typeof (val.text) != "string") { + else if (typeof (val.text) !== "string") { throw new Error(error.INVALID_DATA) } return ` @@ -76,8 +85,7 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR ` }).join(''); - // console.log("list",renderHTMLText) - this.$target.innerHTML = renderHTMLText + this.$target.innerHTML = renderedHTMLText } this.render() } \ No newline at end of file diff --git a/mission001/ganeodolu/js/constant.js b/mission001/ganeodolu/js/constant.js new file mode 100644 index 0000000..a515344 --- /dev/null +++ b/mission001/ganeodolu/js/constant.js @@ -0,0 +1,19 @@ +const error = { + NO_USED_NEW_KEYWORD: "함수 선언시 new를 사용해주세요.", + NOARRAY_DATA: "data타입이 Array가 아닙니다.", + NOT_DATA: "data가 null 또는 undefined 입니다.", + INVALID_DATA: "data타입이 문자열이 아닙니다.", +}; + +const data = [ + { + text: 'JS 공부하기', + isCompleted : false, + isEditing : false, + }, + { + text: 'JS 복습하기', + isCompleted: true, + isEditing : false, + }, +] diff --git a/mission001/ganeodolu/js/index.js b/mission001/ganeodolu/js/index.js index 06d37c5..05f4a06 100644 --- a/mission001/ganeodolu/js/index.js +++ b/mission001/ganeodolu/js/index.js @@ -1,23 +1 @@ -const error = { - NO_USED_NEW_KEYWORD: "함수 선언시 new를 사용해주세요.", - NOARRAY_DATA: "data타입이 Array가 아닙니다.", - NOT_DATA: "data가 null 또는 undefined 입니다.", - INVALID_DATA: "data타입이 문자열이 아닙니다.", -}; - -const data = [ - { - text: 'JS 공부하기', - isCompleted : false, - isEditing : false, - // isFiltered: false - }, - { - text: 'JS 복습하기', - isCompleted: true, - isEditing : false, - // isFiltered: false - }, -] - new App(data); \ No newline at end of file From a3137a4ede289a5e15d8f948c604164fed1ceba6 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Fri, 10 Jan 2020 20:18:04 +0900 Subject: [PATCH 09/10] =?UTF-8?q?M1=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. if else를 switch로 변환 2. import, export 사용 3. instanceOf 사용하여 instance 검사 프로토타입 미반영 --- mission001/ganeodolu/index.html | 7 +----- mission001/ganeodolu/js/App.js | 20 ++++++++++++----- mission001/ganeodolu/js/TodoCount.js | 2 +- mission001/ganeodolu/js/TodoInput.js | 6 +++-- mission001/ganeodolu/js/TodoList.js | 33 +++++++++++++++------------- mission001/ganeodolu/js/constant.js | 9 +++++--- mission001/ganeodolu/js/index.js | 3 +++ 7 files changed, 47 insertions(+), 33 deletions(-) diff --git a/mission001/ganeodolu/index.html b/mission001/ganeodolu/index.html index 6d17d43..8d19eb5 100644 --- a/mission001/ganeodolu/index.html +++ b/mission001/ganeodolu/index.html @@ -56,11 +56,6 @@

    TODOS

    - - - - - - + diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index cf78cf6..f680f62 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -1,4 +1,9 @@ -function App(data) { +import TodoList from "./TodoList.js" +import TodoCount from "./TodoCount.js" +import TodoInput from "./TodoInput.js" +import {error} from "./constant.js" + +export default function App(data) { this.data = data; this.render = function (filteredData) { todoList.setState(filteredData) @@ -21,24 +26,24 @@ function App(data) { $target: $todoList, $targetFilter: $todoFilter, data: this.data, - onToggleClick: (index) => { + onClickToggle: (index) => { const nextData = [...this.data] nextData[index].isCompleted = !nextData[index].isCompleted this.setState(nextData) }, - onTodoEdit: (index) => { + onEditTodo: (index) => { const nextData = [...this.data] if (!nextData[index].isCompleted) { nextData[index].isEditing = !nextData[index].isEditing } this.setState(nextData) }, - onRemoveClick: (index) => { + onClickRemoval: (index) => { const nextData = [...this.data] nextData.splice(index, 1) this.setState(nextData) }, - onTodoChange: (index, value) => { + onChangeTodo: (index, value) => { const nextData = [...this.data] nextData[index] = { text: value, @@ -47,7 +52,7 @@ function App(data) { }; this.setState(nextData) }, - onFilterClick: (filterBoolean) => { + onClickFilter: (filterBoolean) => { let filteredData = [...this.data] filteredData = this.data.filter(todo => todo.isCompleted !== filterBoolean) this.render(filteredData) @@ -77,4 +82,7 @@ function App(data) { } } ) + if(!todoList instanceof TodoList || !todoCount instanceof TodoCount){ + throw new Error(error.NO_USED_NEW_KEYWORD) + } } \ No newline at end of file diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js index dd00a52..7b8635f 100644 --- a/mission001/ganeodolu/js/TodoCount.js +++ b/mission001/ganeodolu/js/TodoCount.js @@ -1,4 +1,4 @@ -function TodoCount({$targetCount, $targetFilter, data, onFilterClick}) { +export default function TodoCount({$targetCount, $targetFilter, data, onFilterClick}) { this.data = data; this.$targetCount = $targetCount; this.$targetFilter = $targetFilter; diff --git a/mission001/ganeodolu/js/TodoInput.js b/mission001/ganeodolu/js/TodoInput.js index 7cf19c6..0d42dc4 100644 --- a/mission001/ganeodolu/js/TodoInput.js +++ b/mission001/ganeodolu/js/TodoInput.js @@ -1,7 +1,9 @@ -function TodoInput($targetInput, {onAdd}) { +import {keyName} from "./constant.js" + +export default function TodoInput($targetInput, {onAdd}) { $targetInput.addEventListener('keydown', (e) => { - if (e.key === "Enter") { + if (e.key === keyName.ENTER) { onAdd($targetInput.value) $targetInput.value = ''; } diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index 4d81606..d258c92 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -1,4 +1,6 @@ -function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onRemoveClick, onTodoChange, onFilterClick }) { +import {error, keyName} from "./constant.js" + +export default function TodoList({ $target, $targetFilter, data, onClickToggle, onEditTodo, onClickRemoval, onChangeTodo, onClickFilter }) { this.$target = $target; this.$targetFilter = $targetFilter this.data = data; @@ -20,12 +22,13 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR this.$target.addEventListener('click', (e) => { const { className } = e.target; const { index } = e.target.parentNode.parentNode.dataset - if(!filterTypes[0].classList.contains("selected")) return - - if (className === 'toggle') { - onToggleClick(index) - } else if (className === 'destroy') { - onRemoveClick(index) + if (!filterTypes[0].classList.contains("selected")) return + + switch (className) { + case 'toggle': onClickToggle(index) + break; + case 'destroy': onClickRemoval(index) + break; } }) @@ -33,7 +36,7 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR const { className } = e.target; const { index } = e.target.closest('li').dataset if (className === 'label') { - onTodoEdit(index) + onEditTodo(index) } }) @@ -41,10 +44,10 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR const { className } = e.target; const { index } = e.target.parentNode.dataset; if (className === 'edit') { - if (e.key === "Enter") { - onTodoChange(index, e.target.value) - } else if (e.key === "Escape") { - onTodoEdit(index) + if (e.key === keyName.ENTER) { + onChangeTodo(index, e.target.value) + } else if (e.key === keyName.ESC) { + onEditTodo(index) } } }) @@ -59,11 +62,11 @@ function TodoList({ $target, $targetFilter, data, onToggleClick, onTodoEdit, onR e.target.classList.add("selected"); if (className.includes('all')) { - onFilterClick() + onClickFilter() } else if (className.includes('active')) { - onFilterClick(true) + onClickFilter(true) } else if (className.includes('completed')) { - onFilterClick(false) + onClickFilter(false) } }) diff --git a/mission001/ganeodolu/js/constant.js b/mission001/ganeodolu/js/constant.js index a515344..f5d18fc 100644 --- a/mission001/ganeodolu/js/constant.js +++ b/mission001/ganeodolu/js/constant.js @@ -1,11 +1,14 @@ -const error = { +export const error = { NO_USED_NEW_KEYWORD: "함수 선언시 new를 사용해주세요.", NOARRAY_DATA: "data타입이 Array가 아닙니다.", NOT_DATA: "data가 null 또는 undefined 입니다.", INVALID_DATA: "data타입이 문자열이 아닙니다.", }; - -const data = [ +export const keyName = { + ENTER: "Enter", + ESC: "Escape" +} +export const data = [ { text: 'JS 공부하기', isCompleted : false, diff --git a/mission001/ganeodolu/js/index.js b/mission001/ganeodolu/js/index.js index 05f4a06..3998931 100644 --- a/mission001/ganeodolu/js/index.js +++ b/mission001/ganeodolu/js/index.js @@ -1 +1,4 @@ +import App from "./App.js" +import {data} from "./constant.js" + new App(data); \ No newline at end of file From 966cec27274715d8f608d8609f4f3433970245a4 Mon Sep 17 00:00:00 2001 From: ganeodolu Date: Thu, 13 Feb 2020 18:54:51 +0900 Subject: [PATCH 10/10] =?UTF-8?q?M1=20prototype=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B0=9C=ED=96=89=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mission001/ganeodolu/js/App.js | 2 +- mission001/ganeodolu/js/TodoCount.js | 2 +- mission001/ganeodolu/js/TodoInput.js | 2 +- mission001/ganeodolu/js/TodoList.js | 34 +++++++++++++++------------- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/mission001/ganeodolu/js/App.js b/mission001/ganeodolu/js/App.js index f680f62..e4af7cf 100644 --- a/mission001/ganeodolu/js/App.js +++ b/mission001/ganeodolu/js/App.js @@ -85,4 +85,4 @@ export default function App(data) { if(!todoList instanceof TodoList || !todoCount instanceof TodoCount){ throw new Error(error.NO_USED_NEW_KEYWORD) } -} \ No newline at end of file +} diff --git a/mission001/ganeodolu/js/TodoCount.js b/mission001/ganeodolu/js/TodoCount.js index 7b8635f..53dbf85 100644 --- a/mission001/ganeodolu/js/TodoCount.js +++ b/mission001/ganeodolu/js/TodoCount.js @@ -18,4 +18,4 @@ export default function TodoCount({$targetCount, $targetFilter, data, onFilterCl } this.render(); -} \ No newline at end of file +} diff --git a/mission001/ganeodolu/js/TodoInput.js b/mission001/ganeodolu/js/TodoInput.js index 0d42dc4..7e211b8 100644 --- a/mission001/ganeodolu/js/TodoInput.js +++ b/mission001/ganeodolu/js/TodoInput.js @@ -8,4 +8,4 @@ export default function TodoInput($targetInput, {onAdd}) { $targetInput.value = ''; } }) -} \ No newline at end of file +} diff --git a/mission001/ganeodolu/js/TodoList.js b/mission001/ganeodolu/js/TodoList.js index d258c92..b0a3327 100644 --- a/mission001/ganeodolu/js/TodoList.js +++ b/mission001/ganeodolu/js/TodoList.js @@ -1,4 +1,4 @@ -import {error, keyName} from "./constant.js" +import { error, keyName } from "./constant.js" export default function TodoList({ $target, $targetFilter, data, onClickToggle, onEditTodo, onClickRemoval, onChangeTodo, onClickFilter }) { this.$target = $target; @@ -25,7 +25,7 @@ export default function TodoList({ $target, $targetFilter, data, onClickToggle, if (!filterTypes[0].classList.contains("selected")) return switch (className) { - case 'toggle': onClickToggle(index) + case 'toggle': onClickToggle(index) break; case 'destroy': onClickRemoval(index) break; @@ -70,15 +70,18 @@ export default function TodoList({ $target, $targetFilter, data, onClickToggle, } }) - this.render = function () { - const renderedHTMLText = this.data.map((val, idx) => { - if (!val.text) { - throw new Error(error.NOT_DATA) - } - else if (typeof (val.text) !== "string") { - throw new Error(error.INVALID_DATA) - } - return ` + this.render() +} + +TodoList.prototype.render = function () { + const renderedHTMLText = this.data.map((val, idx) => { + if (!val.text) { + throw new Error(error.NOT_DATA) + } + else if (typeof (val.text) !== "string") { + throw new Error(error.INVALID_DATA) + } + return `
  • @@ -87,8 +90,7 @@ export default function TodoList({ $target, $targetFilter, data, onClickToggle,
  • ` - }).join(''); - this.$target.innerHTML = renderedHTMLText - } - this.render() -} \ No newline at end of file + }).join(''); + this.$target.innerHTML = renderedHTMLText +} +