fix: 分页条数切换后自动刷新 (#243)
This commit is contained in:
@@ -50,7 +50,7 @@ func TestInnerCodeTemplate_模块状态白名单已登记(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(raw), `"/inner-codes": ["date", "status", "q", "page"]`) {
|
||||
if !strings.Contains(string(raw), `"/inner-codes": ["date", "status", "q", "page", "page_size"]`) {
|
||||
t.Fatal("档口入库码页面切换模块后应保持稳定筛选和页码")
|
||||
}
|
||||
for _, want := range []string{
|
||||
|
||||
+43
-2
@@ -67,8 +67,13 @@ func TestModuleNavigation_按账号保存稳定列表状态且安全回退(t *te
|
||||
jsSource := string(js)
|
||||
for _, want := range []string{
|
||||
"var MODULE_QUERY_KEYS = {",
|
||||
"\"/shopee\": [\"q\", \"search_field\", \"status\", \"deleted\", \"unlinked\", \"page\"]",
|
||||
"\"/syb\": [\"order_no\", \"shop\", \"stage\", \"page\", \"date_from\", \"date_to\"]",
|
||||
"\"/shopee\": [\"q\", \"search_field\", \"status\", \"deleted\", \"unlinked\", \"page\", \"page_size\"]",
|
||||
"\"/pdd\": [\"q\", \"status\", \"page\", \"page_size\"]",
|
||||
"\"/syb\": [\"order_no\", \"shop\", \"stage\", \"page\", \"page_size\", \"date_from\", \"date_to\"]",
|
||||
"\"/tasks\": [\"type\", \"status\", \"creator\", \"q\", \"page\", \"page_size\"]",
|
||||
"\"/clients\": [\"name\", \"page\", \"page_size\"]",
|
||||
"\"/inner-codes\": [\"date\", \"status\", \"q\", \"page\", \"page_size\"]",
|
||||
"\"/users\": [\"q\", \"status\", \"page\", \"page_size\"]",
|
||||
"var MODULE_STATE_PREFIX = \"cmautobuy:module-state:\"",
|
||||
"parsed.origin !== window.location.origin || parsed.pathname !== moduleRoot",
|
||||
"sessionStorage.setItem(",
|
||||
@@ -96,6 +101,42 @@ func TestModuleNavigation_按账号保存稳定列表状态且安全回退(t *te
|
||||
}
|
||||
}
|
||||
|
||||
func TestPageSizeSelect_切换后自动提交且保留无脚本回退(t *testing.T) {
|
||||
footer, err := os.ReadFile("templates/partials/footer.html")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
footerSource := string(footer)
|
||||
for _, want := range []string{
|
||||
`method="get" class="page-size-form" data-page-size-form`,
|
||||
`name="page_size" data-page-size-select`,
|
||||
`type="submit" data-page-size-submit>应用</button>`,
|
||||
} {
|
||||
if !strings.Contains(footerSource, want) {
|
||||
t.Errorf("公共分页缺少渐进增强回退 %q", want)
|
||||
}
|
||||
}
|
||||
|
||||
js, err := os.ReadFile("static/js/app.js")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jsSource := string(js)
|
||||
for _, want := range []string{
|
||||
`function setupPageSizeForms()`,
|
||||
`select.addEventListener("change"`,
|
||||
`form.getAttribute("aria-busy") === "true"`,
|
||||
`form.requestSubmit()`,
|
||||
`if (beginSubmit()) form.submit()`,
|
||||
`submit.textContent = "加载中…"`,
|
||||
`setupPageSizeForms();`,
|
||||
} {
|
||||
if !strings.Contains(jsSource, want) {
|
||||
t.Errorf("分页容量自动提交缺少交互约束 %q", want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPurchaseModal_未选规格行保持隐藏且不提交(t *testing.T) {
|
||||
files := map[string][]string{
|
||||
"static/css/app.css": {
|
||||
|
||||
+42
-7
@@ -17,14 +17,14 @@
|
||||
都不进入 sessionStorage。链接原始 href 保持模块根地址,因此脚本失效时
|
||||
仍可正常导航。 */
|
||||
var MODULE_QUERY_KEYS = {
|
||||
"/shopee": ["q", "search_field", "status", "deleted", "unlinked", "page"],
|
||||
"/pdd": ["q", "status", "page"],
|
||||
"/syb": ["order_no", "shop", "stage", "page", "date_from", "date_to"],
|
||||
"/shopee": ["q", "search_field", "status", "deleted", "unlinked", "page", "page_size"],
|
||||
"/pdd": ["q", "status", "page", "page_size"],
|
||||
"/syb": ["order_no", "shop", "stage", "page", "page_size", "date_from", "date_to"],
|
||||
"/shops": [],
|
||||
"/tasks": ["type", "status", "creator", "q", "page"],
|
||||
"/clients": ["name", "page"],
|
||||
"/inner-codes": ["date", "status", "q", "page"],
|
||||
"/users": ["q", "status", "page"]
|
||||
"/tasks": ["type", "status", "creator", "q", "page", "page_size"],
|
||||
"/clients": ["name", "page", "page_size"],
|
||||
"/inner-codes": ["date", "status", "q", "page", "page_size"],
|
||||
"/users": ["q", "status", "page", "page_size"]
|
||||
};
|
||||
var MODULE_STATE_PREFIX = "cmautobuy:module-state:";
|
||||
|
||||
@@ -92,6 +92,40 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 每页条数立即生效 ─────────────────────────
|
||||
普通 GET 表单仍是无 JavaScript 时的完整回退;脚本只做渐进增强,让采购员
|
||||
选择 20/50/100 后不用再点一次“应用”。select 不能禁用,否则浏览器提交时
|
||||
会丢掉 page_size。 */
|
||||
function setupPageSizeForms() {
|
||||
document.querySelectorAll("[data-page-size-form]").forEach(function (form) {
|
||||
var select = form.querySelector("[data-page-size-select]");
|
||||
var submit = form.querySelector("[data-page-size-submit]");
|
||||
if (!select) return;
|
||||
|
||||
function beginSubmit() {
|
||||
if (form.getAttribute("aria-busy") === "true") return false;
|
||||
form.setAttribute("aria-busy", "true");
|
||||
if (submit) {
|
||||
submit.disabled = true;
|
||||
submit.textContent = "加载中…";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
form.addEventListener("submit", function () {
|
||||
beginSubmit();
|
||||
});
|
||||
select.addEventListener("change", function () {
|
||||
if (form.getAttribute("aria-busy") === "true") return;
|
||||
if (typeof form.requestSubmit === "function") {
|
||||
form.requestSubmit();
|
||||
return;
|
||||
}
|
||||
if (beginSubmit()) form.submit();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ── 全选 / 反选 ──────────────────────────────
|
||||
表头的勾选框控制本表格所有行的勾选框。 */
|
||||
function setupCheckAll(root) {
|
||||
@@ -853,6 +887,7 @@
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
setupModuleNavigationState();
|
||||
setupPageSizeForms();
|
||||
document.querySelectorAll("table").forEach(setupCheckAll);
|
||||
setupConfirmDelete();
|
||||
setupConfirmSubmit();
|
||||
|
||||
@@ -14,18 +14,18 @@
|
||||
<span>{{.Status}}</span>
|
||||
{{if .Pagination}}
|
||||
<nav class="pagination" aria-label="分页">
|
||||
<form method="get" class="page-size-form">
|
||||
<form method="get" class="page-size-form" data-page-size-form>
|
||||
{{range .Pagination.FilterFields}}
|
||||
<input type="hidden" name="{{.Name}}" value="{{.Value}}">
|
||||
{{end}}
|
||||
<label>每页
|
||||
<select name="page_size">
|
||||
<select name="page_size" data-page-size-select>
|
||||
{{range .Pagination.PageSizeOptions}}
|
||||
<option value="{{.Value}}"{{if .Selected}} selected{{end}}>{{.Value}} 条</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</label>
|
||||
<button type="submit">应用</button>
|
||||
<button type="submit" data-page-size-submit>应用</button>
|
||||
</form>
|
||||
{{if .Pagination.HasPrev}}
|
||||
<a href="{{.Pagination.FirstURL}}">首页</a>
|
||||
|
||||
@@ -114,6 +114,9 @@
|
||||
其他值都回退为 20,不能把用户输入直接交给 SQL `LIMIT`。
|
||||
- `[必须]` 修改每页条数时回到第 1 页;筛选、翻页、写操作跳转、F5、浏览器
|
||||
前进后退和模块状态恢复都保留归一化后的 `page_size`。
|
||||
- `[必须]` 选择 20、50、100 后立即提交 GET 表单并刷新,不要求采购员再点一次
|
||||
“应用”。自动提交要显示加载状态并防重复;“应用”按钮仍保留为 JavaScript
|
||||
不可用时的回退,不能把分页变成只有脚本才能使用的功能。
|
||||
- `[必须]` 越界要兜住:
|
||||
- `page` 非数字、`0`、负数 → 当作第 1 页;
|
||||
- `page` 超过总页数 → 显示**最后一页**(有数据的那页),不是空表格;
|
||||
|
||||
Reference in New Issue
Block a user