window.checkData = []; //全选 数据池 window.sort = require('../utilities/sort');//排序组件 window.Header = function getHeader(object) { let _targetDom = object.el ? document.getElementById(object.el) : document.getElementsByTagName("table")[0];//基点元素 let _columns = object.column; //列名 let _fixedTop = object.fixedTop || 0; //同级浮动元素高度,使当前元素追加该元素高度浮动 let _isCheckAllBox = object.isCheckAllBox !== false;//是否开启全选框 let _data = object.data || []; //被排序数据 let _restorationColumn = object.restorationColumn || 'id'; //恢复原数据基准字段 let _isRestorationColumnAsc = object.isRestorationColumnAsc || false; //恢复原数据基准字段的排序类型 true:asc false:desc let _before = object.before;//前置元素 let _name = "header:" + (object.name ? object.name + "." : "");//唯一名称 用于区别模块 本地存储 let _isForbidDrag = object.isForbidDrag; let sortType = {}; //排序类型 let columnArr = []; //列数组 let moveTd = {}; //移动列 let isNested = _targetDom.getElementsByTagName("table").length > 0; let setting = "setting-column"; let settingInfo = localStorage.getItem("settingInfo") ? JSON.parse(localStorage.getItem("settingInfo")) : { isCopyWrap: true }; let keyCode = false; let settingCheck = true; var beforeHeaderDom; var headerDom; function getTargetChildNode(dom) { //递归获取input子节点 if (!dom || dom.tagName === 'INPUT') return dom; return getTargetChildNode(dom.firstElementChild); } function createHeaderBefore() {//生成前置元素 let tr = document.createElement("tr"); tr.className = "text-center"; _before.forEach(be => { let th = document.createElement("th"); if (be.colspan) th.colSpan = be.colspan; if (be.font) { let font = document.createElement("span"); font.className = be.font; th.appendChild(font); } if (be.value) th.appendChild(document.createTextNode(be.value)); if (be.class) th.className = be.class; tr.appendChild(th); }); _targetDom.insertBefore(tr, _targetDom.firstElementChild); beforeHeaderDom = tr; } function appendFloat(div, cla = "") { div.style.overflowX = "hidden"; div.className = "m-0 p-0"; let th = document.createElement("th"); th.className = "pl-2 pr-2 header-float " + cla; th.style.top = _fixedTop + "px"; th.appendChild(div); return th; } function createHeader() {//生成表头列 let tr = document.createElement("tr"); tr.className = "text-nowrap"; let firstTr = _targetDom.getElementsByTagName("tr")[0]; let tds = []; if (firstTr) tds = firstTr.children; if (_isCheckAllBox) {//是否开启全选 let div = document.createElement("div"); let check = document.createElement("input"); check.type = "checkbox"; check.id = "checkAll"; if (firstTr) bindCheckbox(check); div.appendChild(check); tr.appendChild(appendFloat(div, "text-left")); } let i = (_isCheckAllBox && firstTr) ? 1 : 0; for (i; i < (tds.length > 0 ? tds.length : _columns.length); i++) { let div = document.createElement("div"); let th = appendFloat(div); let column = _columns[(_isCheckAllBox && firstTr) ? i - 1 : i]; let wid = column ? localStorage.getItem(_name + column.name) : null; if (wid) { div.style.width = wid + "px"; th.style.minWidth = wid + "px"; let trs = _targetDom.children; while (trs[0] && trs[0].tagName !== 'TR') trs = trs[0].children; if (trs[0]) { for (let j = 0; j < trs.length; j++) { if (trs[j].children[i]) { trs[j].children[i].firstElementChild.style.width = wid + "px"; trs[j].children[i].style.minWidth = wid + "px"; } } } } if (column) { if (column.type === 'multi') multiColumn(div, column); else defaultColumn(div, column); } tr.appendChild(th); } bindMove(tr); if (_targetDom.firstElementChild) _targetDom.insertBefore(tr, _targetDom.firstElementChild); else _targetDom.appendChild(tr); headerDom = tr; } function multiColumn(th, column) { //多列样式的生成 if (column.title) { let div = document.createElement("div"); div.className = "w-100 text-center"; div.appendChild(document.createTextNode(column.title)); th.appendChild(div); } let div = document.createElement("div"); div.className = "row text-center"; if (column.rows) { column.rows.forEach(row => { let node = document.createElement("div"); node.className = "col-" + (row.col ? row.col : 1); node.appendChild(document.createTextNode(row.value)); div.appendChild(node); }); th.appendChild(div); } } function defaultColumn(th, column) { //默认列样式的生成 if (column.style) for (let key in column.style) if (column.style.hasOwnProperty(key)) th.parentElement.style[key] = column.style[key]; if (column.class) th.parentElement.className += column.class; let span = document.createElement("span"); span.style.display = "inline-block"; if (!column.neglect) { span.style.cursor = "pointer"; let font = document.createElement("span"); font.className = "fa fa-sort"; span.appendChild(font); span.onclick = rule(column, font); //绑定排序事件 } span.appendChild(document.createTextNode((column.value ? column.value : ''))); th.appendChild(span); } //点击事件触发的排序规则 function rule(column, columnSort) { return function () { if (!sortType[column.name]) { sortType[column.name] = 'asc'; columnArr.push(column.name); columnSort.className = "fa fa-sort-asc"; let columnArrTemp = []; columnArrTemp.push.apply(columnArrTemp, columnArr); window.sort.sort(_data, columnArrTemp, sortType); return; } if (sortType[column.name] === 'asc') { sortType[column.name] = 'desc'; columnSort.className = "fa fa-sort-desc"; let columnArrTemp = []; columnArrTemp.push.apply(columnArrTemp, columnArr); window.sort.sort(_data, columnArrTemp, sortType); return; } if (sortType[column.name] === 'desc') { delete sortType[column.name]; columnArr.some(function (name, index) { if (name === column.name) { columnArr.splice(index, 1); return true; } }); columnSort.className = "fa fa-sort"; if (columnArr.length === 0) { //希尔排序 let arr = []; arr.push.apply(arr, _data); let len = arr.length; for (let gap = Math.floor(len / 2); gap > 0; gap = Math.floor(gap / 2)) { for (let i = gap; i < len; i++) { let j = i; let current = arr[i]; if (_isRestorationColumnAsc) { while (j - gap >= 0 && Number(current[_restorationColumn]) < Number(arr[j - gap][_restorationColumn])) { arr[j] = arr[j - gap]; j = j - gap; } } else { while (j - gap >= 0 && Number(current[_restorationColumn]) > Number(arr[j - gap][_restorationColumn])) { arr[j] = arr[j - gap]; j = j - gap; } } arr[j] = current; } } _data.length = 0; _data.push.apply(_data, arr); return; } let columnArrTemp = []; columnArrTemp.push.apply(columnArrTemp, columnArr); window.sort.sort(_data, columnArrTemp, sortType); } } } function bindCheckbox(check) { let trs = _targetDom.children; while (trs[0].tagName !== 'TR') trs = trs[0].children; check.onchange = function () { if (event.target.checked) { for (let i = 0; i < trs.length; i++) { let checkbox = getTargetChildNode(trs[i].children[0]); if (checkbox && !checkbox.checked) { checkData.push(checkbox.value); checkbox.checked = true; } } } else { checkData = []; for (let i = 0; i < trs.length; i++) { let checkbox = getTargetChildNode(trs[i].children[0]); if (checkbox && checkbox.checked) checkbox.checked = false; } } }; for (let i = 0; i < trs.length; i++) { let checkbox = getTargetChildNode(trs[i].children[0]); if (checkbox) checkbox.onchange = function () { if (event.target.checked) checkData.push(checkbox.value); else checkData.splice(checkData.indexOf(checkbox.value), 1); if (checkData.length === _data.length && !check.checked) check.checked = true; if (checkData.length !== _data.length && check.checked) check.checked = false; } } } function bindMove(tr) { if (_isForbidDrag) return; for (let j = 0; j < tr.children.length; j++) { //为首列绑定拖拽列宽事件 tr.children[j].onmousedown = function () { if (j === 0 && event.offsetX < 10) return; if (event.offsetX < 10) moveTd = {oldX: event.clientX, dom: tr.children[j - 1], index: j - 1}; if (event.offsetX > tr.children[j].offsetWidth - 10) moveTd = { oldX: event.clientX, dom: tr.children[j], index: j }; }; tr.children[j].onmousemove = function () { if (j === 0 && event.offsetX < 10) return; if (event.offsetX < 10 || event.offsetX > tr.children[j].offsetWidth - 10) this.style.cursor = 'w-resize'; else this.style.cursor = 'default'; } } document.onmouseup = function () { //全局监听拖拽列宽的发生 作用域设为全局是为了防抖动 if (moveTd.oldX) { event.stopPropagation(); moveTd.dom.style.cursor = 'default'; moveTd.oldX = undefined; setTimeout(function () { let column = _columns[(_isCheckAllBox && _targetDom.firstElementChild) ? moveTd.index - 1 : moveTd.index]; if (column) localStorage.setItem(_name + column.name, moveTd.dom.offsetWidth); }); } }; //移动时调整表头与表身的列宽 document.onmousemove = function () { if (moveTd.oldX) { event.stopPropagation(); let diff = event.clientX - moveTd.oldX; let newWidth = moveTd.dom.firstElementChild.offsetWidth + diff + "px"; if (diff !== 0) { let trs = _targetDom.getElementsByTagName("tr"); for (let j = (_before ? 1 : 0); j < trs.length; j++) { if (isNested) { let table = trs[j].parentElement; while (table.tagName !== 'TABLE') table = table.parentElement; if (table.id !== object.el) continue; } if (trs[j].children[moveTd.index]) { trs[j].children[moveTd.index].firstElementChild.style.width = newWidth; trs[j].children[moveTd.index].style.minWidth = newWidth; } } _targetDom.style.width = _targetDom.offsetWidth + diff + "px"; moveTd.oldX = event.clientX; } } }; } function repaintDom() { let trs = _targetDom.getElementsByTagName("tr"); for (let i = 0; i < trs.length; i++) { if (isNested) { let table = trs[i].parentElement; while (table.tagName !== 'TABLE') table = table.parentElement; if (table.id !== object.el) continue; } let tds = trs[i].children; for (let j = 0; j < tds.length; j++) { let count = tds[j].children.length; let div = document.createElement("div"); div.style.overflowX = "hidden"; for (let k = 0; k < count; k++) { div.appendChild(tds[j].children[0]); } tds[j].appendChild(div); tds[j].className += " pl-2 pr-2"; } } } function showSetting(type) { return function () { let type2 = type === "setting-1" ? "setting-2" : "setting-1"; document.getElementById(type2).style.display = ""; document.getElementById(type).style.display = "none"; }; } function _createSetting1() { /* *

