iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0

前言

昨天我們已經把「完成任務」和「刪除任務」搬到網頁上。

現在打開 Todo 頁面,不只能看到 MySQL 裡的任務,也可以直接按:

完成任務 刪除

不用再回到 Postman 手動呼叫 API。

那今天就是要繼續把「新增」和「修改」也搬進網頁。

如果這兩個功能完成,前面做過的 CRUD 就真的全部可以直接在 Todo 頁面操作了。

增加新增任務功能

首先在 Todo 頁面上方加入:

<button class="add-btn" onclick="showAddForm()">
    + 新增任務
</button>

接著準備一個新增任務的表單:

<div class="task-form" id="add-form">
    <h2>新增任務</h2>

    <label>任務名稱</label>
    <input type="text" id="new-title">

    <label>任務描述</label>
    <textarea id="new-description"></textarea>

    <label>截止日期</label>
    <input type="datetime-local" id="new-deadline">

    <label>重要程度</label>
    <select id="new-importance">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3" selected>3</option>
        <option value="4">4</option>
        <option value="5">5</option>
    </select>

    <label>預估時間</label>
    <input type="number" id="new-estimated-minutes">

    <div class="form-actions">
        <button onclick="addTask()">新增</button>
        <button onclick="hideAddForm()">取消</button>
    </div>
</div>

這裡先把新增表單隱藏起來:

.task-form {
    display: none;
    background: white;
    padding: 20px;
    margin-bottom: 20px;
    border-radius: 10px;
}

等使用者按下 「+新增任務」 時,再透過 JavaScript 顯示:

function showAddForm() {
    document.getElementById("add-form").style.display = "block";
}

function hideAddForm() {
    document.getElementById("add-form").style.display = "none";
}

這樣平常不會一直看到一大堆輸入框,需要新增任務時再把表單打開。

用 POST 把任務新增進 MySQL

表單有了之後,下一步就是把使用者輸入的內容送到 Flask。
這裡使用前面已經做過的POST /tasks

JavaScript:

async function addTask() {
    const title = document.getElementById("new-title").value;
    const description = document.getElementById("new-description").value;
    const deadline = document.getElementById("new-deadline").value;
    const importance = document.getElementById("new-importance").value;
    const estimatedMinutes =
        document.getElementById("new-estimated-minutes").value;

    if (!title) {
        alert("請輸入任務名稱");
        return;
    }

    try {
        const response = await fetch("/tasks", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({
                title: title,
                description: description,
                deadline: deadline,
                importance: Number(importance),
                estimated_minutes: Number(estimatedMinutes)
            })
        });

        const data = await response.json();

        if (response.ok) {
            location.reload();
        } else {
            alert(data.error || "新增任務失敗");
        }

    } catch (error) {
        console.error(error);
        alert("發生錯誤");
    }
}

這裡跟昨天完成、刪除任務的做法其實很像,都是使用 fetch() 呼叫前面已經寫好的 API。
只是這次除了指定:method: "POST"

還需要透過:JSON.stringify()

把使用者輸入的資料整理成 JSON 傳給 Flask。
新增成功之後:
location.reload();

重新載入頁面,就可以直接看到剛剛新增的任務。
整個流程變成:

填寫新增表單
↓
addTask()
↓
POST /tasks
↓
Flask
↓
MySQL
↓
新增任務
↓
重新整理網頁

到這裡,新增 Todo 已經不需要 Postman 了。

加入編輯功能

新增成功之後,接下來處理修改任務。
先在昨天的「完成任務」和「刪除」中間加入:

<button
    class="edit-btn"
    onclick="showEditForm({{ task.task_id }})"
>
    編輯
</button>

現在每張 Todo 就會有:
完成任務 編輯 刪除

每一張任務都準備自己的編輯表單。

例如任務名稱:

<input
    type="text"
    id="edit-title-{{ task.task_id }}"
    value="{{ task.title }}"
>

重要程度:

<select id="edit-importance-{{ task.task_id }}">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
</select>

進度則可以直接修改:

<input
    type="number"
    id="edit-progress-{{ task.task_id }}"
    value="{{ task.progress }}"
    min="0"
    max="100"
>

跟新增表單一樣,編輯表單平常也是隱藏的。
image

按下「編輯」之後才顯示:

function showEditForm(taskId) {
    document
        .getElementById(`edit-form-${taskId}`)
        .style.display = "block";
}

function hideEditForm(taskId) {
    document
        .getElementById(`edit-form-${taskId}`)
        .style.display = "none";
}

image

這裡再次用到 task_id,讓 JavaScript 知道現在到底是在編輯哪一筆任務。

用 PUT 修改任務

使用者修改完成後,就可以呼叫前面做好的:
PUT /tasks/<task_id>

JavaScript 先取得表單裡的新資料:

const title =
    document.getElementById(`edit-title-${taskId}`).value;

const description =
    document.getElementById(`edit-description-${taskId}`).value;

const deadline =
    document.getElementById(`edit-deadline-${taskId}`).value;

const importance =
    document.getElementById(`edit-importance-${taskId}`).value;

const estimatedMinutes =
    document.getElementById(`edit-estimated-${taskId}`).value;

const progress =
    document.getElementById(`edit-progress-${taskId}`).value;

再透過 fetch() 送給 Flask:

const response = await fetch(`/tasks/${taskId}`, {
    method: "PUT",

    headers: {
        "Content-Type": "application/json"
    },

    body: JSON.stringify({
        title: title,
        description: description,
        estimated_minutes: Number(estimatedMinutes),
        importance: Number(importance),
        deadline: deadline,
        progress: Number(progress),
        status: "todo"
    })
});

修改成功之後一樣:
location.reload();

重新整理頁面,就可以看到更新後的資料。
流程變成:

按下編輯
↓
修改任務資料
↓
儲存修改
↓
PUT /tasks/<task_id>
↓
Flask
↓
UPDATE tasks
↓
MySQL
↓
重新整理

實際測試

今天最後實際從網頁新增一筆任務。
輸入:

任務名稱
任務描述
截止日期
重要程度
預估時間

按下「新增」後,任務會直接寫入 MySQL,重新整理後也還是存在。
接著按下任務旁邊的「編輯」,修改:

任務名稱
任務描述
截止日期
重要程度
預估時間
目前進度

按下「儲存修改」後,頁面重新載入,也可以看到修改後的新資料。
加上昨天完成的「完成任務」和「刪除」,現在終於可以直接在網頁完成:

新增
讀取
修改
刪除

也就是前面一直在做的 CRUD。


做到今天,終於可以暫時跟 Postman 說再見了。

一開始建立 API 時,新增、查看、修改、刪除任務幾乎全部都要在 Postman 一個一個測試。

但經過這幾天慢慢把功能搬進網頁,現在已經可以直接在 Todo 頁面新增任務、修改資料、完成任務和刪除任務。

Day 29,就把 Gemini 正式搬進 Todo 網頁。


上一篇
Day 27|不用再開 Postman:直接在網頁完成、刪除 Todo
下一篇
Day 29|把 Gemini 搬進網頁:AI 告訴我現在先做什麼
系列文
如果 AI 幫我安排每日的任務?——讓待辦清單不只是清單:LLM × Flask × MySQL 打造動態任務規劃系統 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言