iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

0
自我挑戰組

花三十天找到 JavaScript 沙漠中的綠洲系列 第 34

番外篇(2)一起來做 To Do List!- 實作篇(2)

大家新年快樂!上一篇完成後還剩下這些功能:

  • 可以一次刪除全部的代辦事項
  • 能刪除所有已完成的代辦事項的內容及數量
  • 代辦事項預設以時間排列
  • 代辦事項的順序可以被使用者拖拉
  • 超過時間還沒完成的代辦事項以紅色顯示
  • 有進度、月份、種類的篩選器
  • 有分析按鈕,按下去會跳出視窗,顯示種類的圓餅圖
  • RWD 所以要有手機漢堡選單

剛剛在寫文章時才發現,我上一篇不小心把「完成的代辦事項會跑到最下方」順便寫好了。如果你 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 細節。

下一篇我們會做完剩下的:

  • 有進度、月份、種類的篩選器
  • 有分析按鈕,按下去會跳出視窗,顯示種類的圓餅圖
  • RWD 所以要有手機漢堡選單

敬請期待!


上一篇
番外篇(2)一起來做 To Do List!- 實作篇(1)
下一篇
番外篇(2)一起來做 To Do List!- 實作篇(3)
系列文
花三十天找到 JavaScript 沙漠中的綠洲35

尚未有邦友留言

立即登入留言