From a4be9fcdce43b09a00ba8cae99d8053af6633b4f Mon Sep 17 00:00:00 2001 From: Yuriy Ivanenko Date: Tue, 14 May 2024 10:57:53 -0400 Subject: [PATCH 1/6] Add create/delete functionality --- index.html | 5 +++-- src/index.js | 32 +++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 64e7f6d8a..4d11f9059 100644 --- a/index.html +++ b/index.html @@ -4,12 +4,13 @@ Flatiron Task Lister +

Task Lister Lite™️

-
+ @@ -21,7 +22,7 @@

My Todos:

- + diff --git a/src/index.js b/src/index.js index 08c71b311..62e450cdb 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,29 @@ -document.addEventListener("DOMContentLoaded", () => { - // your code here -}); +// your code here +const form = document.querySelector('#create-task-form') +const submitButton = document.querySelector("#create-task-form input[type='Submit']") +console.log(submitButton) + + +const createNewTask = (e) => { + e.preventDefault() + const taskText = e.target.previousElementSibling.value + if(taskText !== ''){ + const li = document.createElement('li') + const btn = document.createElement('button') + btn.textContent = 'X' + btn.addEventListener('click', handleDeleteTask) + li.textContent = `${taskText} ` + li.appendChild(btn) + document.querySelector("#tasks").appendChild(li) + form.reset() + } +} + +const handleDeleteTask = (e) => { + e.target.parentNode.remove() +} + +submitButton.addEventListener('click', createNewTask) + + + From 85cbad92356ff5be718ee7b177c2d240e4af5a10 Mon Sep 17 00:00:00 2001 From: Yuriy Ivanenko Date: Tue, 14 May 2024 10:59:34 -0400 Subject: [PATCH 2/6] Refactor code --- src/index.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/index.js b/src/index.js index 62e450cdb..3c8cb37af 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,5 @@ -// your code here const form = document.querySelector('#create-task-form') const submitButton = document.querySelector("#create-task-form input[type='Submit']") -console.log(submitButton) - const createNewTask = (e) => { e.preventDefault() @@ -19,9 +16,7 @@ const createNewTask = (e) => { } } -const handleDeleteTask = (e) => { - e.target.parentNode.remove() -} +const handleDeleteTask = (e) => e.target.parentNode.remove() submitButton.addEventListener('click', createNewTask) From db0b87f248b4109f0a48d676bd24f139fa42a8d8 Mon Sep 17 00:00:00 2001 From: Yuriy Ivanenko Date: Wed, 15 May 2024 15:05:01 -0400 Subject: [PATCH 3/6] ALOT of changes --- index.html | 9 +++++ src/index.js | 106 ++++++++++++++++++++++++++++++++++++++++++++++----- style.css | 68 ++++++++++++++++++++++++++------- 3 files changed, 160 insertions(+), 23 deletions(-) diff --git a/index.html b/index.html index 4d11f9059..79e218deb 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,13 @@

Task Lister Lite™️

+ + @@ -20,6 +27,8 @@

Task Lister Lite™️

My Todos:

+ +
diff --git a/src/index.js b/src/index.js index 3c8cb37af..ea4a51609 100644 --- a/src/index.js +++ b/src/index.js @@ -3,22 +3,108 @@ const submitButton = document.querySelector("#create-task-form input[type='Submi const createNewTask = (e) => { e.preventDefault() - const taskText = e.target.previousElementSibling.value - if(taskText !== ''){ - const li = document.createElement('li') + const taskText = e.target['new-task-description'].value + const taskPriority = e.target['new-task-priority'].value + if(taskText !== '' && taskPriority !== ''){ + const tr = document.createElement('tr') + const td1 = document.createElement('td') + const td2 = document.createElement('td') + const td3 = document.createElement('td') const btn = document.createElement('button') - btn.textContent = 'X' - btn.addEventListener('click', handleDeleteTask) - li.textContent = `${taskText} ` - li.appendChild(btn) - document.querySelector("#tasks").appendChild(li) + const editBtn = document.createElement('button') + editBtn.style.marginLeft = '20px' + editBtn.textContent = 'Edit' + editBtn.addEventListener('click', ()=>console.log('edit clicked')) + btn.style.marginLeft = '20px' + btn.textContent = 'Delete' + btn.addEventListener('click', handleTaskDELETE) + tr.className = taskPriority + td1.textContent = taskText + td2.appendChild(btn) + td3.appendChild(editBtn) + tr.appendChild(td1) + tr.appendChild(td2) + tr.appendChild(td3) + document.querySelector('#task-table').appendChild(tr) + handleTaskPOST(taskText, taskPriority).then(data => { + tr.id = data.id + }) form.reset() } } -const handleDeleteTask = (e) => e.target.parentNode.remove() +const handleTaskPOST = (taskText, taskPriority) => { + return fetch('http://localhost:3000/tasks',{ + method: "POST", + headers: { + 'Content-Type' : 'application/json' + }, + body: JSON.stringify({ + task: taskText, + priority: taskPriority + }) + }) + .then(res => res.json()) + .then(data => data) + .catch(error => { + alert('Ooops, something went wrong when trying to write data to the server') + console.log(error) + }) +} + +const handleTaskDELETE = (e) => { + const id = e.target.closest('tr').id + const task = e.target.closest('tr').firstChild.textContent + fetch(`http://localhost:3000/tasks/${id}`,{ + method: 'DELETE', + }) + .then(res => res.json()) + .then(data => { + e.target.closest('tr').remove() + }) + .catch(error => { + alert(`Ooops, something went wrong when trying to delete task: ${task}`) + console.log(error) + }) +} -submitButton.addEventListener('click', createNewTask) +const handleDeleteTask = (e) => e.target.parentNode.remove() +const renderTasks = (body) => { + body.forEach(item => { + const tr = document.createElement('tr') + const td1 = document.createElement('td') + const td2 = document.createElement('td') + const td3 = document.createElement('td') + const btn = document.createElement('button') + const editBtn = document.createElement('button') + editBtn.style.marginLeft = '20px' + editBtn.textContent = 'Edit' + editBtn.addEventListener('click', () => console.log('edit clicked')) + btn.style.marginLeft = '20px' + btn.textContent = 'Delete' + btn.addEventListener('click', handleTaskDELETE) + tr.id = item.id + tr.className = item.priority + td1.textContent = item.task + td2.appendChild(btn) + td3.appendChild(editBtn) + tr.appendChild(td1) + tr.appendChild(td2) + tr.appendChild(td3) + document.querySelector('#task-table').appendChild(tr) + }) +} +const initApp = () => { + fetch('http://localhost:3000/tasks') + .then(res => res.json()) + .then(body => renderTasks(body)) + .catch(error => { + alert('Ooops, looks like something went wrong when trying to retrieve tasks from db.json') + console.log(error) + }) +} +form.addEventListener('submit', createNewTask) +document.addEventListener('DOMContentLoaded', initApp) diff --git a/style.css b/style.css index fe4a85b46..1a9ec4382 100644 --- a/style.css +++ b/style.css @@ -7,11 +7,53 @@ html { body { min-height: 100%; min-width: 100%; - background: linear-gradient(pink, violet); + background: linear-gradient(#f7d9d9, #f1c0c0); + display: flex; + justify-content: center; + align-items: center; + margin: 0; + padding: 0; +} + +select { + font-size: 16px; + padding: 8px; + border-radius: 4px; + border: 1px solid #ccc; + /* background-color: #fff; */ + color: #333; +} + +.high { + font-size: 16px; + padding: 8px; + color: #f90404; +} + +.medium { + font-size: 16px; + padding: 8px; + color: #eeb60e; +} + +.low { + font-size: 16px; + padding: 8px; + color: #01b82f; } button { - font-size: 7px; + font-size: 14px; + padding: 8px 12px; + border: none; + background-color: #4a4a4a; + color: white; + border-radius: 4px; + cursor: pointer; +} + +button:hover { + background-color: #333; } #main-content { @@ -20,18 +62,18 @@ button { justify-content: center; align-items: center; flex-direction: column; - border: 1px solid #333; - background: rgba(255, 255, 255, 0.3); - padding: 15px 20px 18px 18px; - border-radius: 5px; - box-shadow: 2px 5px 5px #333; + border: 1px solid #ccc; + background: rgba(255, 255, 255, 0.9); + padding: 20px; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } #list { - margin: 10px; - border: 1px solid #333; - background: rgba(255, 255, 255, 0.75); - padding: 15px 20px 18px 18px; - border-radius: 5px; - box-shadow: 2px 5px 5px #333; + margin: 10px 0; + border: 1px solid #ccc; + background: rgba(255, 255, 255, 0.9); + padding: 15px; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } From b30d60bafea7a70304707815f4a94b088fa3d7c3 Mon Sep 17 00:00:00 2001 From: Yuriy Ivanenko Date: Thu, 16 May 2024 11:33:48 -0400 Subject: [PATCH 4/6] Full CRUD capability added --- index.html | 2 +- src/index.js | 133 ++++++++++++++++++++++++++++++++++++++------------- style.css | 47 ++++++++++++++---- 3 files changed, 138 insertions(+), 44 deletions(-) diff --git a/index.html b/index.html index 79e218deb..ec340b373 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,7 @@

Task Lister Lite™️

- +
diff --git a/src/index.js b/src/index.js index ea4a51609..968fbdd24 100644 --- a/src/index.js +++ b/src/index.js @@ -1,38 +1,60 @@ const form = document.querySelector('#create-task-form') -const submitButton = document.querySelector("#create-task-form input[type='Submit']") +const submitButton = document.querySelector("#create-task-form input[type='submit']") const createNewTask = (e) => { e.preventDefault() const taskText = e.target['new-task-description'].value const taskPriority = e.target['new-task-priority'].value if(taskText !== '' && taskPriority !== ''){ - const tr = document.createElement('tr') - const td1 = document.createElement('td') - const td2 = document.createElement('td') - const td3 = document.createElement('td') - const btn = document.createElement('button') - const editBtn = document.createElement('button') - editBtn.style.marginLeft = '20px' - editBtn.textContent = 'Edit' - editBtn.addEventListener('click', ()=>console.log('edit clicked')) - btn.style.marginLeft = '20px' - btn.textContent = 'Delete' - btn.addEventListener('click', handleTaskDELETE) - tr.className = taskPriority - td1.textContent = taskText - td2.appendChild(btn) - td3.appendChild(editBtn) - tr.appendChild(td1) - tr.appendChild(td2) - tr.appendChild(td3) - document.querySelector('#task-table').appendChild(tr) handleTaskPOST(taskText, taskPriority).then(data => { + const tr = document.createElement('tr') tr.id = data.id + const td1 = document.createElement('td') + const td2 = document.createElement('td') + const td3 = document.createElement('td') + const editBtn = createEditButton(data.id); + const deleteBtn = createDeleteButton(data.id) + tr.className = taskPriority + td1.textContent = taskText + td2.appendChild(deleteBtn) + td3.appendChild(editBtn) + tr.appendChild(td1) + tr.appendChild(td2) + tr.appendChild(td3) + document.querySelector('#task-table').appendChild(tr) + document.querySelector("#new-task-description").value = '' + document.querySelector("#task-priority").value = '' + //form.reset() + }) + .catch(error => { + console.log(error) }) - form.reset() + } } +//Create edit button and return +const createEditButton = (id) => { + const editBtn = document.createElement('button') + editBtn.style.marginLeft = '20px' + editBtn.textContent = 'Edit' + editBtn.className = 'btn' + editBtn.setAttribute('task-id',id) + editBtn.addEventListener('click', editTask) + return editBtn +} + +const createDeleteButton = (id) => { + const btn = document.createElement('button') + btn.style.marginLeft = '20px' + btn.textContent = 'Delete' + btn.className = 'btn' + btn.addEventListener('click', handleTaskDELETE) + btn.setAttribute('task-id',id) + return btn +} + + const handleTaskPOST = (taskText, taskPriority) => { return fetch('http://localhost:3000/tasks',{ method: "POST", @@ -53,7 +75,7 @@ const handleTaskPOST = (taskText, taskPriority) => { } const handleTaskDELETE = (e) => { - const id = e.target.closest('tr').id + const id = e.target.attributes['task-id'].value const task = e.target.closest('tr').firstChild.textContent fetch(`http://localhost:3000/tasks/${id}`,{ method: 'DELETE', @@ -68,26 +90,71 @@ const handleTaskDELETE = (e) => { }) } -const handleDeleteTask = (e) => e.target.parentNode.remove() +const handleTaskPATCH = (e) => { + e.preventDefault() + const taskText = e.target['new-task-description'].value + const taskPriority = e.target['new-task-priority'].value + id = submitButton.attributes['task-id'].value + fetch(`http://localhost:3000/tasks/${id}`,{ + method: "PATCH", + headers: { + 'Content-Type' : 'application/json' + }, + body: JSON.stringify({ + task: taskText, + priority: taskPriority + }) + }) + .then(res => res.json()) + .then(data => { + //initApp(); + document.querySelector("#new-task-description").value = '' + document.querySelector("#task-priority").value = '' + submitButton.className = 'btn' + submitButton.removeAttribute('task-id') + submitButton.value = 'Create New Task' + form.removeEventListener('submit', handleTaskPATCH) + form.addEventListener('submit',createNewTask) + document.querySelectorAll('tr').forEach(tr => { + tr.remove() + }) + initApp() + }) + .catch(error => { + alert(`Something went wrong while trying to update task: ${taskText}`) + console.log(error) + }) +} + +const editTask = (e) => { + const task = e.target.closest('tr').firstChild.textContent + const priority = e.target.closest('tr').className + const id = e.target.attributes['task-id'].value + // console.log(id) + document.querySelector("#new-task-description").value = task + document.querySelector("#task-priority").value = priority + submitButton.className = 'editBtn' + submitButton.value = 'Edit Task' + submitButton.setAttribute('task-id',id) + form.removeEventListener('submit', createNewTask) + form.addEventListener('submit',handleTaskPATCH) +} const renderTasks = (body) => { + document.querySelector("#new-task-description").value = '' + document.querySelector("#task-priority").value = '' + document.querySelectorAll('tr').forEach(tr => console.log(tr)) body.forEach(item => { const tr = document.createElement('tr') const td1 = document.createElement('td') const td2 = document.createElement('td') const td3 = document.createElement('td') - const btn = document.createElement('button') - const editBtn = document.createElement('button') - editBtn.style.marginLeft = '20px' - editBtn.textContent = 'Edit' - editBtn.addEventListener('click', () => console.log('edit clicked')) - btn.style.marginLeft = '20px' - btn.textContent = 'Delete' - btn.addEventListener('click', handleTaskDELETE) + const editBtn = createEditButton(item.id) + const deleteBtn = createDeleteButton(item.id) tr.id = item.id tr.className = item.priority td1.textContent = item.task - td2.appendChild(btn) + td2.appendChild(deleteBtn) td3.appendChild(editBtn) tr.appendChild(td1) tr.appendChild(td2) diff --git a/style.css b/style.css index 1a9ec4382..5de2ed638 100644 --- a/style.css +++ b/style.css @@ -42,18 +42,45 @@ select { color: #01b82f; } -button { - font-size: 14px; - padding: 8px 12px; - border: none; - background-color: #4a4a4a; - color: white; - border-radius: 4px; - cursor: pointer; +/* Basic button styles */ +.btn { + background-color: #007BFF; /* Blue background */ + border: none; /* Remove default border */ + color: white; /* White text */ + padding: 10px 20px; /* Padding for size */ + text-align: center; /* Center text */ + text-decoration: none; /* Remove underline */ + display: inline-block; /* Inline-block for layout */ + font-size: 16px; /* Font size */ + margin: 4px 2px; /* Margin for spacing */ + cursor: pointer; /* Pointer cursor on hover */ + border-radius: 25px; /* Rounded corners */ + transition: background-color 0.3s ease; /* Smooth transition for hover */ +} + +.editBtn { + background-color: #fb7a02; /* Blue background */ + border: none; /* Remove default border */ + color: white; /* White text */ + padding: 10px 20px; /* Padding for size */ + text-align: center; /* Center text */ + text-decoration: none; /* Remove underline */ + display: inline-block; /* Inline-block for layout */ + font-size: 16px; /* Font size */ + margin: 4px 2px; /* Margin for spacing */ + cursor: pointer; /* Pointer cursor on hover */ + border-radius: 25px; /* Rounded corners */ + transition: background-color 0.3s ease; /* Smooth transition for hover */ +} + +/* Hover state */ +.editBtn:hover { + background-color: #be6601; /* Darker blue on hover */ } -button:hover { - background-color: #333; +/* Hover state */ +.btn:hover { + background-color: #0056b3; /* Darker blue on hover */ } #main-content { From 7b1ba6dcf3899a97182474faeb7fc65c4702a14b Mon Sep 17 00:00:00 2001 From: Yuriy Ivanenko Date: Thu, 16 May 2024 15:01:21 -0400 Subject: [PATCH 5/6] Move table-row creation into seperate function --- src/index.js | 53 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/index.js b/src/index.js index 968fbdd24..9ef6b4194 100644 --- a/src/index.js +++ b/src/index.js @@ -6,33 +6,37 @@ const createNewTask = (e) => { const taskText = e.target['new-task-description'].value const taskPriority = e.target['new-task-priority'].value if(taskText !== '' && taskPriority !== ''){ - handleTaskPOST(taskText, taskPriority).then(data => { - const tr = document.createElement('tr') - tr.id = data.id - const td1 = document.createElement('td') - const td2 = document.createElement('td') - const td3 = document.createElement('td') + handleTaskPOST(taskText, taskPriority) + .then(data => { const editBtn = createEditButton(data.id); const deleteBtn = createDeleteButton(data.id) - tr.className = taskPriority - td1.textContent = taskText - td2.appendChild(deleteBtn) - td3.appendChild(editBtn) - tr.appendChild(td1) - tr.appendChild(td2) - tr.appendChild(td3) + tr = createRow(data.id, taskText, taskPriority, deleteBtn, editBtn) document.querySelector('#task-table').appendChild(tr) document.querySelector("#new-task-description").value = '' document.querySelector("#task-priority").value = '' - //form.reset() }) .catch(error => { console.log(error) }) - } } +const createRow = (id, taskText, taskPriority, deleteBtn, editBtn) => { + const tr = document.createElement('tr') + tr.id = id + tr.className = taskPriority + const td1 = document.createElement('td') + td1.textContent = taskText + const td2 = document.createElement('td') + td2.appendChild(deleteBtn) + const td3 = document.createElement('td') + td3.appendChild(editBtn) + tr.appendChild(td1) + tr.appendChild(td2) + tr.appendChild(td3) + return tr +} + //Create edit button and return const createEditButton = (id) => { const editBtn = document.createElement('button') @@ -107,7 +111,6 @@ const handleTaskPATCH = (e) => { }) .then(res => res.json()) .then(data => { - //initApp(); document.querySelector("#new-task-description").value = '' document.querySelector("#task-priority").value = '' submitButton.className = 'btn' @@ -118,11 +121,11 @@ const handleTaskPATCH = (e) => { document.querySelectorAll('tr').forEach(tr => { tr.remove() }) - initApp() + initApp(); }) .catch(error => { alert(`Something went wrong while trying to update task: ${taskText}`) - console.log(error) + console.log(error) }) } @@ -130,7 +133,6 @@ const editTask = (e) => { const task = e.target.closest('tr').firstChild.textContent const priority = e.target.closest('tr').className const id = e.target.attributes['task-id'].value - // console.log(id) document.querySelector("#new-task-description").value = task document.querySelector("#task-priority").value = priority submitButton.className = 'editBtn' @@ -145,20 +147,9 @@ const renderTasks = (body) => { document.querySelector("#task-priority").value = '' document.querySelectorAll('tr').forEach(tr => console.log(tr)) body.forEach(item => { - const tr = document.createElement('tr') - const td1 = document.createElement('td') - const td2 = document.createElement('td') - const td3 = document.createElement('td') const editBtn = createEditButton(item.id) const deleteBtn = createDeleteButton(item.id) - tr.id = item.id - tr.className = item.priority - td1.textContent = item.task - td2.appendChild(deleteBtn) - td3.appendChild(editBtn) - tr.appendChild(td1) - tr.appendChild(td2) - tr.appendChild(td3) + tr = createRow(item.id, item.task, item.priority, deleteBtn, editBtn) document.querySelector('#task-table').appendChild(tr) }) } From 84b0a5f9920fc52a8bcd4b74527a09b6a1a5f172 Mon Sep 17 00:00:00 2001 From: Yuriy Ivanenko Date: Thu, 16 May 2024 15:41:31 -0400 Subject: [PATCH 6/6] Move reset of App after PATCH into seperate function --- src/index.js | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/index.js b/src/index.js index 9ef6b4194..f08b20855 100644 --- a/src/index.js +++ b/src/index.js @@ -37,7 +37,6 @@ const createRow = (id, taskText, taskPriority, deleteBtn, editBtn) => { return tr } -//Create edit button and return const createEditButton = (id) => { const editBtn = document.createElement('button') editBtn.style.marginLeft = '20px' @@ -58,17 +57,11 @@ const createDeleteButton = (id) => { return btn } - const handleTaskPOST = (taskText, taskPriority) => { return fetch('http://localhost:3000/tasks',{ method: "POST", - headers: { - 'Content-Type' : 'application/json' - }, - body: JSON.stringify({ - task: taskText, - priority: taskPriority - }) + headers: {'Content-Type' : 'application/json'}, + body: JSON.stringify({task: taskText, priority: taskPriority}) }) .then(res => res.json()) .then(data => data) @@ -111,7 +104,16 @@ const handleTaskPATCH = (e) => { }) .then(res => res.json()) .then(data => { - document.querySelector("#new-task-description").value = '' + resetAfterPATCH(); + }) + .catch(error => { + alert(`Something went wrong while trying to update task: ${taskText}`) + console.log(error) + }) +} + +const resetAfterPATCH = () => { + document.querySelector("#new-task-description").value = '' document.querySelector("#task-priority").value = '' submitButton.className = 'btn' submitButton.removeAttribute('task-id') @@ -122,11 +124,6 @@ const handleTaskPATCH = (e) => { tr.remove() }) initApp(); - }) - .catch(error => { - alert(`Something went wrong while trying to update task: ${taskText}`) - console.log(error) - }) } const editTask = (e) => {