88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
/* Admin 的全部 JavaScript。
|
|||
|
|
*
|
||
|
|
* 原生 JS,没有框架、没有构建步骤——见 admin/AGENTS.md 前端约束。
|
||
|
|
* 只做三件纯前端的事:全选、删除前二次确认、按钮禁用。
|
||
|
|
* 搜索、删除、导入本身都是普通表单 POST,服务端渲染,不需要 JS。
|
||
|
|
*
|
||
|
|
* 不要往这里加业务逻辑。业务逻辑在服务端。
|
||
|
|
*/
|
||
|
|
(function () {
|
||
|
|
"use strict";
|
||
|
|
|
||
|
|
/* ── 全选 / 反选 ──────────────────────────────
|
||
|
|
表头的勾选框控制本表格所有行的勾选框。 */
|
||
|
|
function setupCheckAll(root) {
|
||
|
|
var master = root.querySelector("[data-check-all]");
|
||
|
|
if (!master) return;
|
||
|
|
|
||
|
|
var table = master.closest("table");
|
||
|
|
if (!table) return;
|
||
|
|
|
||
|
|
function rowBoxes() {
|
||
|
|
return table.querySelectorAll("tbody input[type=checkbox]");
|
||
|
|
}
|
||
|
|
|
||
|
|
master.addEventListener("change", function () {
|
||
|
|
rowBoxes().forEach(function (box) {
|
||
|
|
box.checked = master.checked;
|
||
|
|
});
|
||
|
|
syncButtons();
|
||
|
|
});
|
||
|
|
|
||
|
|
table.addEventListener("change", function (e) {
|
||
|
|
if (e.target.type !== "checkbox" || e.target === master) return;
|
||
|
|
var boxes = Array.prototype.slice.call(rowBoxes());
|
||
|
|
master.checked = boxes.length > 0 && boxes.every(function (b) {
|
||
|
|
return b.checked;
|
||
|
|
});
|
||
|
|
syncButtons();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── 选中数量 ────────────────────────────── */
|
||
|
|
function checkedCount() {
|
||
|
|
return document.querySelectorAll(
|
||
|
|
"tbody input[type=checkbox]:checked"
|
||
|
|
).length;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── 需要勾选才能点的按钮 ──────────────────
|
||
|
|
标了 data-need-checked 的按钮,没勾选任何行时禁用。 */
|
||
|
|
function syncButtons() {
|
||
|
|
var n = checkedCount();
|
||
|
|
document.querySelectorAll("[data-need-checked]").forEach(function (btn) {
|
||
|
|
btn.disabled = n === 0;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── 删除前二次确认 ────────────────────────
|
||
|
|
标了 data-confirm-delete 的表单,提交前必须确认,
|
||
|
|
并明确告诉用户会删掉几条、不可恢复。 */
|
||
|
|
function setupConfirmDelete() {
|
||
|
|
document.querySelectorAll("[data-confirm-delete]").forEach(function (form) {
|
||
|
|
form.addEventListener("submit", function (e) {
|
||
|
|
var n = checkedCount();
|
||
|
|
if (n === 0) {
|
||
|
|
e.preventDefault();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (!window.confirm("将删除 " + n + " 条记录,不可恢复。确定继续?")) {
|
||
|
|
e.preventDefault();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
document.addEventListener("DOMContentLoaded", function () {
|
||
|
|
document.querySelectorAll("table").forEach(setupCheckAll);
|
||
|
|
setupConfirmDelete();
|
||
|
|
syncButtons();
|
||
|
|
});
|
||
|
|
|
||
|
|
/* TODO(骨架): 双击行打开弹窗。
|
||
|
|
蝦皮数据页 -> 编辑弹窗(填 PDD 链接 + 采集按钮)
|
||
|
|
顺运宝页 -> 规格匹配弹窗
|
||
|
|
实现时注意:弹窗内容由服务端渲染,这里只负责显示/隐藏,
|
||
|
|
不要在前端拼业务数据。 */
|
||
|
|
})();
|