Verify.js,axios.min.js,treeTable懶載入,distpicker省市區聯動
vue相容ie情況:
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
axios在ie中提示promise未定義解決辦法:
<script src="https://cdn.bootcss.com/es6-promise/4.1.1/es6-promise.auto.min.js"></script>
1.axios.min.js 使用:
axios({
method: 'post',
url: '/Budget/Handler/PlanHandler.ashx?Method=OldGetSubBudgetList',
var res = res.data.ds;
}).catch(function (error) {
console.log(error);
alert(false);
});
2.表單驗證Verify.js使用
/*! * 主 題:《表單錄入驗證》 * 說 明:通過控制元件屬性實現驗證,包括生成星號標註、非法提示等; * 功能描述: * 1、當錄入框必填時,在控制元件後生成紅色星號(設定star=false時不顯示星號); * 2、根據控制元件屬性判斷需要錄入的資料格式,如果非法則阻止提交併彈出提示 * 3、支援分組驗證 * 4、可脫離微廈線上學習系統獨立使用(需要JQuery庫支援) * * 作 者:微廈科技_宋雷鳴[email protected] * 開發時間: 2013年8月5日 * 最後修訂:2018年2月4日Verify.js*/ (function () { var verify = { version: "1.5", //版本號 //預設屬性值 attr: { place: "right", //提示資訊顯示位置,預設為下方,可以設定right backgroundcolor: "#FF3300", //背景色 foregroundcolor: "#FFFFFF", //前景色 showheight: 25, //提示框的高度 showsize: 13 //提示框字型大小 }, //驗證的錯誤提示 errmsg: { nullable: { def: "不能為空" }, lenlimit: { def: "限制{0}字元", msg1: "超出{0}個字元", msg2: "請錄入{0}-{1}個字元" }, numlimit: { def: "請輸入數字", msg1: "請輸入小於等於{0}的數字", msg2: "請錄入{0}-{1}之間的數字", msg3: "只能錄入{0}" }, sametarget: { def: "兩次輸入不相同" }, novalue: { def: "值不合法" }, datatype: { def: "值不合法!", uint: "請輸入正整數", number: "請輸入數字", float: "請輸入浮點數", tel: "請輸入正確的電話號碼", mobile: "請輸入行動電話號碼", zip: "請輸入郵政編碼", user: "請用字元開頭的字母數字組合", email: "請輸入正確的電子信箱", idcard: "請輸入正確的身份證資訊", url: "請輸入合法的網路地址", qq: "請輸入合規的QQ號碼", chinese: "請輸入中文字元", creditcode:"請輸入統一信用程式碼", }, fileallow: { def: "上傳檔案僅限{0}格式!" }, filelimit: { def: "不許上傳{0}格式的檔案!" }, begin: { def: "請以{0}開頭!" }, end: { def: "請以{0}結尾!" }, regex: { def: "無法滿足錄入要求!" } }, //初始化控制元件 //element:頁面元素(jquery物件),如果為空,則為全域性 init: function (element) { var star = "<span class='nullable' style=\"color:red;width:5px;line-height:26px\" >*</span>"; var noStar = "<span class='nullable' style=\"color:red;width:5px;line-height:26px\" > </span>"; if (element == null) element = $("body"); element.find("*[nullable='false'],select[novalue='-1']").each(function () { var isstar = verify.getAttr($(this), "star", "true"); if (isstar == "true") $(this).before(star); }); element.find("*[nullable='true'],select[novalue='-1']").each(function () { var isstar = verify.getAttr($(this), "star", "true"); if (isstar == "true") $(this).before(noStar); }); //提交按鈕的事件 $("*[verify='true']").click(function () { if ($(this).attr("disabled")) return; //如果按鈕是禁用的,則不驗證 var group = $(this).attr("group"); //按鈕的驗證組,識標碼 var form = $(this).parents("form"); form = form.size() > 0 ? form : $("body"); return verify.IsPass(form, group); }); //失去焦點時的事件 $("form[patter=focus] *[type!=submit][type!=button][type!=image]:visible").focus(function () { verify.operateSingle(null, $(this)); }); $("form[patter!=focus] *[type!=submit][type!=button][type!=image][patter=focus]:visible").focus(function () { verify.operateSingle(null, $(this)); }); //當滑鼠點選,或錄入時,清除提示框 $(window).bind("mousedown keydown scroll onmousewheel", function () { $(".VerifyShowBox").remove(); }); }, //批量驗證控制元件 IsPass: function (control, group) { var isPass = true; group = group == null ? "" : group; var ctls = control.find("*[type!=submit][type!=button]:visible"); if (ctls.length > 0) { ctls.each(function () { isPass = verify.operateSingle(group, $(this)); if (!isPass) return false; }); } else { return verify.operateSingle(group, control); } return isPass; }, //逐個驗證控制元件 operateSingle: function (group, control) { var isPass = true; var name = control.get(0).tagName.toLowerCase(); if (name == "input" || name == "select" || name == "textarea") { //按鈕與控制元件的分組碼不同,則跳過 if (group == "all" || verify.isSamegroup(group, control.attr("group"))) { for (var attr in verify.verifyfunc) { var attrval = control.attr(attr); //屬性的值 if (typeof (attrval) == "undefined") continue; isPass = verify.verifyfunc[attr](control, attrval, $.trim(control.val())); if (!isPass) return false; } } } return isPass; }, //判斷兩個組是否有交疊 isSamegroup: function (btnGroup, ctlGroup) { btnGroup = btnGroup == null ? "" : btnGroup; ctlGroup = ctlGroup == null ? "" : ctlGroup; if (btnGroup == ctlGroup) return true; var arr1 = btnGroup.split("|"); var arr2 = ctlGroup.split("|"); for (var a in arr1) { for (var b in arr2) { if (arr1[a] == arr2[b]) return true; } } return false; }, //獲取屬性,如果控制元件沒有該屬性,則取form上的同名屬性 //control:控制元件 //attrName:屬性 //defValue:預設值 getAttr: function (control, attrName, defValue) { var attr = control.attr(attrName); if (attr == null || attr == "") { var form = control.parents("form"); if (form.length > 0) attr = form.attr(attrName); } return attr == null || attr == "" ? defValue : attr; }, //顯示提示個資訊 //control:要顯示提示的控制元件 //showTxt:要顯示的提示,如果控制元件有alt屬性,則顯示alt值作為提示 //isforce:是否強行顯示showTxt showBox: function (control, showTxt, isforce) { //提示資訊 if (isforce == null || !isforce) { var alt = $.trim(control.attr("alt")); showTxt = alt.length < 1 ? showTxt : alt; } $(".VerifyShowBox").remove(); $(".errorShow").remove(); var html = "<div name=\"" + control.attr("name") + "\" group=\"" + control.attr("group") + "\" class=\"VerifyShowBox\" style=\"display:none\">"; html += "<div class=\"arrow-up\"> </div><div class=\"errorShow\">" + showTxt + " </div></div>"; $("body").prepend(html); var box = $(".VerifyShowBox[name=" + control.attr("name") + "]"); var place = verify.getAttr(control, "place", verify.attr.place); //顯示位置,預設在下方 var bgcolor = verify.getAttr(control, "bgcolor", verify.attr.backgroundcolor); //背景色 var fgcolor = verify.getAttr(control, "fgcolor", verify.attr.foregroundcolor); //前景色 var showheight = Number(verify.getAttr(control, "showheight", verify.attr.showheight)); //提示資訊高度 showheight = (place == "left" || place == "right") && showheight == verify.attr.showheight ? control.outerHeight() : showheight; var size = Number(verify.getAttr(control, "showsize", verify.attr.showsize)); //提示資訊字型大小 box.css({ "position": "absolute", "z-index": 5000, "height": showheight, "width": "auto" }); //錯誤提示文字 box.find(".errorShow").css({ "white-space": "nowrap", "width": "auto", "font-size": size, "line-height": showheight + "px", "text-indent": "10px", "height": showheight, "background-color": bgcolor, "color": fgcolor, "border-radius": "2px", "padding-right": "10px" }); var offset = control.offset(); var left = 0, top = 0; //三角符號 box.find(".arrow-up").css({ "width": "0px", "height": "0px", "font-size": "0px", "line-height": "0px" }); if (place == "left") { box.find(".arrow-up").insertAfter(box.find(".errorShow")).css({ "border-top": "5px solid transparent", "border-left": "5px solid " + bgcolor, "border-bottom": "5px solid transparent", "margin-top": -showheight / 2 - 5, "margin-right": "-5px", "float": "right" }); left = offset.left - box.width() - 15; top = offset.top - 1; } if (place == "right") { box.find(".arrow-up").css({ "border-top": "5px solid transparent", "border-right": "5px solid " + bgcolor, "border-bottom": "5px solid transparent", "margin-top": showheight / 2 - 5, "float": "left" }); left = offset.left + control.width() + 5; top = offset.top - 1; box.find(".errorShow").css("float", "left"); } if (place == "bottom") { box.find(".arrow-up").css({ "border-left": "5px solid transparent", "border-right": "5px solid transparent", "border-bottom": "5px solid " + bgcolor, "margin-left": "10px" }); left = offset.left; top = offset.top + control.height() + 5; box.width(control.width() > box.width() ? control.width() + 4 : box.width()); } if (place == "top") { box.find(".arrow-up").insertAfter(box.find(".errorShow")).css({ "border-left": "5px solid transparent", "border-right": "5px solid transparent", "border-top": "5px solid " + bgcolor, "margin-left": 7, "float": "left" }); left = offset.left; top = offset.top - box.height() - 2; } box.css({ left: left, top: top }); box.css("display", "block").css({ opacity: .9 }).slideDown("slow"); if (verify.getAttr(control, "patter", "submit") == "submit") control.focus(); return false; }, //基本等同showBox,供外部呼叫,會強制顯示showTxt,忽悠控制元件的alt屬性 ShowBox: function (control, showTxt) { verify.showBox(control, showTxt, true); }, //格式化字串 format: function (str, args) { if (arguments.length < 1) return ""; var primary = arguments[0]; for (var i = 1; i < arguments.length; i++) { primary = primary.replace(eval('/\\{' + (i - 1) + '\\}/g'), arguments[i]); } return primary; }, //獲取控制元件,通過name屬性 getctl: function (name) { var ctl = $("input[name='" + name + "']:visible"); if (ctl.length < 1) ctl = $("input[name$='" + name + "']:visible"); return ctl; }, //獲取花括號中的值 getbrace: function (str) { var result = str.match(/\{(\w[^\}]+)\}/); if (result != null && result.length >= 2) return result[1]; return null; }, //驗證方法 verifyfunc: { //不能為空, //control:當前驗證的錄入控制元件 //attrval:驗證屬性的值 //input:使用者錄入的值 nullable: function (control, attrval, input) { return attrval == "false" && (input == "" || input == control.attr("deftxt")) ? verify.showBox(control, verify.errmsg.nullable.def) : true; }, //長度區間 lenlimit: function (control, attrval, input) { //取錄入的值長度 var len = input.length; if (attrval.indexOf("-") < 0) { if (len > Number(attrval)) return verify.showBox(control, verify.format(verify.errmsg.lenlimit.msg1, len - Number(attrval))); } else { var minlen = Number(attrval.substring(0, attrval.indexOf("-"))); var maxlen = Number(attrval.substring(attrval.indexOf("-") + 1)); if (minlen == maxlen && len != minlen) return verify.showBox(control, verify.format(verify.errmsg.lenlimit.def, minlen)); if (!(len >= minlen && len <= maxlen)) return verify.showBox(control, verify.format(verify.errmsg.lenlimit.msg2, minlen, maxlen)); } return true; }, //數值區間 numlimit: function (control, attrval, input) { var num = Number(input); //取錄入的值 if (isNaN(num) || num == null) return verify.showBox(control, verify.errmsg.numlimit.def); var min = 0, max = 0; if (attrval.indexOf("-") < 0) { var target = verify.getbrace(attrval); min = target != null ? Number(verify.getctl(target).val()) : Number(attrval); if (num > min) return verify.showBox(control, verify.format(verify.errmsg.numlimit.msg1, min)); } else { var pre = attrval.substring(0, attrval.indexOf("-")); var pos = attrval.substring(attrval.indexOf("-") + 1); var preCtl = verify.getbrace(pre); min = preCtl != null ? Number(verify.getctl(preCtl).val()) : Number(pre); var posCtl = verify.getbrace(pos); max = posCtl != null ? Number(verify.getctl(posCtl).val()) : Number(pos); if (min == max && num != min) return verify.showBox(control, verify.format(verify.errmsg.numlimit.msg3, min, max)); if (!(num >= min && num <= max)) return verify.showBox(control, verify.format(verify.errmsg.numlimit.msg2, min, max)); } return true; }, //驗證輸入是否相同 sametarget: function (control, attrval, input) { var same = verify.getctl(attrval); if (same.size() < 1) return true; if (input != $.trim(same.val())) return verify.showBox(control, verify.errmsg.sametarget.def); return true; }, //驗證不允許等於某值 novalue: function (control, attrval, input) { var arr = attrval.split("|"); for (var t in arr) { if (input == arr[t]) return verify.showBox(control, verify.errmsg.novalue.def); } return true; }, //上傳檔案限制,允許的檔案類弄型 fileallow: function (control, attrval, input) { if (input == "") return true; if (input.indexOf(".") > -1) input = input.substring(input.lastIndexOf(".") + 1); var arr = attrval.split("|"); for (var s in arr) { if (arr[s] == input.toLowerCase()) return true; } return verify.showBox(control, verify.format(verify.errmsg.fileallow.def, attrval.replace(/\|/g, "、"))); }, //上傳檔案限制,不允許的檔案型別 filelimit: function (control, attrval, input) { if (input == "") return true; if (input.indexOf(".") > -1) input = input.substring(input.lastIndexOf(".") + 1); var arr = attrval.split("|"); for (var s in arr) { if (arr[s] == input.toLowerCase()) return verify.showBox(control, verify.format(verify.errmsg.filelimit.def, attrval.replace(/\|/g, "、"))); } return true; }, //以限定字元開頭,可以設定多個,用|分隔 begin: function (control, attrval, input) { var arr = attrval.split("|"); for (var t in arr) { if (arr[t].length > input.length) continue; if (input.indexOf(arr[t]) == 0) return true; } return verify.showBox(control, verify.format(verify.errmsg.begin.def, arr.join())); }, //以限定字元結尾,可以設定多個,用|分隔 end: function (control, attrval, input) { var arr = attrval.split("|"); for (var t in arr) { if (arr[t].length > input.length) continue; if (input.indexOf(arr[t]) == input.length - arr[t].length) return true; } return verify.showBox(control, verify.format(verify.errmsg.end.def, arr.join())); }, //正則表示式驗證 regex: function (control, attrval, input) { var regexp = new RegExp("^" + attrval + "$", "gi"); if (!regexp.test(input)) return verify.showBox(control, verify.errmsg.regex.def); return true; }, //驗證資料型別,驗證是否為數字、帳號、email、郵編、手機號 datatype: function (control, attrval, input) { if (input == "") return true; //如果沒有錄入,則不驗證 //驗證,支援多重驗證,用|分隔 var ispass = { pass: false, err: verify.errmsg.datatype.def }; //是否通過 var typeArr = attrval.indexOf("&") > -1 ? attrval.split("&") : attrval.split("|"); //正則表示式 var regexp = { uint: { exp: /^[0-9]{1,}$/gi }, //正整數 number: { exp: /(^-?[0-9]\d*\.\d*|-0\.\d*[0-9]\d*$)|(^-?[0-9]\d*$)/gi }, //數字 float: { exp: /^(-?\d+)(\.\d+)?$/gi }, //浮點數 //tel: { exp: /^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/gi }, //固定電話 //mobile: { exp: /^1[0-9]{10}$/gi }, //行動電話 tel: { exp: /^((0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/ }, //固定電話 mobile: { exp: /^1[34578]\d{9}$/ }, //行動電話 zip: { exp: /^[0-9]{6,6}$/gi }, //郵政編碼 user: { exp: /^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){1,20}$/gi }, //賬號 email: { exp: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/gi }, //電子郵箱 idcard: { exp: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/gi }, //身份證 url: { exp: /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/gi }, //網址 qq: { exp: /^[1-9]\d{4,12}$/gi }, //qq號 chinese: { exp: /^[\u0391-\uFFE5]+$/gi }, //中文 creditcode: { exp: /^[0-9A-Z]{18}$/gi }//統一信用程式碼 }; for (var t in typeArr) { if (t < typeArr.length) { var type = $.trim(typeArr[t].toLowerCase()); for (var ex in regexp) { if (type == ex) { ispass.pass = regexp[ex].exp.test(input); if (!ispass.pass) ispass.err = eval("verify.errmsg.datatype." + ex); break; } } if (attrval.indexOf("|") > -1 && ispass.pass) break; if (attrval.indexOf("&") > -1 && !ispass.pass) break; } } if (!ispass.pass) return verify.showBox(control, ispass.err); return true; } // } }; //將內部變數賦給window,成為全域性變數 window.Verify = verify; $(function () { window.Verify.init(); }); })();
https://www.17sucai.com/preview/829123/2018-03-14/Verify_Js/index.html?file=Demo/3-4.htm 具體使用方法
<input name="" type="text" nullable="false" star="false"/>
A.屬性
非空:nullable="false" 適用於input,textarea,select
是否顯示*號:star="false"
錯誤提示資訊:alt="請選擇學歷"
檔案上傳驗證:fileallow="jpg|png" 設定上傳格式
filelimit="exe|com|bat|js" 禁止上傳exe執行檔案等有危險的檔案
字元長度驗證:lenlimit="5" 最大長度5位 長度<=5位,漢字也是一樣的,例如:"張三李四萬"也是滿足條件的
lenlimit="5-10" 長度5-10位,包含5和10
數值區間驗證:numlimit="5"(數值不得大於5) 自動驗證是數字
numlimit="5-10"(數值介於5-10之間)自動驗證是數字
商品價格驗證:
產品價格:<input name="prise" type="text" value="10" datatype="uint"/>元
最低優惠:<input name="min" type="text" value="12" datatype="uint" numlimit="{prise}"/>(優惠價不可以超過產品價格)
最大優惠:<input name="max" type="text" numlimit="{min}-{prise}"/>(最大優惠大於最低優惠,但不可以超過產品價格)
輸入是否相同:
<input name="pw1" type="text"/>
<input name="pw2" type="text" sametarget="pw1"/>(與name="pw1"的控制元件錄入相同)
sametarget="pw1" pw1為要對比的name值
不等於某值:novalue="|1|2",即不得等於1和2 input,select,textarea同樣適用
資料型別驗證:
正整數:datatype="uint"
datatype="chinese" //僅限中文字元
datatype="user",字元或數字,且字元開頭
datatype="number",可以帶小數,或負數
datatype="tel" ,電話
datatype="mobile" ,手機
datatype="zip" , 郵編
datatype="email" , 郵箱
datatype="idcard" , 身份證驗證,只有驗證了長度,和型別
datatype="qq" , qq號
datatype="url" , 網址
多條件使用,滿足任意一個即可:datatype="tel|mobile"
滿足所有條件:datatype="uint&zip"
驗證以xxx開頭:begin="http://|https://|ftp://"
驗證以xxx結尾:end="@qq.com"
正則表示式驗證:regex="\d+" 純數字
regex="[a-z]+" 純字母
失去焦點時驗證:patter="focus" 單個input上加是單個文字框失去焦點時,如果在form上加patter="focus"則所有需要驗證的文字框都是在失去焦點的時候進行驗證
提示資訊顯示位置:place="right" place="top" place="left" place="bottom" 在form上加表示所有都在某個方向提示
設定提示資訊背景色和字型顏色:bgcolor="#33f" fgcolor="#FF9" 在form上加表示所有提示都是指定顏色
分組驗證:通過group="a" 對輸入框進行分組
B.點選提交時驗證
if (Verify.IsPass($("#formData"))) {
var fordata = $("#formData input,#formData select,#formData textarea").serialize();
if ($("#formData input,#formData select,#formData textarea").length > 5) {
var data = {
resutl: true,
data: fordata,
msg: 'ok'
};
return data;
}
}
C.驗證b組的資訊是否完全通過
if(Verify.IsPass($("form"),"b")){
alert("b組驗證通過");
};
3.layui tree 懶載入使用
使用:
A.引入相關js檔案
/* 最外層容器 */ .ew-tree-table { margin: 10px 0; position: relative; } .ew-tree-table .layui-table { margin: 0; table-layout: fixed; } /* 表格容器 */ .ew-tree-table-group { position: relative; } /* 主體表格容器 */ .ew-tree-table > .ew-tree-table-group > .ew-tree-table-box { overflow: auto; position: relative; box-sizing: border-box; } /* 表頭表格容器 */ .ew-tree-table > .ew-tree-table-group > .ew-tree-table-head { overflow: hidden; position: relative; box-sizing: border-box; background-color: #f2f2f2; } /* 容器加邊框 */ .ew-tree-table .ew-tree-table-border { position: absolute; background-color: #e6e6e6; } .ew-tree-table .ew-tree-table-border.top { left: 0; right: 0; top: 0; height: 1px; } .ew-tree-table .ew-tree-table-border.left { top: 0; left: 0; bottom: 0; width: 1px; } .ew-tree-table .ew-tree-table-border.right { top: 0; right: 0; bottom: 0; width: 0.52px; } .ew-tree-table .ew-tree-table-border.bottom { left: 0; right: 0; bottom: 0; height: 0.52px; } /* table的loading */ .ew-tree-table .ew-tree-table-box > .ew-tree-table-loading { padding: 10px 0; text-align: center; } .ew-tree-table .ew-tree-table-box > .ew-tree-table-loading > i { color: #999; font-size: 30px; } .ew-tree-table .ew-tree-table-box > .ew-tree-table-loading.ew-loading-float { position: absolute; left: 0; right: 0; top: 0; } /* 空資料提示 */ .ew-tree-table .ew-tree-table-box > .ew-tree-table-empty { color: #666; font-size: 14px; text-align: center; } /* 摺疊箭頭 */ .ew-tree-table .ew-tree-table-arrow { margin-right: 5px; vertical-align: middle; } .ew-tree-table .ew-tree-table-arrow:before { content: "\e623"; } .ew-tree-table .ew-tree-table-open .ew-tree-table-arrow:before { content: "\e625"; } .ew-tree-table .ew-tree-table-arrow.arrow2 { font-size: 13px; font-weight: 600; line-height: 16px; height: 16px; width: 16px; display: inline-block; text-align: center; color: #888; } .ew-tree-table .ew-tree-table-arrow.arrow2:before { content: "\e602"; } .ew-tree-table .ew-tree-table-open .ew-tree-table-arrow.arrow2:before { content: "\e61a"; } /* 箭頭隱藏 */ .ew-tree-table-arrow.ew-tree-table-arrow-hide { visibility: hidden; } /* 箭頭變載入中狀態 */ .ew-tree-table .ew-tree-table-loading > td .ew-tree-pack > .ew-tree-table-arrow:before { content: "\e63d" !important; } .ew-tree-table .ew-tree-table-loading > td .ew-tree-pack > .ew-tree-table-arrow { margin-right: 0; } .ew-tree-table .ew-tree-table-loading > td .ew-tree-pack > .ew-tree-table-arrow + * { margin-left: 5px; } /* tr載入中禁用事件 */ .ew-tree-table tr.ew-tree-table-loading > * { pointer-events: none !important; } /* 圖示列 */ .ew-tree-table .ew-tree-pack { cursor: pointer; line-height: 16px; display: inline-block; vertical-align: middle; } .ew-tree-table .ew-tree-pack > span { height: 16px; line-height: 16px; display: inline-block; vertical-align: middle; } /* 摺疊行 */ .ew-tree-table .ew-tree-tb-hide { display: none; } /* 縮排 */ .ew-tree-table .ew-tree-table-indent { margin-right: 5px; padding-left: 16px; } /* 圖示 */ .ew-tree-table .ew-tree-icon { margin-right: 5px; display: inline-block; vertical-align: middle; } .ew-tree-table .ew-tree-icon-folder, .ew-tree-table .ew-tree-icon-file { width: 22px; height: 16px; line-height: 16px; position: relative; } .ew-tree-table .ew-tree-icon-folder:after, .ew-tree-table .ew-tree-icon-file:after { content: ""; width: 22px; height: 22px; position: absolute; left: 0; top: -3px; background-size: cover; background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc0MDYyMzE3MTQ3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIxNTgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNjQiIGhlaWdodD0iNjQiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTE4MSA4MjNoLTMxLjFjLTI4LjYgMC01MS45LTIzLjItNTEuOS01MS45VjI1Mi40YzAtMjguNiAyMy4yLTUxLjkgNTEuOS01MS45SDQzMGw4MyA3Ny44aDMzMmM0NS42IDAgODMgMzUgODMgNzcuOHYzODkuMWMwIDQyLjgtMzcuMyA3Ny44LTgzIDc3LjhIMTgxeiIgcC1pZD0iMjE1OSIgZmlsbD0iI0ZGQTUwMCI+PC9wYXRoPjwvc3ZnPg==") } .ew-tree-table tr.ew-tree-table-open > td > .ew-tree-pack .ew-tree-icon-folder:after { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc0MDYyMzA5MDQwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE5NzciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNjQiIGhlaWdodD0iNjQiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTMyNi40IDQ2MC4xSDkyOGwtODIuMyAzMjRjLTUuOCAyMy0yNi42IDM5LjEtNTAuMyAzOS4xSDE0OS45Yy0yOC42IDAtNTEuOS0yMy4yLTUxLjktNTEuOVYyNTIuNmMwLTI4LjYgMjMuMi01MS45IDUxLjktNTEuOUg0MTNsMTA1IDEwMy43aDI5MS44YzE0LjMgMCAyNS45IDExLjYgMjUuOSAyNS45djc3LjhoLTUyN0wyMDMuNCA1NjMuOWg1Mi43bDcwLjMtMTAzLjh6IiBwLWlkPSIxOTc4IiBmaWxsPSIjRkZBNTAwIj48L3BhdGg+PC9zdmc+") } .ew-tree-table .ew-tree-icon-file:after { background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc0MDYyNTE1MDUxIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEzNTE4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0Ij48ZGVmcz48c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwvc3R5bGU+PC9kZWZzPjxwYXRoIGQ9Ik03NDEuMyAxNjEuNmgtNDIuNGMtMTAuNSAwLTE5LjEgOC42LTE5LjEgMTkuMXM4LjYgMTkuMSAxOS4xIDE5LjFoNDIuNGM0MiAwIDc2LjIgMzQuMiA3Ni4yIDc2LjN2NDc3LjRjMCA0Mi4xLTM0LjMgNzYuMy03Ni40IDc2LjNIMjgyLjljLTQyLjEgMC03Ni4zLTM0LjItNzYuMy03Ni4zVjI3Ni4xYzAtNDIuMSAzNC4yLTc2LjMgNzYuMy03Ni4zaDQ0LjljMTAuNSAwIDE5LjEtOC42IDE5LjEtMTkuMXMtOC42LTE5LjEtMTkuMS0xOS4xaC00NC45Yy02My4xIDAtMTE0LjUgNTEuNC0xMTQuNSAxMTQuNXY0NzcuNGMwIDYzLjEgNTEuNCAxMTQuNSAxMTQuNSAxMTQuNWg0NTguM2M2My4xIDAgMTE0LjUtNTEuNCAxMTQuNS0xMTQuNVYyNzYuMWMtMC4xLTYzLjEtNTEuNC0xMTQuNS0xMTQuNC0xMTQuNXoiIHAtaWQ9IjEzNTE5IiBmaWxsPSIjRkZBNTAwIj48L3BhdGg+PHBhdGggZD0iTTY4MC42IDUwNS4zSDM0My40Yy0xMi4zIDAtMjIuMyA4LjYtMjIuMyAxOS4xczEwIDE5LjEgMjIuMyAxOS4xaDMzNy4yYzEyLjMgMCAyMi4zLTguNiAyMi4zLTE5LjEgMC0xMC42LTEwLTE5LjEtMjIuMy0xOS4xek00MzkuMyAyMTMuM2gxNDQuNmMxOSAwIDM0LjQtMTIuOCAzNC40LTI4LjZzLTE1LjQtMjguNi0zNC40LTI4LjZINDM5LjNjLTE5IDAtMzQuNCAxMi44LTM0LjQgMjguNi0wLjEgMTUuNyAxNS4zIDI4LjYgMzQuNCAyOC42ek02ODAuNiA2NThIMzQzLjRjLTEyLjMgMC0yMi4zIDguNS0yMi4zIDE5LjEgMCAxMC41IDEwIDE5LjEgMjIuMyAxOS4xaDMzNy4yYzEyLjMgMCAyMi4zLTguNiAyMi4zLTE5LjEgMC0xMC42LTEwLTE5LjEtMjIuMy0xOS4xek02ODAuNiAzNTIuNUgzNDMuNGMtMTIuMyAwLTIyLjMgOC42LTIyLjMgMTkuMXMxMCAxOS4xIDIyLjMgMTkuMWgzMzcuMmMxMi4zIDAgMjIuMy04LjYgMjIuMy0xOS4xIDAtMTAuNS0xMC0xOS4xLTIyLjMtMTkuMXoiIHAtaWQ9IjEzNTIwIiBmaWxsPSIjRkZBNTAwIj48L3BhdGg+PC9zdmc+") } /* 序號列調整 */ .ew-tree-table td[data-type="numbers"] { padding-left: 0; padding-right: 0; text-align: center; } /* 單元格內表單元素樣式調整 */ .ew-tree-table .layui-form-switch { margin-top: 0; } .ew-tree-table .layui-form-radio { margin: 0; } /* checkbox和radio列調整 */ .ew-tree-table-checkbox + .layui-form-checkbox { padding: 0; } .ew-tree-table-checkbox + .layui-form-checkbox > .layui-icon { color: transparent; transition: background-color .1s linear; } .ew-tree-table-checkbox + .layui-form-checkbox.layui-form-checked > .layui-icon { color: #fff; } .ew-tree-table-radio + .layui-form-radio { padding: 0; height: 20px; line-height: 20px; } .ew-tree-table-radio + .layui-form-radio > i { margin: 0; height: 20px; font-size: 20px; line-height: 20px; } /* checkbox半選狀態 */ .ew-tree-table .layui-form-checked.ew-form-indeterminate > .layui-icon:before { content: ""; width: 9px; height: 2px; display: inline-block; background-color: #eee; vertical-align: middle; } .ew-tree-table .layui-form-checked.ew-form-indeterminate > .layui-icon { line-height: 14px; } /* 單元格編輯 */ .ew-tree-table .layui-table td[data-edit] { cursor: text; } .ew-tree-table .ew-tree-table-edit { position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 0; box-shadow: 1px 1px 20px rgba(0, 0, 0, .15); } .ew-tree-table .ew-tree-table-edit:focus { border-color: #5FB878 !important; } .ew-tree-table .ew-tree-table-edit.layui-form-danger { border-color: #FF5722 !important; } /* 搜尋資料隱藏行 */ .ew-tree-table tr.ew-tree-table-filter-hide { display: none !important; } /* 單元格超出隱藏 */ .ew-tree-table-td-single { position: relative; } .ew-tree-table-td-single > .ew-tree-tips { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .ew-tree-table-td-single > .ew-tree-tips-c { position: absolute; right: -10px; top: -6px; width: 24px; height: 24px; line-height: 24px; font-size: 18px; text-align: center; color: #fff; border-radius: 50%; background-color: #666; cursor: pointer; display: none; } .ew-tree-table table tr:first-child .ew-tree-table-td-single > .ew-tree-tips-c { top: 2px; bottom: auto; right: -12px; } .ew-tree-table-td-single.ew-tree-tips-open { position: absolute; top: 0; left: 0; z-index: 5; background-color: #fff; min-height: 100%; box-sizing: border-box; box-shadow: 3px 3px 8px rgba(0, 0, 0, .15); } .ew-tree-table table thead .ew-tree-table-td-single.ew-tree-tips-open { background-color: #f2f2f2; } .ew-tree-table-td-single.ew-tree-tips-open.ew-show-left { right: 0; left: auto; box-shadow: -3px 3px 8px rgba(0, 0, 0, .15); } .ew-tree-table-td-single.ew-tree-tips-open.ew-show-bottom { bottom: 0; top: auto; box-shadow: 3px -3px 8px rgba(0, 0, 0, .15); } .ew-tree-table-td-single.ew-tree-tips-open.ew-show-left.ew-show-bottom { box-shadow: -3px -3px 8px rgba(0, 0, 0, .15); } .ew-tree-table-td-single.ew-tree-tips-open > .ew-tree-tips { padding: 9px 15px; overflow: auto; max-width: 280px; max-height: 100px; width: max-content; white-space: normal; } .ew-tree-table-td-single.ew-tree-tips-open > .ew-tree-tips-c { display: block; } .ew-tree-table-td-single.ew-tree-tips-open.ew-show-left > .ew-tree-tips-c { left: -10px; right: auto !important; } .ew-tree-table td > .layui-table-grid-down { bottom: 0; height: auto; } /* 輔助樣式 */ .pd-tb-0 { padding-top: 0 !important; padding-bottom: 0 !important; } .break-all { word-break: break-all !important; } /* 列寬拖拽調整 */ /*.ew-tree-table .ew-tb-resize { position: absolute; right: 0; top: 0; bottom: 0; width: 10px; cursor: col-resize; }*/treeTable.css
/** * 樹形表格 2.x * date:2019-11-08 License By http://easyweb.vip */ layui.define(['layer', 'laytpl', 'form'], function (exports) { var $ = layui.jquery; var layer = layui.layer; var laytpl = layui.laytpl; var form = layui.form; var device = layui.device(); var MOD_NAME = 'treeTable'; // 繫結事件的模組名 // 改為同步載入css,避免滾動條補丁首次進入無效 $.ajax({ url: layui.cache.base + 'treeTable/treeTable.css', async: false, success: function (res) { $('head').append('<style id="ew-tree-table-css">' + res + '</style>'); } }); /** TreeTable類構造方法 */ var TreeTable = function (options) { // 表格預設引數 var defaultOption = { elem: undefined, // table容器 data: [], // 資料 cols: [], // 列配置 reqData: undefined, // 非同步載入資料的方法 width: undefined, // 容器寬度 height: undefined, // 容器高度 cellMinWidth: 100, // 單元格最小寬度 skin: undefined, // 表格風格 size: undefined, // 表格尺寸 even: undefined, // 是否開啟隔行變色 style: undefined, // 容器樣式 showtooobar: false, EdidLEVEL: undefined, getThead: function () { // 獲取表頭 return getThead(this); }, getAllChooseBox: function () { // 獲取全選按鈕 return getAllChooseBox(this); }, getColgroup: function () { // 獲取colgroup return getColgroup(this); }, getTbWidth: function () { // 計算table的寬度 return getTbWidth(this); }, tree: {}, text: {} }; // 預設tree引數 var treeDefaultOption = { idName: 'id', // id的欄位名 pidName: 'pid', // pid的欄位名 childName: 'children', // children的欄位名 haveChildName: 'haveChild', // 是否有children標識的欄位名 openName: 'open', // 是否預設展開的欄位名 isPidData: false, // 是否是pid形式的資料 iconIndex: 0, // 圖示列的索引 arrowType: undefined, // 箭頭型別 onlyIconControl: false, // 僅允許點選圖示摺疊 getIcon: function (d) { // 自定義圖示 return getIcon(d, this); } }; // 預設提示文字 var textDefaultOption = { none: '<div style="padding: 18px 0;">暫無資料</div>' // 空文字提示文字 }; this.options = $.extend(defaultOption, options); this.options.tree = $.extend(treeDefaultOption, options.tree); this.options.text = $.extend(textDefaultOption, options.text); for (var i = 0; i < options.cols.length; i++) { // 列預設引數 var colDefaultOption = { field: undefined, // 欄位名 title: undefined, // 標題 align: undefined, // 對齊方式 templet: undefined, // 自定義模板 toolbar: undefined, // 工具列 toolbarDel: undefined, width: undefined, // 寬度 minWidth: undefined, // 最小寬度 type: undefined, // 列型別 style: undefined, // 單元格樣式 IsEdit: undefined, LEVEL: undefined, class: '', // 單元格class singleLine: true, // 一行顯示 fixed: undefined, // 固定列 unresize: false // 關閉拖拽列寬 }; this.options.cols[i] = $.extend(colDefaultOption, options.cols[i]); } this.init(); // 初始化表格 this.bindEvents(); // 繫結事件 }; /** 初始化表格 */ TreeTable.prototype.init = function () { var options = this.options; var tbFilter = options.elem.substring(1); // 樹表格的filter var $elem = $(options.elem); // 原始表格 // 生成樹表格dom $elem.removeAttr('lay-filter'); $elem.next('.ew-tree-table').remove(); var viewHtml = '<div class="layui-form ew-tree-table" style="' + (options.style || '') + '">'; viewHtml += ' <div class="ew-tree-table-group">'; viewHtml += ' <div class="ew-tree-table-head">'; viewHtml += ' <table class="layui-table"></table>'; viewHtml += ' <div class="ew-tree-table-border"></div>'; viewHtml += ' </div>'; viewHtml += ' <div class="ew-tree-table-box">'; viewHtml += ' <table class="layui-table"></table>'; viewHtml += ' <div class="ew-tree-table-loading"><i class="layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i></div>'; viewHtml += ' <div class="ew-tree-table-empty" style="display: none;">' + (options.text.none || '') + '</div>'; viewHtml += ' </div>'; viewHtml += ' </div>'; viewHtml += ' <div class="ew-tree-table-border top"></div><div class="ew-tree-table-border left"></div>'; viewHtml += ' <div class="ew-tree-table-border right"></div><div class="ew-tree-table-border"></div>'; viewHtml += ' </div>'; $elem.after(viewHtml); // 獲取各個元件 var components = this.getComponents(); var $view = components.$view; // 容器 $view.attr('lay-filter', tbFilter); var $group = components.$group; // 表格容器 var $tbBox = components.$tbBox; // 表格主體部分容器 var $table = components.$table; // 主體表格 var $headTb = components.$headTb; // 表頭表格 var $tbEmpty = components.$tbEmpty; // 空檢視 var $tbLoading = components.$tbLoading; // 空檢視 // 基礎引數設定 options.skin && $table.attr('lay-skin', options.skin); options.size && $table.attr('lay-size', options.size); options.even && $table.attr('lay-even', options.even); // 容器邊框調整 if (device.ie) { $view.find('.ew-tree-table-border.bottom').css('height', '1px'); $view.find('.ew-tree-table-border.right').css('width', '1px'); } // 固定寬度 if (options.width) { $view.css('width', options.width); $headTb.parent().css('width', options.width); $tbBox.css('width', options.width); } // col最小寬度 var tbWidth = options.getTbWidth(); if (tbWidth.setWidth) { $table.css('width', "100%"); $headTb.css('width', "100%"); } else { $table.css('min-width', tbWidth.minWidth); $headTb.css('min-width', tbWidth.minWidth); } // 渲染表結構及表頭 var colgroupHtmlStr = options.getColgroup(); var headHtmlStr = colgroupHtmlStr + '<thead>' + options.getThead() + '</thead>'; if (options.height) { // 固定表頭 $table.html(colgroupHtmlStr + '<tbody></tbody>'); $headTb.html(headHtmlStr); $table.css('margin-top', '-1px'); if (options.height.indexOf('full-') == 0) { // 差值高度 var h = parseFloat(options.height.substring(5)); var cssStr = '<style>.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box {'; cssStr += ' height: ' + (getPageHeight() - h) + 'px;'; cssStr += ' height: -moz-calc(100vh - ' + h + 'px);'; cssStr += ' height: -webkit-calc(100vh - ' + h + 'px);'; cssStr += ' height: calc(100vh - ' + h + 'px);'; cssStr += ' }</style>'; $tbBox.after(cssStr); $tbBox.attr('ew-tree-full', h); } else { // 固定高度 $tbBox.css('height', options.height); } } else { $table.html(headHtmlStr + '<tbody></tbody>'); } form.render('checkbox', tbFilter); // 渲染表頭的表單元素 // 渲染資料 if (options.reqData) { // 非同步載入 this.renderBodyAsync(); } else { // 一次性渲染 if (options.data && options.data.length > 0) { // 處理資料 if (options.tree.isPidData) { // pid形式資料 options.data = treeTb.pidToChildren(options.data, options.tree.idName, options.tree.pidName, options.tree.childName); } else { // children形式資料 addPidField(options.data, options.tree); } $table.children('tbody').html(this.renderBody(options.data)); $tbLoading.hide(); this.renderNumberCol(); // 渲染序號列 form.render(null, tbFilter); // 渲染表單元素 this.checkChooseAllCB(); // 聯動全選框 updateFixedTbHead($view); } else { $tbLoading.hide(); $tbEmpty.show(); } } }; /** 繫結各項事件 */ TreeTable.prototype.bindEvents = function () { var that = this; var options = this.options; var components = this.getComponents(); var $view = components.$view; var $table = components.$table; var $tbEmpty = components.$tbEmpty; var tbFilter = components.tbFilter; var checkboxFilter = components.checkboxFilter; var radioFilter = components.radioFilter; var cbAllFilter = components.cbAllFilter; var $tbody = $table.children('tbody'); /** 行事件公共返回物件 */ var commonMember = function (ext) { var $tr = $(this); if (!$tr.is('tr')) { var $td_tr = $tr.parent('tr[data-id]'); if ($td_tr.length > 0) { $tr = $td_tr; } else { $tr = $tr.parentsUntil('tr[data-id]').last().parent(); } } var id = $tr.data('id'); var data = getDataById(options.data, id, options.tree); var obj = { tr: $tr, // 當前行 data: data, //當前行資料 del: function () { // 刪除行 var indent = parseInt(this.tr.data('indent')); this.tr.nextAll('tr').each(function () { if (parseInt($(this).data('indent')) <= indent) { return false; } $(this).remove(); }); var $parentTr = this.tr.prevAll('tr'); this.tr.remove(); delDataById(options.data, id, options.tree); if (!options.data || options.data.length <= 0) { $tbEmpty.show(); } that.renderNumberCol(); // 渲染序號列 // 聯動父級 $parentTr.each(function () { var tInd = parseInt($(this).data('indent')); if (tInd < indent) { that.checkParentCB($(this)); indent = tInd; } }); that.checkChooseAllCB(); // 聯動全選框 }, update: function (fields) { // 修改行 data = $.extend(data, fields); var indent = parseInt(this.tr.data('indent')); that.renderBodyTr(data, indent, undefined, this.tr); form.render(null, tbFilter); // 渲染表單元素 that.checkIndeterminateCB(); // 恢復半選框狀態 that.checkChooseAllCB(); // 聯動全選框 } }; return $.extend(obj, ext); }; // 繫結摺疊展開事件 $tbody.off('click.fold').on('click.fold', '.ew-tree-pack', function (e) { layui.stope(e); var $tr = $(this).parentsUntil('tr').last().parent(); if ($tr.hasClass('ew-tree-table-loading')) { // 已是載入中 return; } var haveChild = $tr.data('have-child'); if (haveChild != true && haveChild != 'true') { // 子節點 return; } var id = $tr.data('id'); var isOpen = $tr.hasClass('ew-tree-table-open'); var data = getDataById(options.data, id, options.tree); if (!isOpen && (!data[options.tree.childName] || data[options.tree.childName].length <= 0)) { that.renderBodyAsync(data, $tr); } else { toggleRow($tr); } }); // 繫結lay-event事件 $tbody.off('click.tool').on('click.tool', '*[lay-event]', function (e) { layui.stope(e); var $this = $(this); layui.event.call(this, MOD_NAME, 'tool(' + tbFilter + ')', commonMember.call(this, { event: $this.attr('lay-event') })); }); // 繫結單選框事件 form.on('radio(' + radioFilter + ')', function (data) { var d = getDataById(options.data, data.value, options.tree); that.removeAllChecked(); d.LAY_CHECKED = true; // 同時更新資料 layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', { checked: true, data: d, type: 'one' }); }); // 繫結複選框事件 form.on('checkbox(' + checkboxFilter + ')', function (data) { var checked = data.elem.checked; var $cb = $(data.elem); var $layCb = $cb.next('.layui-form-checkbox'); // 如果是半選狀態,點選全選 if (!checked && $layCb.hasClass('ew-form-indeterminate')) { checked = true; $cb.prop('checked', checked); $cb.data('indeterminate', 'false'); $layCb.addClass('layui-form-checked'); $layCb.removeClass('ew-form-indeterminate'); } var d = getDataById(options.data, data.value, options.tree); d.LAY_CHECKED = checked; // 同時更新資料 // 聯動操作 var $tr = $cb.parentsUntil('tr').last().parent(); if (d[options.tree.childName] && d[options.tree.childName].length > 0) { that.checkSubCB($tr, checked); // 聯動子級 } var indent = parseInt($tr.data('indent')); $tr.prevAll('tr').each(function () { var tInd = parseInt($(this).data('indent')); if (tInd < indent) { that.checkParentCB($(this)); // 聯動父級 indent = tInd; } }); that.checkChooseAllCB(); // 聯動全選框 // 回撥事件 layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', { checked: checked, data: d, type: 'one' }); }); // 繫結全選複選框事件 form.on('checkbox(' + cbAllFilter + ')', function (data) { var checked = data.elem.checked; var $cb = $(data.elem); var $layCb = $cb.next('.layui-form-checkbox'); if (!options.data || options.data.length <= 0) { // 如果資料為空 $cb.prop('checked', false); $cb.data('indeterminate', 'false'); $layCb.removeClass('layui-form-checked ew-form-indeterminate'); return; } // 如果是半選狀態,點選全選 if (!checked && $layCb.hasClass('ew-form-indeterminate')) { checked = true; $cb.prop('checked', checked); $cb.data('indeterminate', 'false'); $layCb.addClass('layui-form-checked'); $layCb.removeClass('ew-form-indeterminate'); } layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', { checked: checked, data: undefined, type: 'all' }); that.checkSubCB($table.children('tbody'), checked); // 聯動操作 }); // 繫結行單擊事件 $tbody.off('click.row').on('click.row', 'tr', function () { layui.event.call(this, MOD_NAME, 'row(' + tbFilter + ')', commonMember.call(this, {})); }); // 繫結行雙擊事件 $tbody.off('dblclick.rowDouble').on('dblclick.rowDouble', 'tr', function () { layui.event.call(this, MOD_NAME, 'rowDouble(' + tbFilter + ')', commonMember.call(this, {})); }); // 繫結單元格點選事件 $tbody.off('click.cell').on('click.cell', 'td', function (e) { var $td = $(this); var type = $td.data('type'); // 判斷是否是複選框、單選框列 if (type == 'checkbox' || type == 'radio') { layui.stope(e); return; } var edit = $td.data('edit'); var field = $td.data('field'); if (edit) { // 開啟了單元格編輯 layui.stope(e); if ($tbody.find('.ew-tree-table-edit').length > 0) { return; } var index = $td.data('index'); var indentSize = $td.children('.ew-tree-table-indent').length; var id = $td.parent().data('id'); var d = getDataById(options.data, id, options.tree); if ('text' == edit || 'number' == edit) { // 文字框 var $input = $('<input type="' + edit + '" class="layui-input ew-tree-table-edit"/>'); $input[0].value = d[field]; $td.append($input); $input.focus(); $input.blur(function () { var value = $(this).val(); if (value == d[field]) { $(this).remove(); return; } var rs = layui.event.call(this, MOD_NAME, 'edit(' + tbFilter + ')', commonMember.call(this, { value: value, field: field })); if (rs == false) { $(this).addClass('layui-form-danger'); $(this).focus(); } else { d[field] = value; // 同步更新資料 that.renderBodyTd(d, indentSize, index, $td); // 更新單元格 } }); } else { console.error('不支援的單元格編輯型別:' + edit); } } else { // 回撥單元格點選事件 var rs = layui.event.call(this, MOD_NAME, 'cell(' + tbFilter + ')', commonMember.call(this, { td: $td, field: field })); if (rs == false) { layui.stope(e); } } }); // 繫結單元格雙擊事件 $tbody.off('dblclick.cellDouble').on('dblclick.cellDouble', 'td', function (e) { var $td = $(this); var type = $td.data('type'); // 判斷是否是複選框、單選框列 if (type == 'checkbox' || type == 'radio') { layui.stope(e); return; } var edit = $td.data('edit'); var field = $td.data('field'); if (edit) { // 開啟了單元格編輯 layui.stope(e); } else { // 回撥單元格雙擊事件 var rs = layui.event.call(this, MOD_NAME, 'cellDouble(' + tbFilter + ')', commonMember.call(this, { td: $td, field: field })); if (rs == false) { layui.stope(e); } } }); // 同步滾動條 components.$tbBox.on('scroll', function () { var $this = $(this); var scrollLeft = $this.scrollLeft(); var scrollTop = $this.scrollTop(); components.$headTb.parent().scrollLeft(scrollLeft); // $headGroup.scrollTop(scrollTop); }); // 列寬拖拽調整 /*$view.off('mousedown.resize').on('mousedown.resize', '.ew-tb-resize', function (e) { layui.stope(e); var index = $(this).parent().data('index'); $(this).data('move', 'true'); $(this).data('x', e.clientX); var w = $(this).parent().parent().parent().parent().children('colgroup').children('col').eq(index).attr('width'); $(this).data('width', w); }); $view.off('mousemove.resize').on('mousemove.resize', '.ew-tb-resize', function (e) { layui.stope(e); var move = $(this).data('move'); if ('true' == move) { var x = $(this).data('x'); var w = $(this).data('width'); var index = $(this).parent().data('index'); var nw = parseFloat(w) + e.clientX - parseFloat(x); $(this).parent().parent().parent().parent().children('colgroup').children('col').eq(index).attr('width', nw); } }); $view.off('mouseup.resize').on('mouseup.resize', '.ew-tb-resize', function (e) { layui.stope(e); $(this).data('move', 'false'); }); $view.off('mouseleave.resize').on('mouseleave.resize', '.ew-tb-resize', function (e) { layui.stope(e); $(this).data('move', 'false'); });*/ }; /** 獲取各個元件 */ TreeTable.prototype.getComponents = function () { var $view = $(this.options.elem).next(); // 容器 var $group = $view.children('.ew-tree-table-group'); // 表格容器 var $tbBox = $group.children('.ew-tree-table-box'); // 表格主體部分容器 var $table = $tbBox.children('.layui-table'); // 主體表格 var $headTb = $group.children('.ew-tree-table-head').children('.layui-table'); // 表頭表格 var $tbEmpty = $tbBox.children('.ew-tree-table-empty'); // 空檢視 var $tbLoading = $tbBox.children('.ew-tree-table-loading'); // 載入檢視 var tbFilter = $view.attr('lay-filter'); // 容器filter var checkboxFilter = 'ew_tb_checkbox_' + tbFilter; // 複選框filter var radioFilter = 'ew_tb_radio_' + tbFilter; // 單選框filter var cbAllFilter = 'ew_tb_choose_all_' + tbFilter; // 全選按鈕filter return { $view: $view, $group: $group, $tbBox: $tbBox, $table: $table, $headTb: $headTb, $tbEmpty: $tbEmpty, $tbLoading: $tbLoading, tbFilter: tbFilter, checkboxFilter: checkboxFilter, radioFilter: radioFilter, cbAllFilter: cbAllFilter }; }; /** * 遞迴渲染表格主體部分 * @param data 資料列表 * @param indentSize 縮排大小 * @param isHide 是否預設隱藏 * @returns {string} */ TreeTable.prototype.renderBody = function (data, indentSize, isHide) { var options = this.options; var treeOption = options.tree; indentSize || (indentSize = 0); var htmlStr = ''; for (var i = 0; i < data.length; i++) { var d = data[i]; htmlStr += this.renderBodyTr(d, indentSize, isHide); // 遞迴渲染子集 var children = d[treeOption.childName]; if (children && children.length > 0) { htmlStr += this.renderBody(children, indentSize + 1, !d[treeOption.openName]); } } return htmlStr; }; /** * 渲染一行資料 * @param d 行資料 * @param option 配置 * @param indentSize 縮排大小 * @param isHide 是否隱藏 * @param $tr * @returns {string} */ TreeTable.prototype.renderBodyTr = function (d, indentSize, isHide, $tr) { var options = this.options; var cols = options.cols; var treeOption = options.tree; indentSize || (indentSize = 0); var htmlStr = ''; var haveChild = getHaveChild(d, treeOption); if ($tr) { $tr.data('pid', d[treeOption.pidName] || ''); $tr.data('have-child', haveChild); $tr.data('indent', indentSize); $tr.removeClass('ew-tree-table-loading'); } else { var classNames = ''; if (haveChild && d[treeOption.openName]) { classNames += 'ew-tree-table-open'; } if (isHide) { classNames += 'ew-tree-tb-hide'; } htmlStr += '<tr class="' + classNames + '" data-id="' + d[treeOption.idName] + '"'; htmlStr += ' data-pid="' + (d[treeOption.pidName] || '') + '" data-have-child="' + haveChild + '"'; htmlStr += ' data-indent="' + indentSize + '">'; } for (var j = 0; j < cols.length; j++) { var $td; if ($tr) { $td = $tr.children('td').eq(j); } htmlStr += this.renderBodyTd(d, indentSize, j, $td); } htmlStr += '</tr>'; return htmlStr; }; /** * 渲染每一個單元格資料 * @param d 行資料 * @param indentSize 縮排大小 * @param index 第幾列 * @param $td * @returns {string} */ TreeTable.prototype.renderBodyTd = function (d, indentSize, index, $td) { var options = this.options; var col = options.cols[index]; var treeOption = options.tree; var components = this.getComponents(); var checkboxFilter = components.checkboxFilter; var radioFilter = components.radioFilter; indentSize || (indentSize = 0); // 內容填充 var fieldStr = ''; var isedit = false; if (col.IsEdit != undefined) { isedit = d[col.IsEdit] == null || d[col.IsEdit] == undefined; console.log(d[col.IsEdit]); } var coledit = false; if (col.LEVEL != undefined && options.EdidLEVEL != undefined) { if (d[col.LEVEL] <= options.EdidLEVEL) coledit = true; } if (col.type == 'numbers') { // 序號列 fieldStr += '<span class="ew-tree-table-numbers"></span>'; col.singleLine = false; } else if (col.type == 'checkbox') { // 複選框列 var attrStr = 'name="' + checkboxFilter + '" lay-filter="' + checkboxFilter + '" value="' + d[treeOption.idName] + '"'; attrStr += d.LAY_CHECKED ? ' checked="checked"' : ''; fieldStr += '<input type="checkbox" lay-skin="primary" ' + attrStr + ' class="ew-tree-table-checkbox" />'; col.singleLine = false; } else if (col.type == 'radio') { // 單選框列 var attrStr = 'name="' + radioFilter + '" lay-filter="' + radioFilter + '" value="' + d[treeOption.idName] + '"'; attrStr += d.LAY_CHECKED ? ' checked="checked"' : ''; fieldStr += '<input type="radio" ' + attrStr + ' class="ew-tree-table-radio" />'; col.singleLine = false; } else if (col.templet) { // 自定義模板 if (typeof col.templet == 'function') { fieldStr += col.templet(d); } else if (typeof col.templet == 'string') { laytpl($(col.templet).html()).render(d, function (html) { fieldStr += html; }); } } else if (col.toolbar) { // 工具列 var isshowtoobar = this.options.showtooobar; laytpl(coledit ? $(col.toolbar).html() : $(col.toolbarDel).html()).render(d, function (html) { if (!d.haveChild && isshowtoobar) fieldStr += html; }); } else if (col.field && d[col.field] != undefined && d[col.field] != null) { // 普通欄位 fieldStr += d[col.field]; } var tdStr = ''; // 圖示列處理 if (index == treeOption.iconIndex) { // 縮排 for (var k = 0; k < indentSize; k++) { tdStr += '<span class="ew-tree-table-indent"></span>'; } tdStr += '<span class="ew-tree-pack">'; // 加箭頭 var haveChild = getHaveChild(d, treeOption); tdStr += ('<i class="layui-icon ew-tree-table-arrow ' + (haveChild ? '' : 'ew-tree-table-arrow-hide') + ' ' + (options.tree.arrowType || '') + '"></i>'); // 加圖示 tdStr += treeOption.getIcon(d); if (options.tree.onlyIconControl) { tdStr += '</span>'; tdStr += ('<span>' + fieldStr + '</span>'); } else { tdStr += ('<span>' + fieldStr + '</span>'); tdStr += '</span>'; } } else { tdStr += fieldStr; } if ($td && col.type != 'numbers') { $td.html(tdStr); } var htmlStr = '<td data-index="' + index + '" '; col.field && (htmlStr += (' data-field="' + col.field + '"')); if (isedit || col.IsEdit == undefined) col.edit && (htmlStr += (' data-edit="' + col.edit + '"')); col.type && (htmlStr += (' data-type="' + col.type + '"')); col.align && (htmlStr += (' align="' + col.align + '"')); // 對齊方式 col.style && (htmlStr += (' style="' + col.style + '"')); // 單元格樣式 col.class && (htmlStr += (' class="' + col.class + '"')); // 單元格樣式 htmlStr += '>'; if (col.singleLine) { htmlStr += ('<div class="ew-tree-table-td-single"><i class="layui-icon layui-icon-close ew-tree-tips-c"></i><div class="ew-tree-tips">' + tdStr + '</div></div>'); } else { htmlStr += tdStr; } htmlStr += '</td>'; return htmlStr; }; /** * 非同步載入渲染 * @param data 父級資料 * @param $tr 父級dom */ TreeTable.prototype.renderBodyAsync = function (d, $tr) { var that = this; var options = this.options; var components = this.getComponents(); var $tbEmpty = components.$tbEmpty; var $tbLoading = components.$tbLoading; // 顯示loading if ($tr) { $tr.addClass('ew-tree-table-loading'); $tr.children('td').find('.ew-tree-pack').children('.ew-tree-table-arrow').addClass('layui-anim layui-anim-rotate layui-anim-loop'); } else { if (options.data && options.data.length > 0) { $tbLoading.addClass('ew-loading-float'); } $tbLoading.show(); $tbEmpty.hide(); } // 請求資料 options.reqData(d, function (res) { if (options.tree.isPidData) { res = treeTb.pidToChildren(res, options.tree.idName, options.tree.pidName, options.tree.childName); } that.renderBodyData(res, d, $tr); // 渲染內容 // 移除loading if ($tr) { $tr.removeClass('ew-tree-table-loading'); $tr.children('td').find('.ew-tree-pack').children('.ew-tree-table-arrow').removeClass('layui-anim layui-anim-rotate layui-anim-loop'); } else { $tbLoading.hide(); $tbLoading.removeClass('ew-loading-float'); // 是否為空 if (!res || res.length == 0) { $tbEmpty.show(); } else { $tbEmpty.hide(); } } }); }; /** * 根據資料渲染body * @param data 資料集合 * @param option 配置項 * @param d 父級資料 * @param $tr 父級dom */ TreeTable.prototype.renderBodyData = function (data, d, $tr) { var that = this; var options = this.options; var components = this.getComponents(); var $view = components.$view; var $table = components.$table; var tbFilter = components.tbFilter; addPidField(data, options.tree, d); // 補充pid欄位 // 更新到資料 if (d == undefined) { options.data = data; } else { d[options.tree.childName] = data; } var indent; if ($tr) { indent = parseInt($tr.data('indent')) + 1; } var htmlStr = this.renderBody(data, indent); if ($tr) { // 移除舊dom $tr.nextAll('tr').each(function () { if (parseInt($(this).data('indent')) <= (indent - 1)) { return false; } $(this).remove(); }); // 渲染新dom $tr.after(htmlStr); $tr.addClass('ew-tree-table-open'); } else { $table.children('tbody').html(htmlStr); } form.render(null, tbFilter); // 渲染表單元素 this.renderNumberCol(); // 渲染序號列 this.checkIndeterminateCB(); // 恢復複選框半選狀態 if ($tr) { // 更新父級複選框狀態 this.checkParentCB($tr); $tr.prevAll('tr').each(function () { var tInd = parseInt($(this).data('indent')); if (tInd < (indent - 1)) { that.checkParentCB($(this)); indent = tInd + 1; } }); } this.checkChooseAllCB(); // 聯動全選框 updateFixedTbHead($view); }; /** * 聯動子級複選框狀態 * @param $tr 當前tr的dom * @param checked */ TreeTable.prototype.checkSubCB = function ($tr, checked) { var that = this; var components = this.getComponents(); var cbFilter = components.checkboxFilter; var indent = -1, $trList; if ($tr.is('tbody')) { $trList = $tr.children('tr'); } else { indent = parseInt($tr.data('indent')); $trList = $tr.nextAll('tr') } $trList.each(function () { if (parseInt($(this).data('indent')) <= indent) { return false; } var $cb = $(this).children('td').find('input[name="' + cbFilter + '"]'); $cb.prop('checked', checked); if (checked) { $cb.data('indeterminate', 'false'); $cb.next('.layui-form-checkbox').addClass('layui-form-checked'); $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate'); } else { $cb.data('indeterminate', 'false'); $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate'); } that.update($(this).data('id'), { LAY_CHECKED: checked }); // 同步更新資料 }); }; /** * 聯動父級複選框狀態 * @param $tr 父級的dom */ TreeTable.prototype.checkParentCB = function ($tr) { var that = this; var components = this.getComponents(); var cbFilter = components.checkboxFilter; var indent = parseInt($tr.data('indent')); var ckNum = 0, unCkNum = 0; $tr.nextAll('tr').each(function () { if (parseInt($(this).data('indent')) <= indent) { return false; } var $cb = $(this).children('td').find('input[name="' + cbFilter + '"]'); if ($cb.prop('checked')) { ckNum++; } else { unCkNum++; } }); var $cb = $tr.children('td').find('input[name="' + cbFilter + '"]'); if (ckNum > 0 && unCkNum == 0) { // 全選 $cb.prop('checked', true); $cb.data('indeterminate', 'false'); $cb.next('.layui-form-checkbox').addClass('layui-form-checked'); $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate'); that.update($tr.data('id'), { LAY_CHECKED: true }); // 同步更新資料 } else if (ckNum == 0 && unCkNum > 0) { // 全不選 $cb.prop('checked', false); $cb.data('indeterminate', 'false'); $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate'); that.update($tr.data('id'), { LAY_CHECKED: false }); // 同步更新資料 } else if (ckNum > 0 && unCkNum > 0) { // 半選 $cb.prop('checked', true); $cb.data('indeterminate', 'true'); $cb.next('.layui-form-checkbox').addClass('layui-form-checked ew-form-indeterminate'); that.update($tr.data('id'), { LAY_CHECKED: true }); // 同步更新資料 } }; /** 聯動全選複選框 */ TreeTable.prototype.checkChooseAllCB = function () { var components = this.getComponents(); var cbAllFilter = components.cbAllFilter; var cbFilter = components.checkboxFilter; var $tbody = components.$table.children('tbody'); var ckNum = 0, unCkNum = 0; $tbody.children('tr').each(function () { var $cb = $(this).children('td').find('input[name="' + cbFilter + '"]'); if ($cb.prop('checked')) { ckNum++; } else { unCkNum++; } }); var $cb = $('input[lay-filter="' + cbAllFilter + '"]'); if (ckNum > 0 && unCkNum == 0) { // 全選 $cb.prop('checked', true); $cb.data('indeterminate', 'false'); $cb.next('.layui-form-checkbox').addClass('layui-form-checked'); $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate'); } else if ((ckNum == 0 && unCkNum > 0) || (ckNum == 0 && unCkNum == 0)) { // 全不選 $cb.prop('checked', false); $cb.data('indeterminate', 'false'); $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate'); } else if (ckNum > 0 && unCkNum > 0) { // 半選 $cb.prop('checked', true); $cb.data('indeterminate', 'true'); $cb.next('.layui-form-checkbox').addClass('layui-form-checked ew-form-indeterminate'); } }; /** 填充序號列 */ TreeTable.prototype.renderNumberCol = function () { var components = this.getComponents(); var $tbody = components.$table.children('tbody'); $tbody.children('tr').each(function (index) { $(this).children('td').find('.ew-tree-table-numbers').text(index + 1); }); }; /* 解決form.render之後半選框被重置的問題 */ TreeTable.prototype.checkIndeterminateCB = function () { var components = this.getComponents(); var cbFilter = components.checkboxFilter; $('input[lay-filter="' + cbFilter + '"]').each(function () { var $cb = $(this); if ($cb.data('indeterminate') == 'true' && $cb.prop('checked')) { $cb.next('.layui-form-checkbox').addClass('ew-form-indeterminate'); } }); }; /** * 搜尋資料 * @param ids 關鍵字或資料id集合 */ TreeTable.prototype.filterData = function (ids) { var components = this.getComponents(); var $trList = components.$table.children('tbody').children('tr'); if (typeof ids == 'string') { // 關鍵字 var keyword = ids; ids = []; $trList.each(function () { var id = $(this).data('id'); $(this).children('td').each(function () { if ($(this).text().indexOf(keyword) != -1) { ids.push(id); return false; } }); }); } $trList.addClass('ew-tree-table-filter-hide'); for (var i = 0; i < ids.length; i++) { var $tr = $trList.filter('[data-id="' + ids[i] + '"]'); $tr.removeClass('ew-tree-table-filter-hide'); // 聯動父級 var indent = parseInt($tr.data('indent')); $tr.prevAll('tr').each(function () { var tInd = parseInt($(this).data('indent')); if (tInd < indent) { $(this).removeClass('ew-tree-table-filter-hide'); // 聯動父級 if (!$(this).hasClass('ew-tree-table-open')) { toggleRow($(this)); } indent = tInd; } }); } }; /** 重置搜尋 */ TreeTable.prototype.clearFilter = function () { var components = this.getComponents(); var $trList = components.$table.children('tbody').children('tr'); $trList.removeClass('ew-tree-table-filter-hide'); }; /** 展開指定行 */ TreeTable.prototype.expand = function (id, cascade) { var components = this.getComponents(); var $tr = components.$table.children('tbody').children('tr[data-id="' + id + '"]'); if (!$tr.hasClass('ew-tree-table-open')) { $tr.children('td').find('.ew-tree-pack').trigger('click'); } if (cascade == false) { return; } // 聯動父級 var indent = parseInt($tr.data('indent')); $tr.prevAll('tr').each(function () { var tInd = parseInt($(this).data('indent')); if (tInd < indent) { if (!$(this).hasClass('ew-tree-table-open')) { $(this).children('td').find('.ew-tree-pack').trigger('click'); } indent = tInd; } }); }; /** 摺疊指定行 */ TreeTable.prototype.fold = function (id, cascade) { var components = this.getComponents(); var $tr = components.$table.children('tbody').children('tr[data-id="' + id + '"]'); if ($tr.hasClass('ew-tree-table-open')) { $tr.children('td').find('.ew-tree-pack').trigger('click'); } if (cascade == false) { return; } // 聯動父級 var indent = parseInt($tr.data('indent')); $tr.prevAll('tr').each(function () { var tInd = parseInt($(this).data('indent')); if (tInd < indent) { if ($(this).hasClass('ew-tree-table-open')) { $(this).children('td').find('.ew-tree-pack').trigger('click'); } indent = tInd; } }); }; /** 全部展開 */ TreeTable.prototype.expandAll = function () { var that = this; var components = this.getComponents(); var $trList = components.$table.children('tbody').children('tr'); $trList.each(function () { that.expand($(this).data('id'), false); }); }; /** 全部摺疊 */ TreeTable.prototype.foldAll = function () { var that = this; var components = this.getComponents(); var $trList = components.$table.children('tbody').children('tr'); $trList.each(function () { that.fold($(this).data('id'), false); }); }; /** 獲取當前資料 */ TreeTable.prototype.getData = function () { return this.options.data; }; /** 過載表格 */ TreeTable.prototype.reload = function (opt) { treeTb.render($.extend(this.options, opt)); }; /** 根據id更新資料 */ TreeTable.prototype.update = function (id, fields) { var data = getDataById(this.getData(), id, this.options.tree); $.extend(data, fields); }; /** 根據id刪除資料 */ TreeTable.prototype.del = function (id) { delDataById(this.getData(), id, this.options.tree); }; /** 獲取當前選中行 */ TreeTable.prototype.checkStatus = function (needIndeterminate) { (needIndeterminate == undefined) && (needIndeterminate = true); var that = this; var components = this.getComponents(); var $table = components.$table; var checkboxFilter = components.checkboxFilter; var radioFilter = components.radioFilter; var list = []; // 獲取單選框選中資料 var $radio = $table.find('input[name="' + radioFilter + '"]'); if ($radio.length > 0) { var id = $radio.filter(':checked').val(); var d = getDataById(this.getData(), id, this.options.tree); if (d) { list.push(d); } } else { // 獲取複選框資料 $table.find('input[name="' + checkboxFilter + '"]:checked').each(function () { var id = $(this).val(); var isIndeterminate = $(this).next('.layui-form-checkbox').hasClass('ew-form-indeterminate'); if (needIndeterminate || !isIndeterminate) { var d = getDataById(that.getData(), id, that.options.tree); if (d) { d.isIndeterminate = isIndeterminate; list.push(d); } } }); } return list; }; /** 設定復/單選框選中 */ TreeTable.prototype.setChecked = function (ids) { var components = this.getComponents(); var $table = components.$table; var checkboxFilter = components.checkboxFilter; var radioFilter = components.radioFilter; var $radio = $table.find('input[name="' + radioFilter + '"]'); if ($radio.length > 0) { // 開啟了單選框 $radio.each(function () { if (ids[ids.length - 1] == $(this).val()) { $(this).next('.layui-form-radio').trigger('click'); return false; } }); } else { // 開啟了複選框 $table.find('input[name="' + checkboxFilter + '"]').each(function () { var $cb = $(this); var value = $cb.val(); var $layCb = $cb.next('.layui-form-checkbox'); for (var i = 0; i < ids.length; i++) { if (value == ids[i]) { var checked = $cb.prop('checked'); var indeterminate = $layCb.hasClass('ew-form-indeterminate'); if (!checked || indeterminate) { $layCb.trigger('click'); } } } }); } }; /** 移除全部選中 */ TreeTable.prototype.removeAllChecked = function () { var components = this.getComponents(); var $table = components.$table; var checkboxFilter = components.checkboxFilter; this.checkSubCB($table.children('tbody'), false); }; /** * 重新整理指定父級下的節點 * @param id 父級id,空則全部重新整理 * @param data 非非同步模式替換的資料 */ TreeTable.prototype.refresh = function (id, data) { if (isClass(id) == 'Array') { data = id; id = undefined; } var components = this.getComponents(); var $table = components.$table; var d, $tr; if (id != undefined) { d = getDataById(this.getData(), id, this.options.tree); $tr = $table.children('tbody').children('tr[data-id="' + id + '"]'); } if (data) { // 資料模式 components.$tbLoading.addClass('ew-loading-float'); components.$tbLoading.show(); this.renderBodyData(data, d, $tr); components.$tbLoading.hide(); components.$tbLoading.removeClass('ew-loading-float'); if (data && data.length > 0) { components.$tbEmpty.hide(); } else { components.$tbEmpty.show(); } } else { // 非同步模式 this.renderBodyAsync(d, $tr); } }; /** 生成表頭 */ function getThead(options) { var htmlStr = '<tr>'; for (var i = 0; i < options.cols.length; i++) { var col = options.cols[i]; htmlStr += '<td data-index="' + i + '" '; col.align && (htmlStr += ' align="' + col.align + '"'); // 對齊方式 htmlStr += ' >'; if (col.singleLine && col.type != 'checkbox') { // 單行顯示 htmlStr += '<div class="ew-tree-table-td-single"><i class="layui-icon layui-icon-close ew-tree-tips-c"></i><div class="ew-tree-tips">'; } // 標題 if (col.type == 'checkbox') { htmlStr += options.getAllChooseBox(); } else { htmlStr += (col.title || ''); } // 列寬拖拽 if (!col.unresize && 'checkbox' != col.type && 'radio' != col.type && 'numbers' != col.type && 'space' != col.type) { htmlStr += '<span class="ew-tb-resize"></span>'; } if (col.singleLine) { // 單行顯示 htmlStr += '</div></div>'; } htmlStr += '</td>'; } htmlStr += '</tr>'; return htmlStr; } /** 生成colgroup */ function getColgroup(options) { var htmlStr = '<colgroup>'; for (var i = 0; i < options.cols.length; i++) { var col = options.cols[i]; htmlStr += '<col '; // 設定寬度 if (col.width) { htmlStr += 'width="' + col.width + '"' } else if (col.type == 'space') { // 空列 htmlStr += 'width="15"' } else if (col.type == 'numbers') { // 序號列 htmlStr += 'width="40"' } else if (col.type == 'checkbox' || col.type == 'radio') { // 復/單選框列 htmlStr += 'width="48"' } htmlStr += ' />'; } htmlStr += '</colgroup>'; return htmlStr; } /** 計算table寬度 */ function getTbWidth(options) { var minWidth = 0, setWidth = true; for (var i = 0; i < options.cols.length; i++) { var col = options.cols[i]; if (col.type == 'space') { // 空列 minWidth += 15; } else if (col.type == 'numbers') { // 序號列 minWidth += 40; } else if (col.type == 'checkbox' || col.type == 'radio') { // 復/單選框列 minWidth += 48; } else if (!col.width || /\d+%$/.test(col.width)) { // 列未固定寬度 setWidth = false; if (col.minWidth) { minWidth += col.minWidth; } else if (options.cellMinWidth) { minWidth += options.cellMinWidth; } } else { // 列固定寬度 minWidth += col.width; } } return { minWidth: minWidth, setWidth: setWidth }; } /** 生成全選按鈕 */ function getAllChooseBox(options) { var tbFilter = $(options.elem).next().attr('lay-filter'); var cbAllFilter = 'ew_tb_choose_all_' + tbFilter; return '<input type="checkbox" lay-filter="' + cbAllFilter + '" lay-skin="primary" class="ew-tree-table-checkbox"/>'; } /** 獲取列圖示 */ function getIcon(d, treeOption) { if (getHaveChild(d, treeOption)) { return '<i class="ew-tree-icon layui-icon layui-icon-layer"></i>'; } else { return '<i class="ew-tree-icon layui-icon layui-icon-file"></i>'; } } /** 摺疊/展開行 */ function toggleRow($tr) { var indent = parseInt($tr.data('indent')); var isOpen = $tr.hasClass('ew-tree-table-open'); if (isOpen) { // 摺疊 $tr.removeClass('ew-tree-table-open'); $tr.nextAll('tr').each(function () { if (parseInt($(this).data('indent')) <= indent) { return false; } $(this).addClass('ew-tree-tb-hide'); }); } else { // 展開 $tr.addClass('ew-tree-table-open'); var hideInd; $tr.nextAll('tr').each(function () { var ind = parseInt($(this).data('indent')); if (ind <= indent) { return false; } if (hideInd != undefined && ind > hideInd) { return true; } $(this).removeClass('ew-tree-tb-hide'); if (!$(this).hasClass('ew-tree-table-open')) { hideInd = parseInt($(this).data('indent')); } else { hideInd = undefined; } }); } updateFixedTbHead($tr.parent().parent().parent().parent().parent()); } /** 固定表頭滾動條補丁 */ function updateFixedTbHead($view) { var $group = $view.children('.ew-tree-table-group'); var $headBox = $group.children('.ew-tree-table-head'); var $tbBox = $group.children('.ew-tree-table-box'); var sWidth = $tbBox.width() - $tbBox.prop('clientWidth'); if (sWidth > 0) { $headBox.css('border-right', sWidth + 'px solid #f2f2f2'); } else { $headBox.css('border-right', 'none'); } } // 監聽視窗大小改變 $(window).resize(function () { $('.ew-tree-table').each(function () { updateFixedTbHead($(this)); var $tbBox = $(this).children('.ew-tree-table-group').children('.ew-tree-table-box'); var full = $tbBox.attr('ew-tree-full'); if (full && device.ie && device.ie < 10) { $tbBox.css('height', getPageHeight() - full); } }); }); // 表格溢位點選展開功能 $(document).on('mouseenter', '.ew-tree-table td', function () { var $tdSingle = $(this).children('.ew-tree-table-td-single'); var $content = $tdSingle.children('.ew-tree-tips'); if ($tdSingle.length > 0 && $content.prop('scrollWidth') > $content.outerWidth()) { $(this).append('<div class="layui-table-grid-down"><i class="layui-icon layui-icon-down"></i></div>'); } }).on('mouseleave', '.ew-tree-table td', function () { $(this).children('.layui-table-grid-down').remove(); }); // 點選箭頭展開 $(document).on('click', '.ew-tree-table td>.layui-table-grid-down', function (e) { hideAllTdTips(); var $tdSingle = $(this).parent().children('.ew-tree-table-td-single'); $tdSingle.addClass('ew-tree-tips-open'); var $box = $tdSingle.parents().filter('.ew-tree-table-box'); if ($box.length <= 0) { $box = $tdSingle.parents().filter('.ew-tree-table-head'); } if (($tdSingle.outerWidth() + $tdSingle.parent().offset().left) > $box.offset().left + $box.outerWidth()) { $tdSingle.addClass('ew-show-left'); } if (($tdSingle.outerHeight() + $tdSingle.parent().offset().top) > $box.offset().top + $box.outerHeight()) { $tdSingle.addClass('ew-show-bottom'); } e.stopPropagation(); }); // 點選關閉按鈕關閉 $(document).on('click', '.ew-tree-table .ew-tree-tips-c', function (e) { hideAllTdTips(); }); // 點選空白部分關閉 $(document).on('click', function () { hideAllTdTips(); }); $(document).on('click', '.ew-tree-table-td-single.ew-tree-tips-open', function (e) { e.stopPropagation(); }); /* 關閉所有單元格溢位提示框 */ function hideAllTdTips() { var $single = $('.ew-tree-table-td-single'); $single.removeClass('ew-tree-tips-open'); $single.removeClass('ew-show-left'); } /** 判斷是否還有子節點 */ function getHaveChild(d, treeOption) { var haveChild = false; if (d[treeOption.haveChildName] != undefined) { haveChild = d[treeOption.haveChildName]; haveChild = haveChild == true || haveChild == 'true'; } else if (d[treeOption.childName]) { haveChild = d[treeOption.childName].length > 0; } return haveChild; } /** 補充pid欄位 */ function addPidField(data, treeOption, parent) { for (var i = 0; i < data.length; i++) { if (parent) { data[i][treeOption.pidName] = parent[treeOption.idName]; } if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) { addPidField(data[i][treeOption.childName], treeOption, data[i]); } } } /** 根據id獲取資料 */ function getDataById(data, id, treeOption) { for (var i = 0; i < data.length; i++) { if (data[i][treeOption.idName] == id) { return data[i]; } if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) { var d = getDataById(data[i][treeOption.childName], id, treeOption); if (d != undefined) { return d; } } } } /** 根據id刪除資料 */ function delDataById(data, id, treeOption) { for (var i = 0; i < data.length; i++) { if (data[i][treeOption.idName] == id) { data.splice(i, 1); return true; } if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) { var rs = delDataById(data[i][treeOption.childName], id, treeOption); if (rs) { return true; } } } } /** 獲取頂級的pId */ function getPids(list, idName, pidName) { var pids = []; for (var i = 0; i < list.length; i++) { var hasPid = false; for (var j = 0; j < list.length; j++) { if (i != j && list[j][idName] == list[i][pidName]) { hasPid = true; } } if (!hasPid) { pids.push(list[i][pidName]); } } return pids; } /** 判斷pId是否相等 */ function pidEquals(pId, pIds) { if (isClass(pIds) == 'Array') { for (var i = 0; i < pIds.length; i++) { if (pId == pIds[i]) { return true; } } } else { return pId == pIds; } return false; } /** 獲取變數型別 */ function isClass(o) { if (o === null) return 'Null'; if (o === undefined) return 'Undefined'; return Object.prototype.toString.call(o).slice(8, -1); } /* 獲取瀏覽器高度 */ function getPageHeight() { return document.documentElement.clientHeight || document.body.clientHeight; } /* 獲取瀏覽器寬度 */ function getPageWidth() { return document.documentElement.clientWidth || document.body.clientWidth; } /** 對外提供的方法 */ var treeTb = { /* 渲染 */ render: function (options) { return new TreeTable(options); }, /* 事件監聽 */ on: function (events, callback) { return layui.onevent.call(this, MOD_NAME, events, callback); }, /* pid轉children形式 */ pidToChildren: function (data, idName, pidName, childName, pId) { childName || (childName = 'children'); var newList = []; for (var i = 0; i < data.length; i++) { (pId == undefined) && (pId = getPids(data, idName, pidName)); if (pidEquals(data[i][pidName], pId)) { var children = this.pidToChildren(data, idName, pidName, childName, data[i][idName]); (children.length > 0) && (data[i][childName] = children); newList.push(data[i]); } } return newList; } }; exports('treeTable', treeTb); });treeTable.js
<script src="jquery-1.8.3.min.js" type="text/javascript"></script>
<link href="layui/css/layui.css" rel="stylesheet" type="text/css" />
<script src="layui/layui.js" type="text/javascript"></script>
<link href="layui/treeTable/treeTable.css" rel="stylesheet" />
注意:toolbarDel:"#tbBarDel", toolbar: '#tbBar'在操作列時需要些自己寫的jsbug
<script>
layui.extend({
treeTable: 'layui/treeTable/treeTable' //treeTable存放路徑
}).use(['treeTable'], function () {
var iseditd = $("#hidControlSave").val();//是否可儲存,執行修改刪除操作 值為1和0 1為不可刪除修改,0可以進行刪除修改EdidLEVEL時不可修改
var treeTable = layui.treeTable;
// 渲染表格
//IsEdit: 'IsEdit', LEVEL: 'LEVEL' 設定是否可編輯,和當前欄目所在層級 IsEdit:如果有值的話則不可編輯,沒有值則可以修改
//toolbar: '#tbBar', toolbarDel: '#tbBarDel', toolbar正常需要展示的操作按鈕,否則顯示toolbarDel的操作按鈕
var col = [
{ type: 'numbers' },
{ field: 'name', templet: '<p>{{d.name}}</p>', title: '投標檔案目錄', width: 360 },
{ field: 'name', IsEdit: 'IsEdit', LEVEL: 'LEVEL', title: '目錄名稱<i class=\"layui-icon\"></i>', edit: 'text' }
,{ align: 'center', IsEdit: 'IsEdit', LEVEL: 'LEVEL', toolbar: '#tbBar', toolbarDel: '#tbBarDel', title: '操作', width: 220 }
];
if (iseditd == 1) {
col = [
{ type: 'numbers' },
{ field: 'name', templet: '<p>{{d.name}}</p>', title: '投標檔案目錄', width: 360 },
{ field: 'name', title: '目錄名稱<i class=\"layui-icon\"></i>' }
];
}
var insTb = treeTable.render({
elem: '#demoTb1',
toolbar: 'default',
showtooobar: true,
EdidLEVEL: 2,//只有1-2級才能有新增按鈕
tree: {
openName: 'name',//設定要開啟的列,列名稱,預設展開資料 如果沒有這個屬性將摺疊,不展開,懶載入不需要設定
iconIndex: 1,
arrowType: 'arrow2',
idName: 'id',//id
isPidData: true,//是否啟用上下級關係,懶載入不需要設定
pidName: 'pid'//父級id
},
text: {},
cols: col,
reqData: function (data, callback) {
var url = '/Budget/Handler/PlanHandler.ashx?Method=GetDocumentTree&djid=<%=Request["djid"]%>&fbid=<%=FBID%>';
url += ((data ? ("&fid=" + data.id) + "" : '')); //條件搜尋
var keywords = $('#edtSearch').val();//條件搜尋
url += ((keywords ? ("&keywords=" + keywords) + "" : ''));//條件搜尋
$.get(url, function (res) {
//res資料格式
//{"suress":true,"msg":"資料獲取成功!","data":[{"id":"010204","pxz":"60 ","LEVEL":1,"pid":"0102","name":"技術部分","IsEdit":"tbs_js"},{"id":"01020401","pxz":"61","LEVEL":2,"pid":"010204","name":"投標產品的品牌、型號、技術引數","IsEdit":null},{"id":"01020402","pxz":"62 ","LEVEL":2,"pid":"010204","name":"關於招標要求的應答對照表","IsEdit":null},{"id":"01020403","pxz":"63 ","LEVEL":2,"pid":"010204","name":"專案組織實施方案","IsEdit":null},{"id":"01020404","pxz":"64 ","LEVEL":2,"pid":"010204","name":"專案人員配備情況","IsEdit":null},{"id":"01020405","pxz":"65 ","LEVEL":2,"pid":"010204","name":"產品彩頁資料和產品工作環境條件說明","IsEdit":null},{"id":"01020407","pxz":"69 ","LEVEL":2,"pid":"010204","name":"售後服務","IsEdit":null},{"id":"0102040701","pxz":"70 ","LEVEL":3,"pid":"01020407","name":"售後服務方案","IsEdit":null},{"id":"0102040702","pxz":"71 ","LEVEL":3,"pid":"01020407","name":"售後服務人員配備","IsEdit":null},{"id":"0102040703","pxz":"72 ","LEVEL":3,"pid":"01020407","name":"售後服務機構設定情況和聯絡電話","IsEdit":null}]}
var res = JSON.parse(res);
callback(res.data);
});
},
style: 'margin-top:0;'
});
// 全部展開
$('#btnExpandAll').click(function () {
insTb.expandAll();
});
// 清除搜尋
$('#btnClearSearch').click(function () {
$('#edtSearch').val("")
insTb.reload();
});
// 工具列點選事件
treeTable.on('tool(demoTb1)', function (obj) {
var event = obj.event;
if (event === 'del') {
layer.msg('刪除成功');
del(obj.data);
obj.del();
} else if (event === 'edit') {
} else if (event === 'add') {
var pid = obj.data.id;
var len = 1;
if (obj.data.children != null && obj.data.children.length > 0 && obj.data.children != undefined)
len = obj.data.children.length + 1;
var name = prompt("請輸入目錄名稱", "")
if (name != null && name != "") {
additem.push({ id: pid + "0" + len, pid: pid, win_name: 'w_tb_import_jsfa1', win_parm: '', name: name, pxz: len });
}
console.log(additem);
$("#btnSavaPageInfo").click();
}
});
// 全部摺疊
$('#btnFoldAll').click(function () {
insTb.foldAll();
});
// 搜尋
$('#btnSearch').click(function () {
var keywords = $('#edtSearch').val();
if (keywords) {
insTb.refresh();
} else {
insTb.clearFilter();
}
});
});
</script>
<%--全部展開摺疊Start--%>
<button id="btnExpandAll" class="layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon"></i>展開全部</button>
<button id="btnFoldAll" class="layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon"></i>摺疊全部</button>
<%--全部展開摺疊End--%>
<%--搜尋Start--%>
<input class="layui-input" id="edtSearch" value="" placeholder="輸入關鍵字" style="display: inline-block; width: 140px; height: 30px; line-height: 30px; padding: 0 5px; margin-right: 5px;" />
<div class="layui-btn-container" style="display: inline-block;">
<button id="btnSearch" class="layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon"></i>搜尋</button>
<button id="btnClearSearch" class="layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon">ဆ</i>清除搜尋</button>
</div>
<%--搜尋End--%>
<div class="tabletree" style="width: 100%;"><%--樹形容器--%>
<table id="demoTb1"></table>
</div>
<script type="text/html" id="tbBar"> <%--某種條件有刪除和新增,對應某一級後不能再往下新增--%>
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="del">刪除</a>
<a class="layui-btn layui-btn-primary layui-btn-xs add" lay-event="add">新增</a>
</script>
<script type="text/html" id="tbBarDel"> <%--某種條件只有刪除--%>
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="del">刪除</a>
</script>
4.省市區聯動控制元件使用
引入
<!--引入js檔案-->
<script src="jquery-1.8.3.min.js"></script>
<!--省市區聯動,以下三個都要引用Start-->
<script src="distpicker/distpicker.data.js"></script>
<script src="distpicker/data.js"></script>
<script src="distpicker/distpicker.js"></script>
<!--省市區聯動,以下三個都要引用End-->
A.div 新增data-toggle="distpicker"
B.select新增屬性
data-province="---- 選擇省 ----"
data-city="---- 選擇市 ----"
data-district="---- 選擇區 ----"
例如:
<div data-toggle="distpicker">
<label for="userID" class="control-label">所在省</label>
<select name="sheng" class="form-control " data-province="---- 選擇省 ----" id="sheng" nullable="false" alt="請選擇供應商性質"></select>
<select name="shi" class="form-control " data-city="---- 選擇市 ----" id="shi" nullable="false" alt="請選擇供應商性質"></select>
<select name="qu" class="form-control " data-district="---- 選擇區 ----" id="qu" nullable="false" alt="請選擇供應商性質">
</select>
</div>