| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216 | /** * 基于layui的tree重写 * author: hsianglee * 最近修改时间: 2019/01/07 */layui.define(["jquery","laytpl"], function (exports) {    var $ = layui.jquery;    var laytpl = layui.laytpl;    var hint = layui.hint();    var MOD_NAME="eleTree";    //外部接口    var eleTree={        //事件监听        on: function(events, callback){            return layui.onevent.call(this, MOD_NAME, events, callback);        },        render: function(options) {            var inst = new Class(options);            return thisTree.call(inst);        }    }    var thisTree=function() {        var _self=this;        var options = _self.config;        // 暴漏外面的方法        return {            // 接收两个参数,1. 节点 key 2. 节点数据的数组            updateKeyChildren: function(key,data) {                if(options.data.length===0) return;                return _self.updateKeyChildren.call(_self,key,data);            },            updateKeySelf: function(key,data) {                if(options.data.length===0) return;                return _self.updateKeySelf.call(_self,key,data);            },            remove: function(key) {                if(options.data.length===0) return;                return _self.remove.call(_self,key);            },            append: function(key,data) {                if(options.data.length===0) return;                return _self.append.call(_self,key,data);            },            insertBefore: function(key,data) {                if(options.data.length===0) return;                return _self.insertBefore.call(_self,key,data);            },            insertAfter: function(key,data) {                if(options.data.length===0) return;                return _self.insertAfter.call(_self,key,data);            },            // 接收两个 boolean 类型的参数,1. 是否只是叶子节点,默认值为 false 2. 是否包含半选节点,默认值为 false            getChecked: function(leafOnly, includeHalfChecked) {                if(options.data.length===0) return;                return _self.getChecked.call(_self,leafOnly, includeHalfChecked);            },            // 接收勾选节点数据的数组            setChecked: function(data) {                if(options.data.length===0) return;                return _self.setChecked.call(_self,data);            },            // 取消选中            unCheckNodes: function() {                if(options.data.length===0) return;                return _self.unCheckNodes.call(_self);            },            expandAll: function() {                options.elem.children(".eleTree-node").children(".eleTree-node-group").empty();                _self.expandAll.call(_self,options.data,[],1,true);                _self.unCheckNodes();                _self.defaultChecked();            },            unExpandAll: function() {                return _self.unExpandAll.call(_self);            },            reload: function(options) {                return _self.reload.call(_self,options);            },            search: function(value) {                return _self.search.call(_self,value);            }        }    }    // 模板渲染    var TPL_ELEM=function(options,floor,parentStatus) {        return [            '{{# for(var i=0;i<d.length;i++){ }}',            '<div class="eleTree-node" data-'+options.request.key+'="{{d[i]["'+options.request.key+'"]}}" eletree-floor="'+floor+'" style="display: none;">',            '<div class="eleTree-node-content" style="padding-left: '+(options.indent*floor)+'px;">',            '<span class="eleTree-node-content-icon">',            '<i class="layui-icon layui-icon-triangle-r ',            function() {                if(options.lazy){                    var str=[                        '{{# if(!d[i]["'+options.request.isLeaf+'"]){ }}',                        'lazy-icon" ></i>',                        '{{# }else{ }}',                        'leaf-icon" style="color: transparent;" ></i>',                        '{{# } }}'                    ].join("");                    return str;                }                return ['{{# if(!d[i]["'+options.request.children+'"] || d[i]["'+options.request.children+'"].length===0){ }}',                    'leaf-icon" style="color: transparent;"',                    '{{# } }}',                    '"></i>'                ].join("");            }(),            '</span>',            function() {                if(options.showCheckbox){                    var status="";                    if(parentStatus==="1"){                        status='"1" checked';                    }else if(parentStatus==="2"){                        status='"2"';                    }else{                        status='"0"';                    }                    return [                        '{{# if(d[i]["'+options.request.checked+'"]) { }}',                        '<input type="checkbox" name="eleTree-node" eleTree-status="1" checked class="eleTree-hideen ',                        '{{# }else{ }}',                        '<input type="checkbox" name="eleTree-node" eleTree-status='+status+' class="eleTree-hideen ',                        '{{# } }}',                        '{{# if(d[i]["'+options.request.disabled+'"]) { }}',                        'eleTree-disabled',                        '{{# } }}',                        '" />'                    ].join("");                }                return ''            }(),            '<span class="eleTree-node-content-label">{{d[i]["'+options.request.name+'"]}}</span>',            '</div>',            '<div class="eleTree-node-group">',            '</div>',            '</div>',            '{{# } }}'        ].join("");    }    var TPL_NoText=function() {        return '<h3 class="eleTree-noText" style="text-align: center;height: 30px;line-height: 30px;color: #888;">{{d.emptText}}</h3>';    }    var Class=function(options) {        options.response=$.extend({}, this.config.response, options.response);        options.request=$.extend({}, this.config.request, options.request);        this.config = $.extend({}, this.config, options);        this.prevClickEle=null;        this.addKeyIndex=20181201;        this.nameIndex=1;        this.render();    };    Class.prototype={        constructor: Class,        config: {            elem: "",            data: [],            emptText: "暂无数据",        // 内容为空的时候展示的文本            renderAfterExpand: true,    // 是否在第一次展开某个树节点后才渲染其子节点            highlightCurrent: false,    // 是否高亮当前选中节点,默认值是 false。            defaultExpandAll: false,    // 是否默认展开所有节点            expandOnClickNode: true,    // 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。            checkOnClickNode: false,    // 是否在点击节点的时候选中节点,默认值为 false,即只有在点击复选框时才会选中节点。            defaultExpandedKeys: [],    // 默认展开的节点的 key 的数组            autoExpandParent: true,     // 展开子节点的时候是否自动展开父节点            showCheckbox: false,        // 节点是否可被选择            checkStrictly: false,       // 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false            defaultCheckedKeys: [],     // 默认勾选的节点的 key 的数组            accordion: false,           // 是否每次只打开一个同级树节点展开(手风琴效果)            indent: 16,                 // 相邻级节点间的水平缩进,单位为像素            lazy: false,                // 是否懒加载子节点,需与 load 方法结合使用            load: function() {},        // 加载子树数据的方法,仅当 lazy 属性为true 时生效            draggable: false,           // 是否开启拖拽节点功能            contextmenuList: [],        // 启用右键菜单,支持的操作有:"copy","add","edit","remove"            searchNodeMethod: null,     // 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏            method: "get",            url: "",            contentType: "",            headers: {},            done: null,            response: {                statusName: "code",                statusCode: 0,                dataName: "data"            },            request: {                name: "label",                key: "id",                children: "children",                disabled: "disabled",                checked: "checked",                isLeaf: "isLeaf"            }        },        render: function() {            if(this.config.indent>30){                this.config.indent=30;            }else if(this.config.indent<10){                this.config.indent=10;            }            var options=this.config;            options.where=options.where || {};            if(!options.elem) return hint.error("缺少elem参数");            options.elem=typeof options.elem === "string" ? $(options.elem) : options.elem;            this.filter=options.elem.attr("lay-filter");            // load加载框            options.elem.append('<div class="eleTree-loadData"><i class="layui-icon layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i></div>')            // 判断加载方式            if(options.data.length===0){                this.ajaxGetData();            }else{                this.renderData();            }        },        renderData: function() {            var options=this.config;            // 渲染第一层            laytpl(TPL_ELEM(options,0)).render(options.data, function(string){                options.elem.html(string).children().show();            });            // 懒加载 > 展开所有 > 初始展开项 > 初始渲染所有子节点 > 初始选中项 > 每次点击只渲染当前层(默认)            // 判断所有dom是否全部加载            if(!options.lazy){                if(!options.renderAfterExpand || options.defaultExpandAll || options.defaultExpandedKeys.length>0 || options.defaultCheckedKeys.length>0){                    this.expandAll(options.data,[],1);                }            }            this.eleTreeEvent();            this.checkboxRender();            this.checkboxEvent();            this.defaultChecked();            this.nodeEvent();            this.rightClickMenu();            if(!options.checkStrictly){                this.checkboxInit();            }        },        ajaxGetData: function() {            var options=this.config;            var _self=this;            if(!options.url) {                laytpl(TPL_NoText()).render(options, function(string){                    options.elem.html(string);                });                return;            }            var data = $.extend({}, options.where);            if(options.contentType && options.contentType.indexOf("application/json") == 0){ //提交 json 格式                data = JSON.stringify(data);            }            $.ajax({                type: options.method || 'get'                ,url: options.url                ,contentType: options.contentType                ,data: data                ,dataType: 'json'                ,headers: options.headers || {}                ,success: function(res){                    if(res[options.response.statusName] != options.response.statusCode || !res[options.response.dataName]){                        hint.error("请检查数据格式是否符合规范");                        typeof options.done === 'function' && options.done(res);                        return;                    }                    options.data=res[options.response.dataName];                    _self.renderData();                    typeof options.done === 'function' && options.done(res);                }            });        },        reload: function(options) {            var _self=this;            if(this.config.data && this.config.data.constructor === Array) this.config.data=[];            this.config = $.extend({}, this.config, options);            $(this.config.elem).off();  // 取消事件绑定,防止多次绑定事件            // reload记录选中的数据            // this.getChecked().forEach(function(val) {            //     if($.inArray(val.key,this.config.defaultCheckedKeys)===-1){            //         this.config.defaultCheckedKeys.push(val.key);            //     }            // },this);            return eleTree.render(this.config)        },        // 下拉        eleTreeEvent: function() {            var _self=this;            var options=this.config;            // 下拉            var expandOnClickNode=options.expandOnClickNode?".eleTree-node-content":".eleTree-node-content>.eleTree-node-content-icon";            options.elem.on("click",expandOnClickNode,function(e) {                e.stopPropagation();                var eleTreeNodeContent=$(this).parent(".eleTree-node").length===0?$(this).parent(".eleTree-node-content"):$(this);                var eleNode=eleTreeNodeContent.parent(".eleTree-node");                var sibNode=eleTreeNodeContent.siblings(".eleTree-node-group");                var el=eleTreeNodeContent.children(".eleTree-node-content-icon").children(".layui-icon");                // 添加active背景                if(_self.prevClickEle) _self.prevClickEle.removeClass("eleTree-node-content-active");                if(options.highlightCurrent) eleTreeNodeContent.addClass("eleTree-node-content-active");                _self.prevClickEle=eleTreeNodeContent;                if(el.hasClass("icon-rotate")){                    // 合并                    sibNode.children(".eleTree-node:not(.eleTree-search-hide)").hide("fast");                    el.removeClass("icon-rotate");                    return;                }                if(sibNode.children(".eleTree-node").length===0){                    var floor=Number(eleNode.attr("eletree-floor"))+1;                    var data=_self.reInitData(eleNode);                    var d=data.currentData;                    // 是否懒加载                    if(options.lazy && el.hasClass("lazy-icon")){                        el.removeClass("layui-icon-triangle-r").addClass("layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop");                        options.load(d,function(getData) {                            d[options.request.children]=getData;                            var eletreeStatus=eleTreeNodeContent.children("input.eleTree-hideen").attr("eletree-status");                            if(d[options.request.children] && d[options.request.children].length>0){                                laytpl(TPL_ELEM(options,floor,eletreeStatus)).render(d[options.request.children], function(string){                                    sibNode.append(string).children().show("fast");                                });                            }else{                                el.css("color","transparent").addClass("leaf-icon");                            }                            el.removeClass("lazy-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop").addClass("layui-icon-triangle-r icon-rotate");                            _self.checkboxRender();                            // 懒加载子元素选择祖父(待写)                        })                    }else{                        var eletreeStatus=eleTreeNodeContent.children("input.eleTree-hideen").attr("eletree-status");                        d[options.request.children] && d[options.request.children].length>0 && laytpl(TPL_ELEM(options,floor,eletreeStatus)).render(d[options.request.children], function(string){                            sibNode.append(string);                        });                        // 选择祖父                        var eleNode1=sibNode.children(".eleTree-node").eq(0);                        if(eleNode1.length===0){                            _self.checkboxRender();                            return;                        }                        var siblingNode1=eleNode1.siblings(".eleTree-node");                        var item1=eleNode1.children(".eleTree-node-content").children(".eleTree-hideen").get(0);                        _self.selectParents(item1,eleNode1,siblingNode1);                        _self.checkboxRender();                    }                }                // 显示隐藏没有搜索类的                sibNode.children(".eleTree-node:not(.eleTree-search-hide)").show("fast");                el.addClass("icon-rotate");                // 手风琴效果                if(options.accordion){                    var node=eleTreeNodeContent.parent(".eleTree-node").siblings(".eleTree-node");                    node.children(".eleTree-node-group").children(".eleTree-node:not(.eleTree-search-hide)").hide("fast");                    node.children(".eleTree-node-content").children(".eleTree-node-content-icon").children(".layui-icon").removeClass("icon-rotate");                }            })        },        // checkbox选中        checkboxEvent: function() {            var options=this.config;            var _self=this;            var checkOnClickNode=options.checkOnClickNode?".eleTree-node-content":".eleTree-checkbox";            // input添加属性eleTree-status:即input的三种状态,"0":未选中,"1":选中,"2":子孙部分选中            options.elem.on("click",checkOnClickNode,function(e,type) {                e.stopPropagation();                var eleTreeNodeContent=$(this).parent(".eleTree-node").length===0?$(this).parent(".eleTree-node-content"):$(this);                var checkbox=eleTreeNodeContent.children(".eleTree-checkbox");                if(checkbox.hasClass("eleTree-checkbox-disabled")) return;                // 获取点击所在数据                var node=eleTreeNodeContent.parent(".eleTree-node");                // var d=_self.reInitData(node).currentData;                // 实际的input                var inp=checkbox.siblings(".eleTree-hideen").get(0);                var childNode=eleTreeNodeContent.siblings(".eleTree-node-group").find("input[name='eleTree-node']");                // 添加active背景                if(_self.prevClickEle) _self.prevClickEle.removeClass("eleTree-node-content-active");                if(options.highlightCurrent) eleTreeNodeContent.addClass("eleTree-node-content-active");                _self.prevClickEle=eleTreeNodeContent;                if(!inp){                    return;                }                if(inp.checked){                    // 反选自身                    $(inp).prop("checked",false).attr("eleTree-status","0");                    // 点击祖父层选中子孙层                    if(!options.checkStrictly){                        childNode.prop("checked",false);                        childNode.attr("eleTree-status","0");                    }                }else{                    // 反选自身                    $(inp).prop("checked",true).attr("eleTree-status","1");                    // 点击祖父层选中子孙层                    if(!options.checkStrictly){                        childNode.prop("checked",true).attr("eleTree-status","1");                    }                }                var eleNode=eleTreeNodeContent.parent(".eleTree-node");                // 点击子孙层选中祖父层(递归)                if(!options.checkStrictly){                    var siblingNode=eleNode.siblings(".eleTree-node");                    // 点击子孙层选中祖父层(递归)                    _self.selectParents(inp,eleNode,siblingNode);                }                _self.checkboxRender();                if(type==="default") return;                layui.event.call(inp, MOD_NAME, 'nodeChecked('+ _self.filter +')', {                    node: eleNode,                    data: _self.reInitData(eleNode),                    isChecked: inp.checked                });            })        },        // 对后台数据有 checked:true 的默认选中项渲染父子层        checkboxInit: function() {            var options=this.config;            var _self=this;            options.elem.find("input[eleTree-status='1']").each(function(index,item) {                var checkboxEl=$(item).siblings(".eleTree-checkbox");                var childNode=checkboxEl.parent(".eleTree-node-content").siblings(".eleTree-node-group").find("input[name='eleTree-node']");                // 选择当前                checkboxEl.addClass("eleTree-checkbox-checked");                checkboxEl.children("i").addClass("layui-icon-ok").removeClass("eleTree-checkbox-line");                // 选择子孙                childNode.prop("checked","checked").attr("eleTree-status","1");                childNode.siblings(".eleTree-checkbox").addClass("eleTree-checkbox-checked");                childNode.siblings(".eleTree-checkbox").children("i").addClass("layui-icon-ok").removeClass("eleTree-checkbox-line");                // 选择祖父                var eleNode=checkboxEl.parent(".eleTree-node-content").parent(".eleTree-node");                var siblingNode=eleNode.siblings(".eleTree-node");                _self.selectParents(item,eleNode,siblingNode);            })            _self.checkboxRender();        },        // 通过子元素选中祖父元素        selectParents: function(inp,eleNode,siblingNode) {            // inp: 实际input(dom元素)            // eleNode: input父层类(.eleTree-node)            // siblingNode: 父层同级兄弟            while (Number(eleNode.attr("eletree-floor"))!==0) {                // 同级input状态存入数组                var arr=[];                arr.push($(inp).attr("eleTree-status"));                siblingNode.each(function(index,item) {                    var siblingIsChecked=$(item).children(".eleTree-node-content").children("input[name='eleTree-node']").attr("eleTree-status");                    arr.push(siblingIsChecked);                })                // 父元素的实际input                var parentInput=eleNode.parent(".eleTree-node-group").siblings(".eleTree-node-content").children("input[name='eleTree-node']");                // 父元素的checkbox替代                var parentCheckbox=parentInput.siblings(".eleTree-checkbox");                // 子都选中则选中父                if(arr.every(function(val) {                        return val==="1";                    })){                    parentInput.prop("checked",true).attr("eleTree-status","1");                }                // 子有一个未选中则checkbox第三种状态                if(arr.some(function(val) {                        return val==="0" || val==="2";                    })){                    parentInput.attr("eleTree-status","2");                }                // 子全部未选中则取消父选中(并且取消第三种状态)                if(arr.every(function(val) {                        return val==="0";                    })){                    parentInput.prop("checked",false);                    parentInput.attr("eleTree-status","0");                }                var parentNode=eleNode.parents("[eletree-floor='"+(Number(eleNode.attr("eletree-floor"))-1)+"']");                var parentCheckbox=parentNode.children(".eleTree-node-content").children("input[name='eleTree-node']").get(0);                var parentSiblingNode=parentNode.siblings(".eleTree-node");                eleNode=parentNode;                inp=parentCheckbox;                siblingNode=parentSiblingNode;            }        },        // 初始展开所有        expandAll: function(data,arr,floor,isMethodsExpandAll) {            var options=this.config;            var _self=this;            data.forEach(function(val,index) {                arr.push(index);                if(val[options.request.children] && val[options.request.children].length>0){                    var el=options.elem.children(".eleTree-node").eq(arr[0]).children(".eleTree-node-group");                    for(var i=1;i<arr.length;i++){                        el=el.children(".eleTree-node").eq(arr[i]).children(".eleTree-node-group");                    }                    laytpl(TPL_ELEM(options,floor)).render(val[options.request.children], function(string){                        el.append(string);                        // 判断是否展开所有                        if(options.defaultExpandAll || isMethodsExpandAll){                            el.siblings(".eleTree-node-content").children(".eleTree-node-content-icon").children(".layui-icon").addClass("icon-rotate");                            el.children().show();                        }else if(options.defaultExpandedKeys.length>0) {                            // 展开指定id项                            var id=el.parent(".eleTree-node").attr("data-"+options.request.key);                            id=isNaN(id) ? id : Number(id);                            if($.inArray(id,options.defaultExpandedKeys)!==-1){                                el.siblings(".eleTree-node-content").children(".eleTree-node-content-icon").children(".layui-icon").addClass("icon-rotate");                                el.children().show();                                // 展开子项是否继续展开祖父项                                if(options.autoExpandParent){                                    var eleP=el.parent(".eleTree-node[data-"+options.request.key+"]").parents(".eleTree-node");                                    eleP.each(function(i,item) {                                        if($(item).attr("data-"+options.request.key)){                                            $(item).children(".eleTree-node-group").siblings(".eleTree-node-content").children(".eleTree-node-content-icon").children(".layui-icon").addClass("icon-rotate");                                            $(item).children(".eleTree-node-group").children().show();                                        }                                    })                                }                            }                        }                    });                    floor++;                    _self.expandAll(val[options.request.children],arr,floor,isMethodsExpandAll);                    floor--;                }                // 重置数组索引                arr.pop();            })        },        // 初始默认选中        defaultChecked: function() {            var options=this.config;            if(options.defaultCheckedKeys.length===0){                return false;            }            // 判断是否父子无关            if(options.checkStrictly){                options.defaultCheckedKeys.forEach(function(val,index) {                    var nodeContent=options.elem.find("[data-"+options.request.key+"='"+val+"']").children(".eleTree-node-content");                    // 如果当前没选中则选中                    if(nodeContent.children(".eleTree-hideen").prop("checked")===false){                        nodeContent.children(".eleTree-checkbox").trigger("click",["default"]);                    }                })                return false;            }            // 父元素优先            var arr=$.extend([],options.defaultCheckedKeys);            options.defaultCheckedKeys.forEach(function(val,index) {                options.elem.find("[data-"+options.request.key+"='"+val+"']").find("[data-"+options.request.key+"]").each(function(i,item) {                    var id=$(item).attr("data-"+options.request.key);                    id=isNaN(id) ? id : Number(id);                    var isInArrayIndex=$.inArray(id,arr);                    if(isInArrayIndex!==-1){                        arr.splice(isInArrayIndex,1);                    }                })            })            arr.forEach(function(val,index) {                var nodeContent=options.elem.find("[data-"+options.request.key+"='"+val+"']").children(".eleTree-node-content");                // 如果当前没选中则选中                if(nodeContent.children(".eleTree-hideen").prop("checked")===false){                    nodeContent.children(".eleTree-checkbox").trigger("click",["default"]);                }            })        },        // 自定义checkbox解析        checkboxRender: function() {            var options=this.config;            options.elem.find(".eleTree-checkbox").remove();            options.elem.find("input.eleTree-hideen[type=checkbox]").each(function(index,item){                if($(item).hasClass("eleTree-disabled")){                    $(item).after('<div class="eleTree-checkbox eleTree-checkbox-disabled"><i class="layui-icon"></i></div>');                }else{                    $(item).after('<div class="eleTree-checkbox"><i class="layui-icon"></i></div>');                }                var checkbox=$(item).siblings(".eleTree-checkbox");                if($(item).attr("eletree-status")==="1"){                    checkbox.addClass("eleTree-checkbox-checked");                    checkbox.children("i").addClass("layui-icon-ok").removeClass("eleTree-checkbox-line");                }else if($(item).attr("eletree-status")==="0"){                    checkbox.removeClass("eleTree-checkbox-checked");                    checkbox.children("i").removeClass("layui-icon-ok eleTree-checkbox-line");                }else if($(item).attr("eletree-status")==="2"){                    checkbox.addClass("eleTree-checkbox-checked");                    checkbox.children("i").removeClass("layui-icon-ok").addClass("eleTree-checkbox-line");                }            })        },        // 通过dom节点找对应数据        reInitData: function(node) {            var options=this.config;            var i=node.index();            var floor=Number(node.attr("eletree-floor"));            var arr=[];     // 节点对应的index            while (floor>=0) {                arr.push(i);                floor=floor-1;                node=node.parents("[eletree-floor='"+floor+"']");                i=node.index();            }            arr=arr.reverse();            var oData=this.config.data;            // 当前节点的父节点数据            var parentData=oData[arr[0]];            // 当前节点的data数据            var d = oData[arr[0]];            for(var i = 1; i<arr.length; i++){                d = d[options.request.children]?d[options.request.children][arr[i]]:d;            }            for(var i = 1; i<arr.length-1; i++){                parentData = parentData[options.request.children]?parentData[options.request.children][arr[i]]:parentData;            }            return {                currentData: d,                parentData: {                    data: parentData,                    childIndex: arr[arr.length-1]                },                index: arr            }        },        // 通过key查找数据        keySearchToOpera: function(key,callback) {            var options=this.config;            var _self=this;            // 查找数据            var fn=function(data) {                var obj={                    i: 0,                    len: data.length                }                for(;obj.i<obj.len;obj.i++){                    if(data[obj.i][options.request.key]!==key){                        if(data[obj.i][options.request.children] && data[obj.i][options.request.children].length>0){                            fn(data[obj.i][options.request.children]);                        }                    }else{                        callback(data,obj);                    }                }            }            fn(options.data);        },        updateKeyChildren: function(key,data) {            var options=this.config;            var node=options.elem.find("[data-"+options.request.key+"='"+key+"']");            var floor=Number(node.attr("eletree-floor"))+1;            var _self=this;            this.keySearchToOpera(key,function(d,obj) {                // 数据更新                d[obj.i][options.request.children]=data;                // dom更新                node.length!==0 && laytpl(TPL_ELEM(options,floor)).render(data, function(string){                    $(node).children(".eleTree-node-group").empty().append(string);                    options.defaultExpandAll && $(node).children(".eleTree-node-group").children().show();                });                _self.unCheckNodes();                _self.defaultChecked();            });        },        updateKeySelf: function(key,data) {            var options=this.config;            var node=options.elem.find("[data-"+options.request.key+"='"+key+"']").children(".eleTree-node-content");            var floor=Number(node.attr("eletree-floor"))+1;            data[options.request.name] && node.children(".eleTree-node-content-label").text(data[options.request.name]);            data[options.request.disabled] && node.children(".eleTree-hideen").addClass("eleTree-disabled")                .siblings(".eleTree-checkbox").addClass("eleTree-checkbox-disabled");            // 数据更新            var getData=this.keySearchToOpera(key,function(d,obj) {                data[options.request.key]=d[obj.i][options.request.key];                data[options.request.children]=d[obj.i][options.request.children];                d[obj.i]=$.extend({},d[obj.i],data);                console.log(options.data);            });        },        remove: function(key) {            var options=this.config;            var node=options.elem.find("[data-"+options.request.key+"='"+key+"']");            var pElem=node.parent(".eleTree-node-group");            // 数据删除            this.keySearchToOpera(key,function(data,obj) {                data.splice(obj.i,1);                obj.i--;                obj.len--;                node.length!==0 && options.elem.find("[data-"+options.request.key+"='"+key+"']").remove();                if(pElem.children(".eleTree-node").length===0){                    pElem.siblings(".eleTree-node-content").children(".eleTree-node-content-icon").children(".layui-icon").css("color", "transparent");                }            });            this.unCheckNodes();            this.defaultChecked();        },        append: function(key,data) {            var options=this.config;            var node=options.elem.find("[data-"+options.request.key+"='"+key+"']");            var floor=Number(node.attr("eletree-floor"))+1;            // 数据更新            this.keySearchToOpera(key,function(d,obj) {                if(d[obj.i][options.request.children]){                    d[obj.i][options.request.children].push(data);                }else{                    d[obj.i][options.request.children]=[data];                }                var arr=d[obj.i][options.request.children];                // 添加之后长度为1,则原来没有三角,添加三角                if(arr.length===1){                    node.children(".eleTree-node-content").find(".eleTree-node-content-icon .layui-icon").removeAttr("style").addClass("icon-rotate");                }                var len=arr.length;                var eletreeStatus=node.children(".eleTree-node-content").children("input.eleTree-hideen").attr("eletree-status");                eletreeStatus=eletreeStatus==="2" ? "0" : eletreeStatus;                node.length!==0 && laytpl(TPL_ELEM(options,floor,eletreeStatus)).render([arr[len-1]], function(string){                    node.children(".eleTree-node-group").append(string).children().show();                });            });            this.checkboxRender();        },        insertBefore: function(key,data) {            var options=this.config;            var node=options.elem.find("[data-"+options.request.key+"='"+key+"']");            var floor=Number(node.attr("eletree-floor"));            // 数据更新            this.keySearchToOpera(key,function(d,obj) {                d.splice(obj.i,0,data);                obj.i++;                obj.len++;                var eletreeStatus=node.parent(".eleTree-node-group").length===0 ? "0" : node.parent(".eleTree-node-group").parent(".eleTree-node")                        .children(".eleTree-node-content").children("input.eleTree-hideen").attr("eletree-status");                eletreeStatus=eletreeStatus==="2" ? "0" : eletreeStatus;                node.length!==0 && laytpl(TPL_ELEM(options,floor,eletreeStatus)).render([data], function(string){                    node.before(string).prev(".eleTree-node").show();                });            });            this.checkboxRender();        },        insertAfter: function(key,data) {            var options=this.config;            var node=options.elem.find("[data-"+options.request.key+"='"+key+"']");            var floor=Number(node.attr("eletree-floor"));            // 数据更新            this.keySearchToOpera(key,function(d,obj) {                d.splice(obj.i+1,0,data);                obj.i++;                obj.len++;                var eletreeStatus=node.parent(".eleTree-node-group").length===0 ? "0" : node.parent(".eleTree-node-group").parent(".eleTree-node")                        .children(".eleTree-node-content").children("input.eleTree-hideen").attr("eletree-status");                eletreeStatus=eletreeStatus==="2" ? "0" : eletreeStatus;                node.length!==0 && laytpl(TPL_ELEM(options,floor,eletreeStatus)).render([data], function(string){                    $(node).after(string).next(".eleTree-node").show();                });            });            this.checkboxRender();            // if(!options.lazy){            //     if(!options.renderAfterExpand || options.defaultExpandAll || options.defaultExpandedKeys.length>0){            //         this.expandAll(options.data,[],1);            //     }            // }        },        getChecked: function(leafOnly, includeHalfChecked) {            var options=this.config                ,el                ,arr=[];            leafOnly=leafOnly || false;            includeHalfChecked=includeHalfChecked || false;            if(leafOnly){                el=options.elem.find(".layui-icon.leaf-icon").parent(".eleTree-node-content-icon")                    .siblings("input.eleTree-hideen[eletree-status='1']");            }else if(includeHalfChecked){                el=options.elem.find("input.eleTree-hideen[eletree-status='1'],input.eleTree-hideen[eletree-status='2']");            }else{                el=options.elem.find("input.eleTree-hideen[eletree-status='1']");            }            el.each(function(index,item) {                var obj={};                var id=$(item).parent(".eleTree-node-content").parent(".eleTree-node").attr("data-"+options.request.key);                id=isNaN(id) ? id : Number(id);                obj[options.request.key]=id;                obj.elem=item;                obj.othis=$(item).siblings(".eleTree-checkbox").get(0)                arr.push(obj);            })            return arr;        },        setChecked: function(arr) {            var options=this.config;            this.unCheckNodes();            arr.forEach(function(val) {                if($.inArray(val,options.defaultCheckedKeys)===-1){                    options.defaultCheckedKeys.push(val);                }            })            this.defaultChecked();        },        unCheckNodes: function() {            var options=this.config;            options.elem.find("input.eleTree-hideen[eletree-status='1'],input.eleTree-hideen[eletree-status='2']").each(function(index,item) {                $(item).attr("eletree-status","0").prop("checked",false);            });            this.checkboxRender();        },        unExpandAll: function() {            var options=this.config;            options.elem.find(".layui-icon.icon-rotate").removeClass("icon-rotate")                .parent(".eleTree-node-content-icon").parent(".eleTree-node-content")                .siblings(".eleTree-node-group").children(".eleTree-node").hide();        },        // 节点事件        nodeEvent: function() {            var _self=this;            var options=this.config;            // 节点被点击的回调事件            options.elem.on("click",".eleTree-node-content",function(e) {                var eleNode=$(this).parent(".eleTree-node");                $("#tree-menu").hide().remove();                layui.event.call(eleNode, MOD_NAME, 'nodeClick('+ _self.filter +')', {                    node: eleNode,                    data: _self.reInitData(eleNode),                    event: e                });            })            // 节点右键的回调事件            options.elem.on("contextmenu",".eleTree-node-content",function(e) {                var eleNode=$(this).parent(".eleTree-node");                layui.event.call(eleNode, MOD_NAME, 'nodeContextmenu('+ _self.filter +')', {                    node: eleNode,                    data: _self.reInitData(eleNode),                    event: e                });            })            // 节点被拖拽的回调事件            options.draggable && options.elem.on("mousedown",".eleTree-node-content",function(e) {                var time=0;                var eleNode=$(this).parent(".eleTree-node");                var eleFloor=Number(eleNode.attr("eletree-floor"));                var groupNode=eleNode.parent(".eleTree-node-group");                e.stopPropagation();                options.elem.css("user-select","none");                var cloneNode=eleNode.clone(true);                var temNode=eleNode.clone(true);                var x=e.clientX-options.elem.offset().left;                var y=e.clientY-options.elem.offset().top;                options.elem.append(cloneNode);                cloneNode.css({                    "display": "none",                    "opacity": 0.7,                    "position": "absolute",                    "background-color": "#f5f5f5",                    "width": "100%"                })                var currentData=_self.reInitData(eleNode);                var isStop=false;                $(document).on("mousemove",function(e) {                    // t为了区别click事件                    time++;                    if(time>2){                        var xx=e.clientX-options.elem.offset().left+10;                        var yy=e.clientY-options.elem.offset().top+$(document).scrollTop()-5;   // 加上浏览器滚动高度                        cloneNode.css({                            display: "block",                            left: xx+"px",                            top: yy+"px"                        })                    }                }).on("mouseup",function(e) {                    $(document).off("mousemove").off("mouseup");                    var target=$(e.target).parents(".eleTree-node").eq(0);                    cloneNode.remove();                    options.elem.css("user-select","auto");                    // 当前点击的是否时最外层                    var isCurrentOuterMost=eleNode.parent().get(0).isEqualNode(options.elem.get(0))                    // 目标是否时最外层                    var isTargetOuterMost=$(e.target).get(0).isEqualNode(options.elem.get(0))                    if(isTargetOuterMost){                        target=options.elem;                    }                    // 判断是否超出边界                    if(target.parents(options.elem).length===0 && !isTargetOuterMost){                        return;                    }                    // 判断初始与结束是否是同一个节点                    if(target.get(0).isEqualNode(eleNode.get(0))){                        return;                    }                    // 判断是否是父节点放到子节点                    var tFloor=target.attr("eletree-floor");                    var isInChild=false;                    eleNode.find("[eletree-floor='"+tFloor+"']").each(function() {                        if(this.isEqualNode(target.get(0))){                            isInChild=true;                        }                    })                    if(isInChild){                        return;                    }                    var targetData=_self.reInitData(target);                    layui.event.call(target, MOD_NAME, 'nodeDrag('+ _self.filter +')', {                        current: {                            node: eleNode,                            data: currentData                        },                        target: {                            node: target,                            data: targetData                        },                        stop: function() {                            isStop=true;                        }                    });                    // 拖拽是否取消                    if(isStop){                        return false;                    }                    // 数据更改                    var currList=currentData.parentData.data[options.request.children]                    var currIndex=currentData.parentData.childIndex                    var currData=currentData.currentData;                    var tarData=targetData.currentData;                    // 当前是否是最外层                    isCurrentOuterMost ? options.data.splice(currIndex,1) : currList.splice(currIndex,1)                    // 目标是否是最外层                    isTargetOuterMost ? options.data.push(currData) : (function() {                            !tarData[options.request.children] ? tarData[options.request.children]=[] : "";                            tarData[options.request.children].push(currData);                        })()                    // dom互换                    eleNode.remove();                    // 最外层判断                    if(isTargetOuterMost){                        target.append(temNode);                        var floor=0;                    }else{                        target.children(".eleTree-node-group").append(temNode);                        var floor=Number(target.attr("eletree-floor"))+1;                    }                    // 加floor和padding                    temNode.attr("eletree-floor",String(floor));                    temNode.children(".eleTree-node-content").css("padding-left",floor*options.indent+"px");                    // 通过floor差值计算子元素的floor                    var countFloor=eleFloor-floor;                    temNode.find(".eleTree-node").each(function(index,item) {                        var f=Number($(item).attr("eletree-floor"))-countFloor;                        $(item).attr("eletree-floor",String(f));                        $(item).children(".eleTree-node-content").css("padding-left",f*options.indent+"px");                    })                    // 原dom去三角                    var leaf=groupNode.children(".eleTree-node").length===0;                    leaf && groupNode.siblings(".eleTree-node-content")                        .children(".eleTree-node-content-icon").children(".layui-icon")                        .removeClass("icon-rotate").css("color","transparent");                    // 当前的增加三角                    var cLeaf=target.children(".eleTree-node-group").children(".eleTree-node").length===0;                    !cLeaf && target.children(".eleTree-node-content")                        .children(".eleTree-node-content-icon").children(".layui-icon")                        .addClass("icon-rotate").removeAttr("style");                    _self.unCheckNodes();                    _self.defaultChecked();                })            })        },        rightClickMenu: function() {            var _self=this;            var options=this.config;            if(options.contextmenuList.length<=0){                return;            }            $(document).on("click",function() {                $("#tree-menu").hide().remove();            });            var menuStr=['<ul id="tree-menu">'                ,$.inArray("copy",options.contextmenuList)!==-1?'<li class="copy"><a href="javascript:;">复制</a></li>':''                ,$.inArray("add",options.contextmenuList)!==-1?'<li class="add"><a href="javascript:;">新增</a></li>'+                    '<li class="insertBefore"><a href="javascript:;">插入节点前</a></li>'+                    '<li class="insertAfter"><a href="javascript:;">插入节点后</a></li>'+                    '<li class="append"><a href="javascript:;">插入子节点</a></li>' : ""                ,$.inArray("edit",options.contextmenuList)!==-1?'<li class="edit"><a href="javascript:;">修改</a></li>':''                ,$.inArray("remove",options.contextmenuList)!==-1?'<li class="remove"><a href="javascript:;">删除</a></li>':''                ,'</ul>'].join("");            this.treeMenu=$(menuStr);            options.elem.off("contextmenu").on("contextmenu",".eleTree-node-content",function(e) {                var that=this;                e.stopPropagation();                e.preventDefault();                // 添加active背景                if(_self.prevClickEle) _self.prevClickEle.removeClass("eleTree-node-content-active");                $(this).addClass("eleTree-node-content-active");                var eleNode=$(this).parent(".eleTree-node");                var nodeData=_self.reInitData(eleNode);                // 菜单位置                $(document.body).after(_self.treeMenu);                $("#tree-menu li.insertBefore,#tree-menu li.insertAfter,#tree-menu li.append").hide();                $("#tree-menu li.copy,#tree-menu li.add,#tree-menu li.edit,#tree-menu li.remove").show();                $("#tree-menu").css({                    left: e.pageX,                    top: e.pageY                }).show();                // 复制                $("#tree-menu li.copy").off().on("click",function() {                    var el = $(that).children(".eleTree-node-content-label").get(0);                    var selection = window.getSelection();                    var range = document.createRange();                    range.selectNodeContents(el);                    selection.removeAllRanges();                    selection.addRange(range);                    document.execCommand('Copy', 'false', null);                    selection.removeAllRanges();                });                // 新增                $("#tree-menu li.add").off().on("click",function(e) {                    e.stopPropagation();                    $(this).hide().siblings("li.copy,li.edit,li.remove").hide();                    $(this).siblings(".append,li.insertAfter,li.insertBefore").show();                })                // 添加的默认数据                var obj={};                obj[options.request.key]=_self.addKeyIndex;                obj[options.request.name]="未命名"+_self.nameIndex;                var arr=["Append","InsertBefore","InsertAfter"];                arr.forEach(function(val) {                    var s=val[0].toLocaleLowerCase()+val.slice(1,val.length);                    $("#tree-menu li."+s).off().on("click",function(e) {                        var node=$(that).parent(".eleTree-node");                        var key=node.attr("data-"+options.request.key);                        key=isNaN(key) ? key : Number(key);                        var isStop=false;                        var s=val[0].toLocaleLowerCase()+val.slice(1,val.length);                        layui.event.call(node, MOD_NAME, 'node'+val+'('+ _self.filter +')', {                            node: node,                            data: nodeData.currentData,                            // 重新设置数据                            setData: function(o) {                                _self[s](key,$.extend({},obj,o));                                isStop=true;                            },                            // 停止添加                            stop: function() {                                isStop=true;                            }                        });                        if(isStop) return;                        _self[s](key,obj)                        _self.nameIndex++;                        _self.addKeyIndex++;                    })                })                // 编辑                $("#tree-menu li.edit").off().on("click",function(e) {                    e.stopPropagation();                    $("#tree-menu").hide().remove();                    var node=$(that).parent(".eleTree-node");                    var key=node.attr("data-"+options.request.key);                    key=isNaN(key) ? key : Number(key);                    var label=$(that).children(".eleTree-node-content-label").hide();                    var text=label.text();                    var inp="<input type='text' value='"+text+"' class='eleTree-node-content-input' />";                    label.after(inp);                    label.siblings(".eleTree-node-content-input").focus().select().off().on("blur",function() {                        var val=$(this).val();                        var isStop=false;                        var inpThis=this;                        layui.event.call(node, MOD_NAME, 'nodeEdit('+ _self.filter +')', {                            node: node,                            value: val,                            data: nodeData.currentData,                            // 停止添加                            stop: function() {                                isStop=true;                                $(inpThis).siblings(".eleTree-node-content-label").show();                                $(inpThis).remove();                            }                        });                        if(isStop) return;                        // 修改数据                        _self.reInitData(eleNode).currentData[options.request.name]=val;                        // 修改dom                        $(this).siblings(".eleTree-node-content-label").text(val).show();                        $(this).remove();                    }).on("mousedown",function(e) {                        // 防止input拖拽                        e.stopPropagation();                    })                })                // 删除                $("#tree-menu li.remove").off().on("click",function(e) {                    var node=$(that).parent(".eleTree-node");                    var key=node.attr("data-"+options.request.key);                    key=isNaN(key) ? key : Number(key);                    var isStop=false;                    layui.event.call(node, MOD_NAME, 'nodeRemove('+ _self.filter +')', {                        node: node,                        data: nodeData.currentData,                        // 停止添加                        stop: function() {                            isStop=true;                        }                    });                    if(isStop) return;                    _self.remove(key);                })                _self.prevClickEle=$(this);            })        },        search: function(value) {            var options=this.config;            if(!options.searchNodeMethod || typeof options.searchNodeMethod !== "function"){                return;            }            var data=options.data;            // 数据递归            var traverse=function(data) {                data.forEach(function(val,index) {                    // 所有查找到的节点增加属性                    val.visible=options.searchNodeMethod(value,val);                    if(val[options.request.children] && val[options.request.children].length>0){                        traverse(val[options.request.children]);                    }                    //如果当前节点属性为隐藏,判断其子节点是否有显示的,如果有,则当前节点改为显示                    if(!val.visible){                        let childSomeShow = false;                        if(val[options.request.children] && val[options.request.children].length>0){                            childSomeShow=val[options.request.children].some(function(v,i) {                                return v.visible;                            })                        }                        val.visible = childSomeShow;                    }                    // 通过节点的属性,显示隐藏各个节点,并添加删除搜索类                    var el=options.elem.find("[data-"+options.request.key+"='"+val[options.request.key]+"']");                    if(val.visible){                        el.removeClass("eleTree-search-hide");                        // 判断父节点是否展开,如果父节点没有展开,则子节点也不要显示                        var parentEl=el.parent(".eleTree-node-group").parent(".eleTree-node");                        var isParentOpen=parentEl.children(".eleTree-node-content").children(".eleTree-node-content-icon").children(".layui-icon.layui-icon-triangle-r").hasClass("icon-rotate")                        if((parentEl.length>0 && isParentOpen) || parentEl.length===0){                            el.show();                        }                    }else{                        el.hide().addClass("eleTree-search-hide");                    }                    // 删除子层属性                    if(val[options.request.children] && val[options.request.children].length>0){                        val[options.request.children].forEach(function(v,i) {                            delete v.visible;                        })                    }                })            }            traverse(data);            // 删除最外层属性            var arr=[];            data.forEach(function(val) {                arr.push(val.visible);                delete val.visible;            })            // 如果第一层的所有的都隐藏,则显示文本            if(arr.every(function(v) {                    return v===false;                })){                laytpl(TPL_NoText()).render(options, function(string){                    options.elem.append(string);                });            }else{                options.elem.children(".eleTree-noText").remove();            }        }    }    exports(MOD_NAME,eleTree);})
 |