UNPKG

xq-tablelist

Version:

基于Bootstrap5的表格列表,包括管理列表页面、添加页面、编辑页面,同时包括后台管理员管理的页面。

502 lines (484 loc) 16.6 kB
/*! * xq-tablelist v1.0.1 (https://xqkeji.cn/demo/xq-tablelist) * Author xqkeji.cn * LICENSE SSPL-1.0 * Copyright 2023 xqkeji.cn */ (function () { 'use strict'; const xqUtil = require('xq-util'); const xqConfirm = require('xq-confirm'); const sortable = require('xq-html5sortable'); const DEFAULT_OPTIONS = { tableClass: ".xq-tablelist", dragClass: ".xq-drag", checkAllClass: ".xq-tablelist .xq-check-all", addBtnClass: ".xq-tablelist .xq-add", editBtnClass: ".xq-edit", deleteBtnClass: ".xq-delete", copyBtnClass: ".xq-copy", batchBtnClass: ".xq-batch", backPageClass: ".xq-backpage", authTableClass: ".xq-auth-table", authCheckTableClass: ".xq-auth-check-table", authCheckRowClass: ".xq-auth-check-row" }; let tablelistOptions = {}; const setOption = (options = {}) => { tablelistOptions = Object.assign({}, DEFAULT_OPTIONS); if (options) { for (const option in options) { if (Object.hasOwn(tablelistOptions, option)) { treegridOptions[option] = options[option]; } } } }; const getOption = (key) => { if (key in tablelistOptions) { return tablelistOptions[key]; } const tableClass = tablelistOptions["tableClass"]; const table = document.querySelector(tableClass); if (table.hasAttribute(key)) { return String(table.getAttribute(key)); } return ""; }; let table; const getTable = () => { if (table) { return table; } else { const tableClass = getOption("tableClass"); const container = document.querySelector(tableClass); table = container; return table; } }; const bindAdd = () => { const addBtnClass = getOption("addBtnClass"); const add_btn = document.querySelector(addBtnClass); if (add_btn) { add_btn.addEventListener("click", (event) => { const target = event.currentTarget; const table = xqUtil.parents(target, "table")[0]; const pid = table.getAttribute("pid"); let url = target.getAttribute("xq-url"); if (!url) { url = window.location.href; if (url.includes(".html") || url.includes("localhost")) { url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url += "/add.html"; } else { if (pid) { url = url.replace("/" + pid, ""); } url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url += pid ? "/add/" + pid : "/add"; } } window.location.href = url; }); } }; const bindEdit = (element) => { const editBtnClass = getOption("editBtnClass"); const edit_btn = element.querySelector(editBtnClass); if (edit_btn) { edit_btn.addEventListener("click", (event) => { const target = event.currentTarget; const table = getTable(); const pid = table?.getAttribute("pid"); let id = element.getAttribute("id"); id = id.replace("xq_", ""); if (id) { let url = target.getAttribute("xq-url"); if (!url) { url = window.location.href; if (url.includes(".html") || url.includes("localhost")) { url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url = url + "/edit.html?id=" + id; } else { if (pid) { url = url.replace("/" + pid, ""); } url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url = url + "/edit/" + id; } } window.location.href = url; } else { xqConfirm({ content: "\u627E\u4E0D\u5230tr\u7684id\u5C5E\u6027\uFF01" }); } }); } }; const copy = (text) => { const el = document.createElement("input"); el.setAttribute("value", text); document.body.append(el); el.select(); document.execCommand("copy"); el.remove(); }; const bindCopy = (element) => { const copyBtnClass = getOption("copyBtnClass"); const copy_btn = element.querySelector(copyBtnClass); if (copy_btn) { copy_btn.addEventListener("click", () => { let id = element.getAttribute("id"); id = id.replace("xq_", ""); if (id) { copy(id); xqConfirm({ content: "\u5DF2\u7ECF\u5C06id\u590D\u5236\u5230\u7C98\u8D34\u677F" }); } }); } }; const bindDelete = (element) => { const deleteBtnClass = getOption("deleteBtnClass"); const delete_btn = element.querySelector(deleteBtnClass); if (delete_btn) { delete_btn.addEventListener("click", (event) => { const target = event.currentTarget; const table = getTable(); const pid = table?.getAttribute("pid"); let id = element.getAttribute("id"); id = id.replace("xq_", ""); if (id) { let url = target.getAttribute("xq-url"); if (!url) { url = window.location.href; if (pid) { url = url.replace("/" + pid, ""); } url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url += "/delete"; } xqConfirm({ content: "\u786E\u5B9A\u8981\u5220\u9664\u5417\uFF1F", confirm() { fetch(url, { body: JSON.stringify({ id }), headers: { "content-type": "application/json" }, method: "POST" }).then(async (response) => { return response.json(); }).then((data) => { xqConfirm({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access content: data.message, confirm() { if (data.code === 200) { window.location.reload(); } } }); }); } }); } else { xqConfirm({ content: "\u627E\u4E0D\u5230tr\u7684id\u5C5E\u6027\uFF01" }); } }); } }; const bindChange = (element) => { const table = getTable(); let id = element.getAttribute("id"); id = id?.replace("xq_", ""); const textes = element.querySelectorAll("input,select"); for (const text of textes) { const elementId = text.getAttribute("id"); if (elementId !== "id" && elementId !== "check_all") { text.addEventListener("change", (event) => { const targetElement = event.currentTarget; let value = null; value = targetElement.type === "checkbox" ? targetElement.checked : targetElement.value; const target_id = targetElement.getAttribute("id"); const field = target_id?.slice(0, Math.max(0, target_id.indexOf("_"))); const pid = table?.getAttribute("pid"); let xq_url = table?.getAttribute("xq-url"); const data = { id, field, value }; if (!xq_url) { let url = window.location.href; if (pid) { url = url.replace("/" + pid, ""); } url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url += "/change"; xq_url = url; } else { xq_url += "/change"; } fetch(xq_url, { body: JSON.stringify(data), headers: { "content-type": "application/json" }, method: "POST" }).then(async (response) => { return response.json(); }).then((data2) => { console.log(data2); }); }); } } }; const bindBatch = () => { const batchBtnClass = getOption("batchBtnClass"); const batch_btns = document.querySelectorAll(batchBtnClass); if (batch_btns) { for (const batch_btn of batch_btns) { batch_btn.addEventListener("click", (event) => { const target = event.currentTarget; const table = xqUtil.parents(target, "table")[0]; const pid = table.getAttribute("pid"); const formObject = xqUtil.parents(target, "form")[0]; const action = target.getAttribute("name"); if (action) { let url = target.getAttribute("xq-url"); if (!url) { url = window.location.href; if (pid) { url = url.replace("/" + pid, ""); } url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url = url + "/" + action; } const formData = xqUtil.jsonFormData(formObject); const jsonData = JSON.stringify(formData); if (jsonData !== "{}") { xqConfirm({ content: "\u786E\u5B9A\u8981\u8FDB\u884C\u6279\u91CF\u64CD\u4F5C\u5417\uFF1F", confirm() { fetch(url, { body: jsonData, headers: { "content-type": "application/json" }, method: "POST" }).then(async (response) => { return response.json(); }).then((data) => { xqConfirm({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access content: data.message, confirm() { if (data.code === 200) { window.location.reload(); } } }); }); } }); } else { xqConfirm({ content: "\u6CA1\u6709\u9009\u62E9\u64CD\u4F5C\u6570\u636E." }); } } }); } } }; const bindDrag = () => { const dragClass = getOption("dragClass"); const dragger_table = document.querySelector(dragClass); if (dragger_table) { const tbody = dragger_table.querySelector("tbody"); if (tbody) { const firstTr = tbody.querySelector("tbody>tr:first-child"); const firstId = firstTr.getAttribute("id"); const firstTd = firstTr.querySelector("td:first-child"); firstTd?.classList.add("xq-move"); tbody.setAttribute("id", "tbody_" + firstId); const trs = tbody.querySelectorAll("tbody>tr:not(:first-child)"); for (const tr of trs) { const td = tr.querySelector("td:first-child"); td?.classList.add("xq-move"); const innerbody = document.createElement("tbody"); innerbody.append(tr); const trId = tr.getAttribute("id"); innerbody.setAttribute("id", "tbody_" + trId); tbody.after(innerbody); } } sortable(dragClass, { items: "tbody", handle: ".xq-move", placeholder: '<tbody><tr><td colspan="99">&nbsp;</td></tr><tbody>' }); dragger_table.addEventListener("sortstop", () => { const rows = []; let rowIndex = 0; const tbodies = dragger_table.querySelectorAll("tbody"); for (const tbody2 of tbodies) { rowIndex++; const tr = tbody2.querySelector("tr:first-child"); const trId = tr?.getAttribute("id"); const row = { id: trId, ordernum: rowIndex }; rows.push(row); } const pid = dragger_table.getAttribute("pid"); let url = dragger_table.getAttribute("xq-url"); if (!url) { url = window.location.href; if (pid) { url = url.replace("/" + pid, ""); } url = url.slice(0, Math.max(0, url.lastIndexOf("/"))); url += "/b-order"; } fetch(url, { body: JSON.stringify(rows), headers: { "content-type": "application/json" }, method: "POST" }).then(async (response) => { return response.json(); }).then((data) => { if (data.code === 200) ; }); }); } }; const bindCheckAll = () => { const checkAllClass = getOption("checkAllClass"); const check_all = document.querySelector(checkAllClass); if (check_all) { check_all.addEventListener("click", (event) => { const target = event.currentTarget; const { checked } = target; const table = getTable(); const checks = table?.querySelectorAll("tr > td:first-child > input[type=checkbox]"); for (const check of checks) { if (check === target) { continue; } if (checked) { check.checked = true; } else { check.checked = false; } } }); } }; const bindBack = () => { let referrer; let backpage; const backPageClass = getOption("backPageClass"); const els = document.querySelectorAll(backPageClass); if (els) { referrer = document.referrer; if (referrer && referrer !== document.location.href && referrer !== window.top?.location.href) { sessionStorage.setItem(document.location.href, referrer); backpage = referrer; } else { const item = sessionStorage.getItem(document.location.href); if (item) { backpage = item.toString(); } } for (const el of els) { el.addEventListener("click", (event) => { event.preventDefault(); if (backpage) { document.location.href = backpage; } else { xqConfirm({ content: "\u7CFB\u7EDF\u65E0\u6CD5\u81EA\u52A8\u8FD4\u56DE\u4E0A\u4E00\u4E2A\u9875\u9762." }); } }); } } }; const bindAuth = () => { const authTableClass = getOption("authTableClass"); const auth_tables = document.querySelectorAll(authTableClass); if (auth_tables) { for (const auth_table of auth_tables) { const authCheckTableClass = getOption("authCheckTableClass"); const check_table = auth_table.querySelector(authCheckTableClass); if (check_table) { const table_check_all = check_table.querySelector("input[type=checkbox]"); if (table_check_all) { table_check_all.addEventListener("click", (event) => { const target = event.currentTarget; const { checked } = target; const other_checks = auth_table.querySelectorAll("input[type=checkbox]:not(" + authCheckTableClass + ">input[type=checkbox])"); for (const other_check of other_checks) { if (checked) { other_check.checked = true; } else { other_check.checked = false; } } }); } } const authCheckRowClass = getOption("authCheckRowClass"); const check_rows = auth_table.querySelectorAll(authCheckRowClass); for (const check_row of check_rows) { const row_check_all = check_row.querySelector("input[type=checkbox]"); if (row_check_all) { row_check_all.addEventListener("click", (event) => { const target = event.currentTarget; const { checked } = target; const next_td = xqUtil.next(check_row, "td")[0]; const next_td_checks = next_td.querySelectorAll("input[type=checkbox]"); for (const next_td_check of next_td_checks) { if (checked) { next_td_check.checked = true; } else { next_td_check.checked = false; } } }); } } } } }; const init = () => { const table = getTable(); if (table) { const tres = table.querySelectorAll("tr"); for (const tr of tres) { bindEdit(tr); bindDelete(tr); bindChange(tr); bindCopy(tr); } bindCheckAll(); bindAdd(); bindBatch(); bindDrag(); } bindBack(); bindAuth(); }; const xqTableList = (options = {}) => { setOption(options); init(); }; xqUtil.domReady(() => { xqTableList(); }); window.xqTableList = xqTableList; module.exports = xqTableList; })();