列表頁每筆資料提供「刪除」按鈕,點擊後彈出確認對話框,使用者確認才送出 AJAX 刪除請求,成功則移除該列 DOM 元素並同步更新父頁面草稿計數。
原範例使用 `$.messager` (EasyUI) 與 jQuery AJAX,現代專案建議改用 **SweetAlert2** 提供美觀、無障礙、Promise 化的對話框,搭配 `fetch` 或 `axios`。
<ul id="draftList">
<li data-id="101">
<span>草稿標題一</span>
<button class="btn-delete">刪除</button>
</li>
<li data-id="102">
<span>草稿標題二</span>
<button class="btn-delete">刪除</button>
</li>
</ul>
<!-- 引入 SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
const API_BASE = 'https://localhost:8090/webplus3/_web/sns';
/**
* 刪除草稿
* @param {HTMLButtonElement} btn - 點擊的刪除按鈕
* @param {number} id - 草稿 ID
*/
async function deleteDraft(btn, id) {
// 1. 確認對話框
const result = await Swal.fire({
title: '確定刪除這篇草稿?',
text: '此操作無法復原,請謹慎操作。',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '確定刪除',
cancelButtonText: '取消',
reverseButtons: true,
focusCancel: true, // 預設焦點在取消,防誤觸
allowOutsideClick: () => !Swal.isLoading() // 載入時禁止點外關閉
});
if (!result.isConfirmed) return;
// 2. 發送刪除請求
try {
Swal.showLoading(); // 顯示載入狀態
const response = await fetch(`${API_BASE}/delBlog.do`, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({_p: 'YXM9Mw==', id}) // 原範例參數
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const text = await response.text(); // 原 API 回傳純文字 "success"
if (text.trim() !== 'success') throw new Error('伺服器回傳失敗:' + text);
// 3. UI 更新
const $li = $(btn).closest('li');
$li.fadeOut(300, () => $li.remove());
// 同步父視窗草稿計數 (若在 iframe 中)
if (window.parent && typeof window.parent.initDraft === 'function') {
window.parent.initDraft();
}
// 4. 成功提示
await Swal.fire({
toast: true,
position: 'top-end',
icon: 'success',
title: '草稿已刪除',
showConfirmButton: false,
timer: 1500,
timerProgressBar: true
});
} catch (err) {
console.error(err);
await Swal.fire('刪除失敗', err.message, 'error');
}
}
// 事件委派綁定 (支援動態新增列表項)
$('#draftList').on('click', '.btn-delete', function() {
const id = $(this).closest('li').data('id');
deleteDraft(this, id);
});
function deleteDraft(the, id) {
$.messager.confirm('刪除草稿提醒', '
確定刪除這篇草稿嗎?
', function(r) {
if (r) {
$.ajax({
type: 'POST',
url: 'https://localhost:8090/webplus3/_web/sns/delBlog.do?_p=YXM9Mw__&id=' + id,
success: function(data) {
if (data === 'success') {
$(the).parents('li').remove();
parent.initDraft && parent.initDraft();
} else {
$.messager.alert('失敗', '伺服器回傳:' + data, 'error');
}
},
error: function() {
$.messager.alert('錯誤', '網路或伺服器異常', 'error');
}
});
}
});
}
<?php
// delBlog.do
header('Content-Type: text/plain; charset=utf-8');
session_start();
// 驗證登入、權限、CSRF Token...
$id = (int)($_POST['id'] ?? $_GET['id'] ?? 0);
if ($id <= 0) { echo 'invalid id'; exit; }
$pdo = new PDO('mysql:host=localhost;dbname=webplus;charset=utf8mb4', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('DELETE FROM blogs WHERE id = ? AND user_id = ?');
$ok = $stmt->execute([$id, $_SESSION['user_id']]);
echo $ok && $stmt->rowCount() > 0 ? 'success' : 'not_found_or_no_permission';
?>