接續昨天的範例,我們今天來完成 To-Do List 的功能實作吧!
昨天的文章已經完成『顯示待辦事項清單』,今天要執行的是新增/修改/刪除待辦事項清單,本範例使用純 js 的方式來完成。
先複習一下今天的要執行需求以及對應的 API:
我們大概會有以下幾個步驟
因為我們需要 input 輸入的內容,所以這裡宣告 todoInputDOM 來存放 input 的 DOM 物件。
const todoInputDOM = document.getElementById('todoInput');
當使用者輸入待辦事項並按下 Enter 之後,我們要抓取 todoInputDOM 的 value。
todoInputDOM.addEventListener('keydown', event => {
if (event.keyCode === 13 && event.target.value) {
// 在這裡新增待辦項目...
event.target.value = '';
}
});
這裡監聽 todoInputDOM 的 keydown 事件,當 event.keyCode 等於 13 的時候,代表使用者按下 Enter,新增待辦項目並清空輸入框。
建立一個函式,名稱為 newItem
,傳入使用者輸入的文字並返回待辦項目的物件,物件內包括待辦事項 isComplete 狀態和 desc 文字。
const newItem = value => ({ desc: value, isComplete: false});
補充:
const newItem = value => { return {name: value, isComplete: false} };
// 可以簡化為:
const newItem = value => ({ desc: value, isComplete: false});
建立一個函式,名稱為 addItem
,我們傳入待辦事項的物件,之後藉由 fetch
發送 POST request,新增資料到後端。
const addItem = item => {
fetch('http://localhost:3000/todolist', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(item)
})
.then(res => res.json())
.then(json => {
todoList.push(json);
render(todoList);
})
}
在資料成功返回後,我們就將待辦事項的物件加到 todoList 裡,並繪製畫面。
我們大概會有以下幾個步驟
由於修改待辦事項是透過點擊待辦內容(ul#todoList)裡的項目 icon 及項目文字來做修改,所以我們新增 todoListDOM
來抓取 ul#todoList 的 DOM 之後再進一步做操作。
const todoListDOM = document.getElementById('todoList');
當使用者點擊待辦事項內清單的項目,就會觸發修改待辦事項的行為。
todoListDOM.addEventListener('click', event => {
// 點擊後的處理
});
修改區塊包括項目 icon (.finish 跟 .unfinished) 及項目文字 (.desc)
todoListDOM.addEventListener('click', event => {
const currentTarget = event.target;
if (currentTarget && (currentTarget.matches('a.unfinished') || currentTarget.matches('a.finish') || currentTarget.matches('.desc'))) {
// 點擊待辦事項內的項目icon及項目文字,執行修改待辦事項的方法
toggleItem(parseInt(currentTarget.dataset.id, 10))
}
});
toggleItem
為修改待辦事項的方法,會傳入當前修改的 id
後透過 Array.prototype.find() 去找到當前選擇項目,再去切換待辦事項裡『已完成』和『未完成』的狀態,最後發出 HTTP Request(PUT)傳送修改內容。
const toggleItem = id => {
const currentSelectItem = todoList.find(item => item.id === id);
// 切換『已完成』和『未完成』狀態
currentSelectItem.isComplete = !currentSelectItem.isComplete;
fetch(`http://localhost:3000/todolist/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(currentSelectItem)
})
.then(res => res.json())
.then(json => {
render(todoList);
})
}
我們大概會有以下幾個步驟
因為刪除待辦事項的按鈕在待辦內容(ul#todoList)裡,所以新增 todoListDOM
來抓取 ul#todoList 的 DOM。
const todoListDOM = document.getElementById('todoList');
當使用者點擊待辦事項內的『刪除按鈕』,就會觸發刪除待辦事項的行為。
todoListDOM.addEventListener('click', event => {
// 點擊後的處理
});
之前有判斷過修改區塊包括項目 icon (.finish 跟 .unfinished) 及項目文字 (.desc),這次再加上刪除按鈕(a.del)。
todoListDOM.addEventListener('click', event => {
const currentTarget = event.target;
if (currentTarget && (currentTarget.matches('a.unfinished') || currentTarget.matches('a.finish') || currentTarget.matches('.desc'))) {
// 點擊待辦事項內項目icon及項目文字,執行修改待辦事項的方法
toggleItem(parseInt(currentTarget.dataset.id, 10))
} else if (currentTarget && currentTarget.matches('a.del')) {
// 點擊待辦事項內的刪除 icon,觸發刪除待辦事項的行為
removeItem(parseInt(currentTarget.dataset.id, 10))
}
});
removeItem
為刪除待辦事項的方法,會傳入當前修改的 id
後,發出 HTTP Request(DELETE)。
const removeItem = id => {
fetch(`http://localhost:3000/todolist/${id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(json => {
todoList = todoList.filter(item => item.id !== id);
render(todoList);
})
}
最後再透過 render(todoList);
更新畫面(可參考前一篇文章)。
function render (todoList) {
renderTodoList(todoList);
}
function renderTodoList (todoList) {
const html = todoList.map((item, index) => `<li class="list">
<a class="${item.isComplete ? 'finish' : 'unfinished'}" data-id=${item.id}></a>
<p class="desc" data-id=${item.id}>
${item.desc}
</p>
<a class="del" data-id=${item.id}></a>
</li>`).join('')
todoListDOM.innerHTML = html;
}
我們透過 Vanilla JS 去實作 To-Do List 的範例,逐步講解 - 新增/修改/刪除待辦事項所執行的功能並藉由 REST API 完成對應行為。
本人小小筆記,如有錯誤或需要改進的部分,歡迎給予回饋。
我將會用最快的速度修正,m(_ _)m。謝謝