* */ let div = document.createElement("div"); div.id = "setting-1"; div.style.position = "fixed"; div.style.bottom = 0; div.style.left = 0; div.style.backgroundColor = "#1b1e21"; div.style.width = "50px"; div.style.height = "50px"; div.style.cursor = "pointer"; div.style.textAlign = "center"; div.style.borderRadius = "3px"; let h1 = document.createElement("h1"); let span = document.createElement("span"); span.className = "fa fa-gear"; span.style.color = "white"; div.onclick = showSetting("setting-1"); h1.appendChild(span); div.appendChild(h1); document.body.appendChild(div); } function _createSettingHeader(text, id) { let div = document.createElement("div"); div.style.width = "5%"; div.style.display = "inline-block"; div.style.borderLeft = "1px solid #aaaaaa"; div.style.textAlign = "center"; div.style.cursor = "pointer"; div.innerText = text; div.id = id; div.onclick = function () { if (event.target.id === setting) return; let old = document.getElementById(setting); old.style.backgroundColor = ""; old.style.color = ""; document.getElementById(setting + "-body").style.display = "none"; event.target.style.backgroundColor = "#3490dc"; event.target.style.color = "white"; document.getElementById(event.target.id + "-body").style.display = ""; setting = event.target.id; }; return div; } function bindColumnEvent() { return function () { let storage = localStorage.getItem("column:" + object.name); let arr = storage ? storage.split(',') : []; localStorage.setItem("column:" + object.name, _exeHid(arr).toString()); }; } function _exeHid(arr) { let nodes = document.getElementById("setting-column-body").getElementsByTagName("input"); let show = []; let hid = []; let newArr = []; for (let i = 0; i < nodes.length; i++) { let value = nodes[i].value; let index = nodes[i].dataset.index; let checked = nodes[i].checked; if (checked && arr.indexOf(value) !== -1) show.push(index); if (!checked) { newArr.push(value); if (arr.indexOf(value) === -1) hid.push(index); } } let trs = _targetDom.getElementsByTagName("tr"); //所有行 let total = trs[_before ? 1 : 0].children.length; //最大列 for (let i = 0; i < trs.length; i++) { if (isNested) { //排除表格嵌套 let table = trs[i].parentElement; while (table.tagName !== 'TABLE') table = table.parentElement; if (table.id !== object.el) continue; } if (total !== trs[i].children.length) { //存在合并行/列 let pointer = [];//建立一个指针数组 用于存储下标指向真实element for (let j = 0; j < trs[i].children.length; j++) { if (trs[i].children[j] && trs[i].children[j].colSpan > 1) { for (let k = 0; k < trs[i].children[j].colSpan; k++) pointer.push(j); } else pointer.push(j); } for (let j = 0; j < show.length; j++) showOrHiddenDom(trs[i].children[pointer[show[j]]]); for (let j = 0; j < hid.length; j++) showOrHiddenDom(trs[i].children[pointer[hid[j]]], "hid"); } else { for (let j = 0; j < show.length; j++) showOrHiddenDom(trs[i].children[show[j]]); for (let j = 0; j < hid.length; j++) showOrHiddenDom(trs[i].children[hid[j]], "hid"); } } return newArr; } function showOrHiddenDom(dom, type = "show") { if (!dom) return; if (type === "show") { if (dom.colSpan > 1) dom.colSpan++; else dom.style.display = ""; } else { if (dom.colSpan > 1) dom.colSpan--; else dom.style.display = "none"; } } function appendCheckboxList(div) { let storage = localStorage.getItem("column:" + object.name); let arr = storage ? storage.split(',') : []; _columns.forEach(function (column, index) { let key = "setting-column-" + column.name; let label = document.createElement("label"); label.style.float = "left"; let input = document.createElement("input"); input.type = "checkbox"; input.id = key; input.className = "fixed-checkbox"; input.dataset.index = _isCheckAllBox ? index + 1 : index; input.value = column.name; if (arr.indexOf(column.name) === -1) input.checked = true; label.appendChild(input); let la = document.createElement("label"); la.setAttribute("for", key); label.appendChild(la); label.appendChild(document.createTextNode(column.type ? column.title : column.value)); let prentLabel = document.createElement("label"); prentLabel.style.width = "10%"; prentLabel.appendChild(label); div.appendChild(prentLabel); }); } function bindClearEvent(need) { return function () { for (let i = 0; i < localStorage.length; i++) { let key = localStorage.key(i); if (need === key.substring(0, need.length)) localStorage.removeItem(key); } }; } function bindCheckAllEvent() { return function () { settingCheck = !settingCheck; let nodes = document.getElementById("setting-column-body").getElementsByTagName("input"); for (let i = 0; i < nodes.length; i++) { if (nodes[i].checked !== settingCheck) nodes[i].checked = settingCheck; } } } function bindReverseEvent() { return function () { let nodes = document.getElementById("setting-column-body").getElementsByTagName("input"); for (let i = 0; i < nodes.length; i++) nodes[i].checked = !nodes[i].checked; } } function _createSetting2() { /* * * */ let div = document.createElement("div"); div.id = "setting-2"; div.style.backgroundColor = "white"; div.style.position = "fixed"; div.style.bottom = 0; div.style.left = 0; div.style.width = "100%"; div.style.display = "none"; let div1 = document.createElement("div"); div1.style.width = "100%"; div1.style.backgroundColor = "RGB(245,245,220)"; div1.style.borderTop = "1px solid #1b1e21"; let div11 = document.createElement("div"); div11.style.width = "30px"; div11.style.display = "inline-block"; div11.style.textAlign = "center"; let span = document.createElement("span"); span.className = "fa fa-gear"; span.style.cursor = "pointer"; span.onclick = showSetting("setting-2"); div11.appendChild(span); div1.appendChild(div11); let div12 = _createSettingHeader("显示列", "setting-column"); div12.style.backgroundColor = "#3490dc"; div12.style.color = "white"; div1.appendChild(div12); div1.appendChild(_createSettingHeader("表头设置", "setting-header")); let b = document.createElement("b"); b.style.float = "right"; b.style.marginRight = "10px"; b.style.cursor = "pointer"; b.style.fontSize = "18px"; b.innerHTML = "×"; b.onclick = showSetting("setting-2"); div1.appendChild(b); div.appendChild(div1); //body let div2 = document.createElement("div"); div2.style.width = "100%"; div2.style.minHeight = "50px"; div2.style.margin = "10px 50px 20px 50px"; let div21 = document.createElement("div"); div21.id = "setting-column-body"; appendCheckboxList(div21); let btn = document.createElement("button"); btn.className = "btn btn-sm btn-success"; btn.type = "button"; btn.innerText = "保存设置"; btn.onclick = bindColumnEvent(); let div211 = document.createElement("div"); div211.appendChild(btn); let btn1 = document.createElement("button"); btn1.className = "btn btn-sm btn-outline-info ml-1"; btn1.type = "button"; btn1.innerText = "全选/取消"; btn1.onclick = bindCheckAllEvent(); div211.appendChild(btn1); let btn2 = document.createElement("button"); btn2.className = "btn btn-sm btn-outline-info ml-1"; btn2.type = "button"; btn2.innerText = "反选"; btn2.onclick = bindReverseEvent(); div211.appendChild(btn2); div21.appendChild(div211); div2.appendChild(div21); let div22 = document.createElement("div"); div22.id = "setting-header-body"; div22.style.display = "none"; let div221 = document.createElement("div"); div221.className = "row mt-2"; let text = document.createElement("label"); text.innerText = "清除本地列宽设置:"; text.className = "text-right col-3"; div221.appendChild(text); let btnA = document.createElement("button"); btnA.className = "btn btn-sm btn-outline-danger"; btnA.innerText = "清除全部"; btnA.onclick = bindClearEvent("header:"); div221.appendChild(btnA); let btnB = document.createElement("button"); btnB.className = "ml-1 btn btn-sm btn-outline-danger"; btnB.innerText = "清除本页"; btnB.onclick = bindClearEvent(_name); div221.appendChild(btnB); let div222 = document.createElement("div"); div222.className = "row mt-2"; let text2 = document.createElement("label"); text2.innerText = "禁止复制换行:"; text2.className = "text-right col-3"; div222.appendChild(text2); let input = document.createElement("input"); input.type = "checkbox"; input.className = "switch"; input.checked = settingInfo.isCopyNoWrap; input.onchange = function () { settingInfo.isCopyNoWrap = event.target.checked; localStorage.setItem("settingInfo", JSON.stringify(settingInfo)); }; let div223 = document.createElement("div"); div223.className = "row"; let text3 = document.createElement("label"); text3.innerText = "消息通知:"; text3.className = "text-right col-3"; div223.appendChild(text3); let btn3 = document.createElement("button"); btn3.className = "btn btn-sm btn-outline-info"; btn3.innerText = "打开消息面板"; btn3.onclick = function () { let height = window.screen.height; window.open("https://" + window.location.host + "/notification/regular", 'newwindow', 'height=' + (height * 0.7) + ', width=510 ,top=' + (height * 0.10) + 'toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no'); }; div223.appendChild(btn3); div222.appendChild(input); div22.appendChild(div223); div22.appendChild(div221); div22.appendChild(div222); div2.appendChild(div22); div.appendChild(div2); document.body.appendChild(div); } function createSetting() { _createSetting1(); _createSetting2(); } function bindGlobalEvent() { document.onkeydown = (e) => { if (e.ctrlKey && e.keyCode === 67) keyCode = true; }; document.oncopy = (e) => { if (keyCode && settingInfo.isCopyNoWrap) { e.preventDefault(); let content = window.getSelection().toString(); e.clipboardData.setData("text", content.replace(/[\n\r]/g, ' ')); keyCode = false; } }; } //初始化 this.init = function () { if (!_isForbidDrag) repaintDom(); createHeader(); if (_before) createHeaderBefore(); createSetting(); _exeHid([]); bindGlobalEvent(); _targetDom.style.width = _targetDom.offsetWidth + "px"; }; this.redrawHeader = function(column) { _columns = column; if (beforeHeaderDom) { _targetDom.removeChild(beforeHeaderDom); } if (headerDom) { _targetDom.removeChild(headerDom); } createHeader(); if (_before) createHeaderBefore(); } };