layui.define(["laydate","laytpl","table","layer","tableEdit"],function(exports) { "use strict"; var moduleName = 'tableTree' ,_layui = layui ,laytpl = _layui.laytpl ,$ = _layui.$ ,table = _layui.table ,layer = _layui.layer ,tableEdit = _layui.tableEdit ,editEntity = tableEdit.callbackFn('tableEdit(getEntity)'); //组件用到的css样式 var thisCss = []; thisCss.push('.layui-tableEdit-checked i{background-color:#60b979!important;}'); thisCss.push('.layui-tableEdit-edit{position:absolute;right:2px;font-size:20px;bottom:8px;z-index:199109084;}'); thisCss.push('.layui-tableEdit-edge{position:absolute;left:8px;bottom:0;font-size:20px;z-index:19910908445;}'); thisCss.push('.layui-tableEdit-span {position:absolute;left:35px;bottom:0;}'); var thisStyle = document.createElement('style'); thisStyle.innerHTML = thisCss.join('\n'),document.getElementsByTagName('head')[0].appendChild(thisStyle); var configs = { callbacks:{} ,tableTreeCache:{} ,isEmpty:function(data){ return typeof data === 'undefined' || data === null || data.length <= 0; } ,parseConfig:function (cols,field) { var type,data,enabled,dateType,csField; cols.forEach(function (ite) { ite.forEach(function (item) { if(field !== item.field || !item.config)return; var config = item.config; type = config.type; data = config.data; enabled = config.enabled; dateType = config.dateType; csField = config.cascadeSelectField; }); }); return {type:type,data:data,enabled:enabled,dateType:dateType,cascadeSelectField:csField}; } }; var TableTree = function () {this.config = {},this.aopObj = {}}; TableTree.prototype = { render:function (options) { var that = this;$.extend(that.config,options); var treeConfig = that.config['treeConfig']; if(!that.initDoneStat){ var _done = that.config.done; var done = function(result){ if(!result.data) result.data = table.cache[that.config.id] = []; configs.tableTreeCache[$(this.elem).attr('id')] = result.data; var params = {field:treeConfig.showField,element:this.elem}; that.initTree(params); if(_done){ _done.call(this,result); } }; that.config.done = done; that.initDoneStat = true; that.url = that.config.url; } that.tableEntity = table.render(that.config); return that.tableEntity.config.cols; } ,initTree:function (options) { var data = configs.tableTreeCache[$(options.element).attr('id')]; this.createChildren(data,options.field,null,0); this.closeAllRows(); this.events(); } ,createChildren:function(arr,field,tr,lvl){ var that = this; var tableBody = $(that.config.elem).next().find('div.layui-table-body'); _layui.each(arr,function (key,item) { if(lvl === 0){ tr = tableBody.find('tr[data-index="'+key+'"]'); $(tr).attr('tree-id',item[that.config.treeConfig.treeid]); var td = $(tr).find('td[data-field="'+field+'"]'); var _div = td.find('div.layui-table-cell'); var span = _div.find('span'); if(!span[0]){ var text = _div.text();_div.text(''); _div.prepend(''+text+''); }else { !span.hasClass('layui-tableEdit-span') && span.addClass('layui-tableEdit-span'); } if(!td.find('i.layui-tableEdit-edge')[0]){ that.addIcon(tr,td,lvl); } var checkboxTd = tr.find('td.layui-table-col-special'); checkboxTd.html(''); var newCheckbox = '
'; checkboxTd.append(newCheckbox); }else { that.addTreeRow(tr,item); } if(item.treeList){ var nextTr = lvl === 0 ? tr : $(tr).next(); that.createChildren(item.treeList,field,nextTr,lvl+1) } }); } ,addTreeRow:function (tr,data) { var that = this,lvl = tr.data('lvl'); lvl = configs.isEmpty(lvl) ? 0 : parseInt(lvl); var treeid = that.config.treeConfig.treeid; if(configs.isEmpty(data[treeid])){ data[treeid] = Number(Math.random().toString().substr(3, 3) + Date.now()).toString(36); } var newTr = $(''); tr.after(newTr); that.addElementToTr(data,tr,newTr,lvl+1); } ,findChildren:function (arr,uniqueTreeid) { var treeid = this.config.treeConfig.treeid; for(var i=0;i0) { var data = this.findChildren(item.treeList, uniqueTreeid); if(data) return data; } } } } ,addIcon:function(tr,td,lvl) { var iconClass = this.config.treeConfig.iconClass; iconClass = configs.isEmpty(iconClass) ? 'layui-icon-triangle-r' : iconClass; var that = this ,icon = $('') ,div = $('
') ,_div = $('
') ,cell = td.find('div.layui-table-cell') ,span = cell.children('span'); if(lvl>0){ var spanLeft = lvl*24 + 35,iconLeft = lvl*24+8; span.css('left',spanLeft+'px'); icon.css('left',iconLeft+'px'); } div.append(icon),cell.append(div),$(td).append(_div); var add = $('');_div.append(add); var update = $('');_div.append(update) var remove = $('');_div.append(remove); _div.hide(); var heightStyle = that.config.size; heightStyle = heightStyle ? heightStyle : ''; if(heightStyle === 'sm'){ //兼容table的size类型 span.css('bottom','0px'); icon.css('bottom','0px'); update.css('bottom','4px'); add.css('bottom','4px'); remove.css('bottom','4px'); } if(heightStyle === 'lg'){ span.css('bottom','-1px'); icon.css('bottom','-1px'); update.css('bottom','15px'); add.css('bottom','15px'); remove.css('bottom','15px'); } add.css('right','1px'),update.css('right','24px'),add.css('right','47px'); } ,events:function () { var that = this; var tableBody = $(this.config.elem).next().find('div.layui-table-body'); var tableTreeid = $(that.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; //编辑图标事件注册 tableBody.on('click','i.layui-tableEdit-edit',function (e) { _layui.stope(e); var isAdd = $(this).hasClass('layui-icon-add-1') ,isUpdate = $(this).hasClass('layui-icon-edit') ,isDelete = $(this).hasClass('layui-icon-delete'); var tr = $(this).parents('tr'); var td = $(this).parents('td'),field = td.data('field'); var treeid = tr.attr('tree-id'); var data = that.findChildren(treeData,treeid); var lvl = tr.data('lvl'); lvl = lvl ? lvl : 0; if(isAdd){//新增 //回调tool(lay-filter)对应的方法 异步/同步获取数据后回调add方法进行新增行 var thisObj = {value:null,data:data,field:field,add:function (newTree) { var _treeid_ = that.config.treeConfig.treeid; var treeList = data.treeList; if(!treeList) treeList = data.treeList = []; if(configs.isEmpty(newTree)) return; var count= 0,num = 0,len = newTree.length; while (count确定删除吗?', function(index){ var thisObj = {value:null,data:data,field:field,event:'del',del:function () { var lvl = tr.data('lvl');lvl = lvl ? lvl : 0; //删除页面隐藏的树 that.removeChildren(tr,lvl); //清楚缓存中的数据 that.clearCacheData(data); tr.remove(); }}; that.aopObj.callback.call(td[0],thisObj); layer.close(index); }); } }); //注册点击事件。 tableBody.on("click",'td.layui-table-col-special',function (e) { _layui.stope(e) var div = $(this).children('div.layui-unselect'); div.hasClass('layui-tableEdit-checked') ? div.removeClass('layui-tableEdit-checked') : div.addClass('layui-tableEdit-checked'); }); //全选复选框事件 var tableHead = tableBody.prev() ,allElem = tableHead.find('th.layui-table-col-special'); allElem[0].innerHTML = ''; var newCheckbox = '
'; allElem.append(newCheckbox); tableHead.on('click','th.layui-table-col-special',function (e) { _layui.stope(e) var div = $(this).children('div.layui-unselect'); if(div.hasClass('layui-tableEdit-checked')){ div.removeClass('layui-tableEdit-checked'); tableBody.find('td.layui-table-col-special div.layui-unselect').removeClass('layui-tableEdit-checked'); }else { div.addClass('layui-tableEdit-checked'); tableBody.find('td.layui-table-col-special div.layui-unselect').addClass('layui-tableEdit-checked'); } }); //showField字段单元格点击事件,展开子叶节点 tableBody.on('click','td[data-field="'+that.config.treeConfig.showField+'"]',function (e) { _layui.stope(e); var thisTreeElem = $(this).parent(); var lvl = thisTreeElem.data('lvl');lvl = lvl ? lvl : 0; var icon = $(this).find('i.layui-tableEdit-edge'); var isShow = icon.hasClass('layui-tableEdit-clicked'); //关闭或者展开子元素 that.showOrHideChildren(thisTreeElem,lvl,!isShow); //选择三角图标 that.rotateFunc(icon); }); //操作栏鼠标经过事件 tableBody.on("mouseover ",'td[data-field="'+that.config.treeConfig.showField+'"]',function (e) { _layui.stope(e) tableBody.find('div.layui-tableTree-edit').hide(); var thisX = this.getBoundingClientRect().left ,thisY = this.getBoundingClientRect().top ,thisWidth = this.offsetWidth ,thisHeight = this.offsetHeight, thisTreeEdit = $(this).find('div.layui-tableTree-edit'); e = e || window.event; if(e.pageX || e.pageY) { var xy = {x: e.pageX, y: e.pageY}; if(xy.y < (thisY+thisHeight) && xy.y > thisY && xy.x > (thisX+thisWidth/2) && xy.x < (thisX+thisWidth)){ thisTreeEdit.show(); } } }); tableBody.on("mouseout",'td[data-field="'+that.config.treeConfig.showField+'"]',function (e) { _layui.stope(e) tableBody.find('div.layui-tableTree-edit').hide(); }); } ,asyncAddTree:function (obj,data,tr,lvl) { var that = this; var _treeid_ = that.config.treeConfig.treeid; var treepid = that.config.treeConfig.treepid; !obj && (obj = []); obj.forEach(function (e) { that.addTreeRow(tr,e); e[treepid] = data[_treeid_]; if(e.treeList && e.treeList.length>0){ that.asyncAddTree(e.treeList,e,tr.next(),lvl+1); } }); that.showOrHideChildren(tr,lvl,true); var nextIcon = tr.find('td[data-field="'+that.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); that.rotateFunc(nextIcon,true); } ,parseTempletData:function (d,field) { var rs = null; this.config.cols.forEach(function (item1) { item1.forEach(function (item2) { if(item2.field === field){ var templet = item2.templet; if(templet){ if(typeof templet === 'string'){ rs = laytpl($(templet).html()).render(d); }else { rs = templet(d,field); } }else { rs = d[field]; } } }); }); return rs; } ,clearCacheData:function (data) { var treeid = this.config.treeConfig.treeid; var tableTreeid = $(this.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; this.clearChildCacheData(treeData,data[treeid]); } ,clearChildCacheData:function (list,uniqueTreeid) { var treeid = this.config.treeConfig.treeid; for(var i=0;i 0){ this.clearChildCacheData(item.treeList,uniqueTreeid) } } } } ,rotateFunc:function (icon,isOpen,isClose) { if(icon.hasClass('layui-tableEdit-clicked')){ if(!isOpen){ icon.css('transform',''); icon.removeClass('layui-tableEdit-clicked'); } }else { icon.css('transform','rotate(90deg)'); icon.addClass('layui-tableEdit-clicked'); } if(isClose){ icon.css('transform',''); icon.removeClass('layui-tableEdit-clicked'); } } ,showOrHideChildren:function (elemTree,lvl,isShow) { var nextTreeElem = elemTree.next(),nextlvl = nextTreeElem.data('lvl'); nextlvl = nextlvl ? nextlvl : 0; if(nextTreeElem[0] && nextlvl > lvl){ if((nextlvl-lvl) <= 1 && isShow){ nextTreeElem.show(); }else { nextTreeElem.hide() } var nextIcon = nextTreeElem.find('td[data-field="'+this.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); //叶子节点不用打开小图标 this.rotateFunc(nextIcon,null,true); this.showOrHideChildren(nextTreeElem,lvl,isShow); } } ,removeChildren:function (elemTree,lvl) { var nextTreeElem = elemTree.next(),nextlvl = nextTreeElem.data('lvl'); nextlvl = nextlvl ? nextlvl : 0; if(nextTreeElem[0] && nextlvl > lvl){ nextTreeElem.remove(); this.removeChildren(elemTree,lvl); } } ,checkedRepeatData:function (data) { var treeid = this.config.treeConfig.treeid; var tableTreeid = $(this.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; var ckeckData = this.findChildren(treeData,data[treeid]); return ckeckData ? true : false; } ,getCheckedData:function () { var that = this; var tableBody = $(this.config.elem).next().find('div.layui-table-body'); var isAll = tableBody.prev().find('th.layui-table-col-special div.layui-unselect').hasClass('layui-tableEdit-checked'); var tableTreeid = $(that.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; var checkedElem = tableBody.find('td.layui-table-col-special div.layui-tableEdit-checked'); if(isAll) return treeData; var dataArr = []; checkedElem.each(function () { var tr = $(this).parents('tr').eq(0); var treeid = tr.attr('tree-id'); var data = that.findChildren(treeData,treeid); dataArr.push(data); }); return dataArr; } ,reload:function (options) { this.config.url = this.url; delete this.config.data; this.render(options); } ,openCheckedRows:function () { var that = this; var treepid =this.config.treeConfig.treepid; var tableTreeid = $(that.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; var tableBody = $(this.config.elem).next().find('div.layui-table-body'); var isAll = tableBody.prev().find('th.layui-table-col-special div.layui-unselect').hasClass('layui-tableEdit-checked'); if(isAll){ that.openAllRows(); }else { tableBody.find('td.layui-table-col-special div.layui-tableEdit-checked').each(function (e) { var tr = $(this).parents('tr'); var icon = tr.find('td[data-field="'+that.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); var lvl = tr.data('lvl'); lvl = lvl ? lvl : 0; if(lvl > 0){ var thisTreeid = tr.attr('tree-id'); var data = that.findChildren(treeData,thisTreeid); var superElem = $("tr[tree-id='"+data[treepid]+"']"); var superIcon = superElem.find('td[data-field="'+that.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); //如果上级节点时关闭的,那么选中行不会进行展开。 if(superElem && superIcon.hasClass("layui-tableEdit-clicked")){ that.openTreeNode(tr,lvl); that.rotateFunc(icon,true); } }else { that.openTreeNode(tr,lvl); that.rotateFunc(icon,true); } }); } } ,openTreeNode:function (elemTree,lvl) { var nextTreeElem = elemTree.next(),nextlvl = nextTreeElem.data('lvl'); nextlvl = nextlvl ? nextlvl : 0; if(nextTreeElem[0] && nextlvl > lvl){ nextTreeElem.show(); var nextIcon = nextTreeElem.find('td[data-field="'+this.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); //叶子节点不用打开小图标 this.rotateFunc(nextIcon,true); this.openTreeNode(nextTreeElem,lvl); } } ,closeCheckedRows:function () { var that = this; var tableBody = $(this.config.elem).next().find('div.layui-table-body'); var isAll = tableBody.prev().find('th.layui-table-col-special div.layui-unselect').hasClass('layui-tableEdit-checked'); if(isAll){ that.closeAllRows(); }else { tableBody.find('td.layui-table-col-special div.layui-tableEdit-checked').each(function (e) { var tr = $(this).parents('tr'); var icon = tr.find('td[data-field="'+that.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); var lvl = tr.data('lvl'); lvl = lvl ? lvl : 0; that.showOrHideChildren(tr,lvl,false); that.rotateFunc(icon,null,true); }); } } ,openAllRows:function () { var that = this; var tableBody = $(this.config.elem).next().find('div.layui-table-body'); tableBody.find('tr').each(function (e) { var tr = $(this); var icon = tr.find('td[data-field="'+that.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); var lvl = tr.data('lvl'); lvl = lvl ? lvl : 0; that.showOrHideChildren(tr,lvl,true); that.rotateFunc(icon,true); }); } ,closeAllRows:function () { var that = this; var tableBody = $(this.config.elem).next().find('div.layui-table-body'); tableBody.find('tr').each(function (e) { var tr = $(this); var icon = tr.find('td[data-field="'+that.config.treeConfig.showField+'"] i.layui-tableEdit-edge'); var lvl = tr.data('lvl'); lvl = lvl ? lvl : 0; that.showOrHideChildren(tr,lvl,false); that.rotateFunc(icon,null,true); }); } ,sort:function (options,treeData) { //排序,此代码抄袭至layui sort源码中来 var that = this; treeData.sort(function(o1, o2){ var isNum = /^-?\d+$/ ,v1 = o1[options.field] ,v2 = o2[options.field]; if(isNum.test(v1)) v1 = parseFloat(v1); if(isNum.test(v2)) v2 = parseFloat(v2); if(v1 && !v2){ return 1; } else if(!v1 && v2){ return -1; } if(v1 > v2){ return 1; } else if (v1 < v2) { return -1; } else { return 0; } }); if(options.desc){ treeData.reverse(); } treeData.forEach(function (e) { if(e.treeList && e.treeList.length>0){ that.sort(options,e.treeList); } }); that.deleteLayTableIndex(treeData); } ,getTableTreeData:function () { var tableTreeid = $(this.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; return treeData; } , deleteLayTableIndex:function (data) { var that = this; data.forEach(function (e) { delete e['LAY_TABLE_INDEX']; if(e.treeList){ that.deleteLayTableIndex(e.treeList); } }) }, on:function (event,callback) { var othis = this;othis.aopObj.event = event,othis.aopObj.callback = callback; table.on(othis.aopObj.event,function (obj) { var zthis = this,field = $(zthis).data('field'),config = configs.parseConfig(othis.config.cols,field); obj.field = field; var callbackFn = function (res) { obj.value = Array.isArray(res) ? (res.length>0 ? res : [{name:'',value:''}]) : res; othis.aopObj.callback.call(zthis,obj); }; if(Object.keys(obj.data).length <= 0){ var tableTreeid = $(othis.config.elem).attr('id') ,treeData = configs.tableTreeCache[tableTreeid] ,_treeid = $(zthis.parentNode).attr("tree-id"); obj.data = othis.findChildren(treeData,_treeid); obj.update = function (fields) { if(!fields)return; for(var key in fields){ obj.data[key] = fields[key]; var showValue = othis.parseTempletData(obj.data,key); showValue = showValue ? showValue : ''; $(zthis).find('div.layui-table-cell').text(showValue) } }; } config.type === 'select' && editEntity.register({data:config.data,element:zthis,enabled:config.enabled,selectedData:obj.data[field],callback:callbackFn}); config.type === 'date' && editEntity.date({dateType:config.dateType,element:zthis,callback:callbackFn}); config.type === 'input'&& editEntity.input({element:zthis,oldValue:obj.data[field],callback:callbackFn}); !config.type && othis.aopObj.callback.call(zthis,obj); }); } ,addTopRow:function (data) { var that = this; var treeid = that.config.treeConfig.treeid; var treepid = that.config.treeConfig.treepid; var tableTreeid = $(that.config.elem).attr('id') ,treeData = configs.tableTreeCache[tableTreeid]; if(treeData.length<=0){ if(!data){ data = {}; } that.config.cols.forEach(function (item1) { item1.forEach(function (item) { if(item.field){ if(!(item.field in data)){ data[item.field] = null; } } }); }); delete data[treepid]; //最上级行不能有treepid delete that.config.url; if(!data[treeid]){ data[treeid] = Number(Math.random().toString().substr(3, 3) + Date.now()).toString(36) } treeData.push(data); that.config.data = treeData; that.render(that.config); return; } if(!data || (data && typeof data !== 'object')){ data = {}; for(var key in treeData[0]){ data[key] = null; } } delete data[treepid]; //最上级行不能有treepid var tr = $(that.config.elem).next().find('div.layui-table-body tr').eq(0); if(configs.isEmpty(data[treeid]) || that.checkedRepeatData(data)){ data[treeid] = Number(Math.random().toString().substr(3, 3) + Date.now()).toString(36) } var newTr = $(''); tr.before(newTr); data['LAY_TABLE_INDEX'] = treeData.length; treeData.push(data); that.addElementToTr(data,tr,newTr,0); that.rotateFunc( newTr.find('td[data-field="'+that.config.treeConfig.showField+'"] i.layui-tableEdit-edge'),true); } ,addElementToTr:function (data,tr,newTr,lvl) { var that = this; tr.children('td').each(function () { var field = $(this).data('field'),td = null; if(field+"" === '0'){ var div = $('
'); td = $(''); td.append(div); }else { var attrsStr = [] ,_divclass = $(this).children('div.layui-table-cell').attr("class") ,attrs = this.attributes; for(var i=0;i
'+text+'
'); that.addIcon(newTr,td,lvl); }else { newTr.append('
'+text+'
'); } } newTr.append(td); }); } ,delCheckedRows:function () { var that = this; var tableTreeid = $(that.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; var tableBody = $(this.config.elem).next().find('div.layui-table-body'); var isAll = tableBody.prev().find('th.layui-table-col-special div.layui-unselect').hasClass('layui-tableEdit-checked'); var checkedElem = tableBody.find('td.layui-table-col-special div.layui-tableEdit-checked'); if(isAll){ treeData.splice(0,treeData.length); tableBody.find('tbody').html(''); return; } checkedElem.each(function () { var tr = $(this).parents('tr').eq(0); var treeid = tr.attr('tree-id'); var data = that.findChildren(treeData,treeid); var lvl = tr.data('lvl');lvl = lvl ? lvl : 0; //删除页面隐藏的树 that.removeChildren(tr,lvl); //清楚缓存中的数据 that.clearCacheData(data); tr.remove(); }); } }; var active = { on:function (event,callback) { var filter = event.match(/\((.*)\)$/),eventName = (filter ? (event.replace(filter[0],'')+'_'+ filter[1]) : event); configs.callbacks[moduleName+'_'+eventName]=callback; }, callbackFn:function (event,params) { var filter = event.match(/\((.*)\)$/),eventName = (filter ? (event.replace(filter[0],'')+'_'+ filter[1]) : event); var key = moduleName+'_'+eventName,func = configs.callbacks[key]; if(!func) return; return func.call(this,params); }, render:function (options) { var tableTree = new TableTree(); tableTree.render(options); return { getTreeOptions:function () { return tableTree.config; }, getCheckedData:function () { return tableTree.getCheckedData(); }, reload:function (options) { tableTree.reload(options); }, openCheckedRows:function () { tableTree.openCheckedRows(); } ,closeCheckedRows:function () { tableTree.closeCheckedRows(); } ,closeAllRows:function () { tableTree.closeAllRows(); } ,openAllRows:function () { tableTree.openAllRows(); } ,sort:function (options) { var tableTreeid = $(tableTree.config.elem).attr('id'); var treeData = configs.tableTreeCache[tableTreeid]; tableTree.sort(options,treeData); delete tableTree.config.url; tableTree.config.data = treeData; tableTree.render(tableTree.config); } ,getTableTreeData:function () { return tableTree.getTableTreeData(); } ,on:function (event,callback) { tableTree.on(event,callback); } ,addTopRow:function (data) { tableTree.addTopRow(data); } ,delCheckedRows:function () { tableTree.delCheckedRows(); } }; } }; exports(moduleName, active); });