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',
}).then(function (res) {
var res = res.data.ds;
}).catch(function (error) {
console.log(error);
alert(false);
});
2.表单验证Verify.js使用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/*! * 主 题:《表单录入验证》 * 说 明:通过控件属性实现验证,包括生成星号标注、非法提示等; * 功能描述: * 1、当录入框必填时,在控件后生成红色星号(设置star=false时不显示星号); * 2、根据控件属性判断需要录入的数据格式,如果非法则阻止提交并弹出提示 * 3、支持分组验证 * 4、可脱离微厦在线学习系统独立使用(需要JQuery库支持) * * 作 者:微厦科技_宋雷鸣_10522779@qq.com * 开发时间: 2013年8月5日 * 最后修订:2018年2月4日 */ (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文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 最外层容器 */ .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; }*/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * 树形表格 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); });
<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>
![](https://www.cnblogs.com/images/cnblogs_com/-hao/1352120/o_zfbAndWx.jpg)
您的资助是我最大的动力!
金额随意,欢迎来赏!