大家新年快樂!上一篇完成後還剩下這些功能:
剛剛在寫文章時才發現,我上一篇不小心把「完成的代辦事項會跑到最下方」順便寫好了。如果你 2/13 前已經看過上一篇,我有把怎麼寫的補充回上一篇。此外我發現本來判斷完成數量的判斷式有 bug ,因此換了一種寫法,一樣有更新。
接著,讓我們來處理時間排序的問題吧!
在日期時間輸入的部分,要自己製作也是可以,但因為要規範合理性等等,我最後選擇使用知識篇介紹過的套件 flatpickr 。因為想將日期與時間拆分開來,因此要分開設定:
flatpickr(dateInput,{
altInput: true,
altFormat: "n/j",
dateFormat: "m/d",
minDate: "today", //限定只能選今天以後的日期
maxDate: "12/31", //限定只能選今年
disableMobile: "true"
});
flatpickr(timeInput,{
enableTime: true,
noCalendar: true,
dateFormat: "H:i",
time_24hr: true,
disableMobile: "true"
});
接著回到需求清單,先從比較簡單的「代辦事項預設以時間排列」開始。沒錯,就是 sort() 。我們分別在本地端儲存兩種資料:todos 和 complete ,並在 function getTodos 中將兩種資料取出,用 JSON.parse 轉回原來方式。而 sort() 會從最左邊的數開始比較。正好我們的陣列是先打日期,再打時間,比較下來沒有問題。在 else if(localStorage.getItem('complete') !== null && localStorage.getItem('todos') !== null){...}
後面加上:
todos.sort();
completes.sort();
要讓超過時間還沒完成的代辦事項以紅色顯示,這句話要如何拆分呢?首先應該是要先取得現在的時間吧?然後才能做後面的比較。
let d = new Date();
//把目前日期和時間轉成數字
let thismonth = parseInt(`${d.getMonth()+1}`);
let today = parseInt(`${d.getDate()}`);
let hourNow = parseInt(`${d.getHours()}`);
let minNow = parseInt(`${d.getMinutes()}`);
接著要取得代辦事項的日期和時間,這裡我用 split("/",2) 以 / 開始拆開前後的月份和日期,用 split(":",2) 以 : 開始拆開前後的小時和分鐘。拆開後即可得到分別的數。
let taskDate= todo[0];
taskDate = taskDate.split("/",2);
let taskMonth = taskDate[0];
let taskDay = taskDate[1];
let taskTime = todo[1];
taskTime = taskTime.split(":",2);
let taskHour = taskTime[0];
let taskMin = taskTime[1];
最後當然就要寫判斷式啦!如果代辦事項的月、日、時、分通通小於目前時間,把本來的樣式移除掉,加上過期的 css 樣式。再到 css 去撰寫過期的樣式就可以囉!
if(taskMonth <= thismonth && taskDay <= today && taskHour < hourNow && taskMin < minNow){
todoLi.classList.remove("todo");
todoLi.classList.add("overdue-todo");
};
為了讓畫面跑好的時候就呈現對的資訊,所以上述程式碼一樣要放到 function getTodos 。
一次刪除的功能大同小異而且挺簡單的,加上按鍵和按鍵的監聽,按下去後除了刪掉畫面上的數字,也要刪掉本地端的。因為我希望即使刪掉已完成的工作數量,還是要顯示一句「尚未有完成的工作」在畫面中,因此我另外放入 innerHTML 做設定。
function clearNumCheck(){
if(confirm("已完成的豐功偉業將會全數刪除,你確定要這麼做嗎?")){
completedTotalNum = 0;
completedNum.innerHTML= `尚未有完成的工作`;
localStorage.removeItem('completeTask'); //連同本地端一起清空
localStorage.removeItem('complete'); //連同本地端一起清空
window.location.reload();
}
}
function deleteAllTask(){
if(confirm("確定刪除所有代辦事項?")){
todoList.innerText = "";
localStorage.removeItem('todos'); //連同本地端一起清空
}
}
今天的最後,要完成的是「代辦事項的順序可以被使用者拖拉」這個功能。我使用的是 sortable 外掛,使用方法在知識篇有提過。
new Sortable(todoList, {
animation: 150,
ghostClass: 'sortable-ghost' //拖曳時的 css 樣式名稱
});
我只有用到最簡單的設定,並在 css 中設定 sortable-ghost class 細節。
下一篇我們會做完剩下的:
敬請期待!