u
This commit is contained in:
1 parent
217838c615
commit
4d60582d4f
1 file changed
+298
+298
@@ -0,0 +1,298 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>主子表分页编辑 Demo</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial;
|
||||
padding: 20px;
|
||||
background: #f5f6f8;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
/* 主表 */
|
||||
.form-row {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 6px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 表格 */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 6px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* 分页 */
|
||||
.pager {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 5px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
background: #ffecb3;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.deleted {
|
||||
background: #ffe5e5;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<h2>主表</h2>
|
||||
<div class="form-row">
|
||||
<input id="mainName" placeholder="主表名称" />
|
||||
<input id="mainCode" placeholder="主表编码" />
|
||||
</div>
|
||||
|
||||
<h2>子表(分页编辑)</h2>
|
||||
|
||||
<div class="toolbar">
|
||||
<button onclick="addRow()">新增行</button>
|
||||
<button onclick="submitAll()">提交全部</button>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>名称</th>
|
||||
<th>数量</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody"></tbody>
|
||||
</table>
|
||||
|
||||
<div class="pager">
|
||||
<button onclick="prevPage()">上一页</button>
|
||||
<span id="pageInfo"></span>
|
||||
<button onclick="nextPage()">下一页</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* =========================
|
||||
* 模拟后端数据
|
||||
* =========================
|
||||
*/
|
||||
const serverData = [];
|
||||
for (let i = 1; i <= 50; i++) {
|
||||
serverData.push({
|
||||
id: i,
|
||||
name: "物料-" + i,
|
||||
qty: Math.floor(Math.random() * 100)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 核心状态
|
||||
* =========================
|
||||
*/
|
||||
let page = 1;
|
||||
const pageSize = 5;
|
||||
|
||||
// ⭐ 子表缓存(核心)
|
||||
const cache = new Map();
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 拉取数据(模拟分页接口)
|
||||
* =========================
|
||||
*/
|
||||
function fetchPageData(page) {
|
||||
const start = (page - 1) * pageSize;
|
||||
const list = serverData.slice(start, start + pageSize);
|
||||
|
||||
return list.map(item => {
|
||||
const cached = cache.get(item.id);
|
||||
return cached ? { ...item, ...cached } : item;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 渲染表格
|
||||
* =========================
|
||||
*/
|
||||
function render() {
|
||||
const data = fetchPageData(page);
|
||||
const tbody = document.getElementById("tbody");
|
||||
|
||||
tbody.innerHTML = "";
|
||||
|
||||
data.forEach(row => {
|
||||
if (row._deleted) return;
|
||||
|
||||
const tr = document.createElement("tr");
|
||||
|
||||
if (row.isNew) tr.classList.add("deleted");
|
||||
|
||||
tr.innerHTML = `
|
||||
<td>${row.id}</td>
|
||||
<td>
|
||||
<input value="${row.name || ""}"
|
||||
onchange="onEdit(${row.id}, 'name', this.value)" />
|
||||
</td>
|
||||
<td>
|
||||
<input value="${row.qty || 0}"
|
||||
onchange="onEdit(${row.id}, 'qty', this.value)" />
|
||||
</td>
|
||||
<td>
|
||||
${row.isNew ? '<span class="tag">新增</span>' : ''}
|
||||
<button onclick="removeRow(${row.id})">删除</button>
|
||||
</td>
|
||||
`;
|
||||
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
|
||||
document.getElementById("pageInfo").innerText =
|
||||
`第 ${page} / ${Math.ceil(serverData.length / pageSize)} 页`;
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 编辑缓存
|
||||
* =========================
|
||||
*/
|
||||
function onEdit(id, field, value) {
|
||||
const old = cache.get(id) || { id };
|
||||
const updated = { ...old, [field]: value, isDirty: true };
|
||||
cache.set(id, updated);
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 新增
|
||||
* =========================
|
||||
*/
|
||||
function addRow() {
|
||||
const tempId = "tmp_" + Date.now();
|
||||
|
||||
const newRow = {
|
||||
id: tempId,
|
||||
name: "",
|
||||
qty: 0,
|
||||
isNew: true
|
||||
};
|
||||
|
||||
cache.set(tempId, newRow);
|
||||
serverData.unshift(newRow); // 模拟插入数据源
|
||||
render();
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 删除(逻辑删除)
|
||||
* =========================
|
||||
*/
|
||||
function removeRow(id) {
|
||||
const row = cache.get(id) || { id };
|
||||
cache.set(id, { ...row, _deleted: true });
|
||||
render();
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 分页
|
||||
* =========================
|
||||
*/
|
||||
function prevPage() {
|
||||
if (page > 1) {
|
||||
page--;
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
function nextPage() {
|
||||
if (page < Math.ceil(serverData.length / pageSize)) {
|
||||
page++;
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 提交全部(核心)
|
||||
* =========================
|
||||
*/
|
||||
function submitAll() {
|
||||
const all = Array.from(cache.values());
|
||||
|
||||
const inserted = all.filter(i => i.isNew);
|
||||
const updated = all.filter(i => i.isDirty && !i.isNew);
|
||||
const deleted = all.filter(i => i._deleted);
|
||||
|
||||
console.log("主表:", {
|
||||
name: document.getElementById("mainName").value,
|
||||
code: document.getElementById("mainCode").value
|
||||
});
|
||||
|
||||
console.log("新增:", inserted);
|
||||
console.log("修改:", updated);
|
||||
console.log("删除:", deleted);
|
||||
|
||||
alert("数据已输出到控制台(F12查看)");
|
||||
}
|
||||
|
||||
/**
|
||||
* init
|
||||
*/
|
||||
render();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user