精华内容
下载资源
问答
  • layui树形组件获取选中id

    千次阅读 2020-08-06 14:44:50
    编写权限分配用到的 layui树形组件 官方文档https://www.layui.com/doc/modules/tree.html //基本演示 tree.render({ elem: '#test12' ,data: data //具体data格式看官方文档 ,showCheckbox: true //是否显示复...

    编写权限分配用到的 layui树形组件

    官方文档https://www.layui.com/doc/modules/tree.html

     //基本演示
      tree.render({
        elem: '#test12'
        ,data: data //具体data格式看官方文档
        ,showCheckbox: true  //是否显示复选框
        ,id: 'demoId1'
        ,isJump: true //是否允许点击节点时弹出新窗口跳转
        ,click: function(obj){
          var data = obj.data;  //获取当前点击的节点数据
          layer.msg('状态:'+ obj.state + '<br>节点数据:' + JSON.stringify(data));
        }
      });
      
       var checkData = tree.getChecked('demoId1');
    
       var list = new Array();
    
       list = getChecked_list(checkData);
    
       console.log(checkData)
    
       console.log(list);
    
      function getChecked_list(data) {
             var id = "";
             $.each(data, function (index, item) {
                 if (id != "") {
                     id = id + "," + item.id;
                 } else {
                     id = item.id;
                 }
                 var i = getChecked_list(item.children);
                 if (i != "") {
                     id = id + "," + i;
                 }
             });
             return id;
       }
    
    
    

    参考https://www.cnblogs.com/zdzdbk/p/13208503.html

    展开全文
  • 递归(layui树形组件数据)

    千次阅读 2019-08-03 09:12:42
    layui树形组件需要下列形式的数据。处理数据库数据的时候用到递归,但是有一点点变化。 原数据: Array ( [0] => Array ( [id] => 23 [name] => admin/article/lst [title] => 文档 [s...

    layui树形组件需要下列形式的数据。处理数据库数据的时候用到递归,但是有一点点变化。
    在这里插入图片描述
    原数据:

    Array
    (
        [0] => Array
            (
                [id] => 23
                [name] => admin/article/lst
                [title] => 文档
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 0
                [show] => 1
            )
    
        [1] => Array
            (
                [id] => 22
                [name] => admin/ad/add
                [title] => 广告添加
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 18
                [show] => 1
            )
    
        [2] => Array
            (
                [id] => 20
                [name] => admin/ad/del/1
                [title] => 广告删除1
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 19
                [show] => 1
            )
    
        [3] => Array
            (
                [id] => 19
                [name] => admin/ad/del
                [title] => 广告删除
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 18
                [show] => 1
            )
    
        [4] => Array
            (
                [id] => 18
                [name] => admin/ad/lst
                [title] => 广告
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 0
                [show] => 1
            )
    
        [5] => Array
            (
                [id] => 14
                [name] => admin/admin
                [title] => 管理员
                [status] => 0
                [condition] => 
                [type] => 1
                [pid] => 0
                [show] => 1
            )
    
        [6] => Array
            (
                [id] => 15
                [name] => admin/admin/add
                [title] => 管理员添加
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 14
                [show] => 1
            )
    
        [7] => Array
            (
                [id] => 16
                [name] => admin/admin/del
                [title] => 管理员删除
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 14
                [show] => 1
            )
    
        [8] => Array
            (
                [id] => 24
                [name] => admin/article/add
                [title] => 文档添加
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 23
                [show] => 1
            )
    
        [9] => Array
            (
                [id] => 25
                [name] => admin/article/del
                [title] => 文档删除
                [status] => 1
                [condition] => 
                [type] => 1
                [pid] => 23
                [show] => 1
            )
    
    )
    
    

    php代码:

     public function getShu()
        {
            $rules = self::order('id', 'desc')->select();
            $re = $this->_getShu($rules);
            return $re;
        }
    
        public function _getShu($data, $pid = 0)
        {
            $t = [];
            foreach ($data as $k => $v) {
                if ($v['pid'] == $pid) {
                    $str['title'] = $v['title'];
                    $str['id'] = $v['id'];
                    $str['children'] = $this->_getShu($data, $v['id']);
                    if (empty($str['children'])) {
                        unset($str['children']);
                    }
                    $t[] = $str;
                }
            }
            return $t;
        }
    

    处理后得到的数据:

    Array
    (
        [0] => Array
            (
                [title] => 文档
                [id] => 23
                [children] => Array
                    (
                        [0] => Array
                            (
                                [title] => 文档删除
                                [id] => 25
                            )
    
                        [1] => Array
                            (
                                [title] => 文档添加
                                [id] => 24
                            )
    
                    )
    
            )
    
        [1] => Array
            (
                [title] => 广告
                [id] => 18
                [children] => Array
                    (
                        [0] => Array
                            (
                                [title] => 广告添加
                                [id] => 22
                            )
    
                        [1] => Array
                            (
                                [title] => 广告删除
                                [id] => 19
                                [children] => Array
                                    (
                                        [0] => Array
                                            (
                                                [title] => 广告删除1
                                                [id] => 20
                                            )
    
                                    )
    
                            )
    
                    )
    
            )
    
        [2] => Array
            (
                [title] => 管理员
                [id] => 14
                [children] => Array
                    (
                        [0] => Array
                            (
                                [title] => 管理员删除
                                [id] => 16
                            )
    
                        [1] => Array
                            (
                                [title] => 管理员添加
                                [id] => 15
                            )
    
                    )
    
            )
    
    )
    
    
    展开全文
  • layui树形组件懒加载实现及相关用法

    千次阅读 2019-11-28 10:58:37
    layui树形组件懒加载实现          工作中需要用到Layui前端框架,但使用过程中发现需要用到树形组件懒加载方式,可惜的是Layui仍未实现树形组件懒加载,网上大神们写了好多文章介绍但总...

    layui树形组件懒加载实现

             工作中需要用到Layui前端框架,但使用过程中发现需要用到树形组件懒加载方式,可惜的是Layui仍未实现树形组件懒加载,网上大神们写了好多文章介绍但总感觉不如自己写一个。以下代码比较多,可能读者没有耐心看完,我权当是自己作一下笔记吧,以后想起来的时候会持续更新下去,若有什么好的建议,希望能下方给我留言,我一定会想办法改进…
             使用方式也在后方通过实例展示。代码最初不是很多的,只实现了懒加载功能,可后面持续用到懒加载下拉树、懒加载下拉框树形组件、懒加载表格下拉框树形组件,代码便这样慢慢积累起来了。很多方法及实现方式是参考的layui.js,很希望贤心有闲心的时候完善一下layui吧。如果还是不明白,建议直接研读原码,希望能给大家带来帮助。

    一、js代码如下:

    /**
     
     @Name:layui.treelazy 树,懒加载实现
     @Author:xxx
     @License:MIT
    
     */
    
    layui.define('form', function(exports) {
    	"use strict";
    
    	var $ = layui.$,
    		form = layui.form
    
    		//模块名
    		,
    		MOD_NAME = 'treelazy'
    
    		//外部接口
    		,
    		treelazy = {
    			config: {},
    			index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0
    
    				//设置全局项
    				,
    			set: function(options) {
    					var that = this;
    					that.config = $.extend({}, that.config, options);
    					return that;
    				}
    
    				//事件监听
    				,
    			on: function(events, callback) {
    				return layui.onevent.call(this, MOD_NAME, events, callback);
    			}
    		}
    
    		//操作当前实例
    		,
    		thisModule = function() {
    			var that = this,
    				options = that.config,
    				id = options.id || that.index;
    
    			thisModule.that[id] = that; //记录当前实例对象
    			thisModule.config[id] = options; //记录当前实例配置项
    
    			return {
    				config: options
    					//重置实例
    					,
    				reload: function(options) {
    					that.reload.call(that, options);
    				},
    				getChecked: function() {
    					return that.getChecked.call(that);
    				},
    				setChecked: function(id) { //设置值
    					return that.setChecked.call(that, id);
    				}
    			}
    		}
    
    		//获取当前实例配置项
    		,
    		getThisModuleConfig = function(id) {
    			var config = thisModule.config[id];
    			if (!config) hint.error('The ID option was not found in the ' + MOD_NAME + ' instance');
    			return config || null;
    		}
    
    		//字符常量
    		,
    		SHOW = 'layui-show',
    		HIDE = 'layui-hide',
    		NONE = 'layui-none',
    		DISABLED = 'layui-disabled'
    
    		,
    		ELEM_VIEW = 'layui-tree',
    		ELEM_SET = 'layui-tree-set',
    		ICON_CLICK = 'layui-tree-iconClick',
    		ICON_ADD = 'layui-icon-addition',
    		ICON_SUB = 'layui-icon-subtraction',
    		ELEM_ENTRY = 'layui-tree-entry',
    		ELEM_MAIN = 'layui-tree-main',
    		ELEM_TEXT = 'layui-tree-txt',
    		ELEM_PACK = 'layui-tree-pack',
    		ELEM_SPREAD = 'layui-tree-spread',
    		ELEM_LINE_SHORT = 'layui-tree-setLineShort',
    		ELEM_SHOW = 'layui-tree-showLine',
    		ELEM_EXTEND = 'layui-tree-lineExtend'
    
    		//构造器
    		,
    		Class = function(options) {
    			var that = this;
    			that.index = ++treelazy.index;
    			that.config = $.extend({}, that.config, treelazy.config, options);
    			that.render();
    		};
    	treelazy.setTitle = function(elem, title, id) {
    		elem.replace('#', '');
    		$('#' + elem).find('option').val(id);
    		var select = $('#' + elem).next().find('input').val(title);
    	};
    	treelazy.treeselect = function(param) {
    		var elem = param.elem; //id
    		var width = param.width ? param.width + 'px' : '100%'; //下拉框文本宽度,默认100%,默认单位px
    		var height = param.height ? param.height + 'px' : '200px'; //下拉框高,默认100px
    		var placeholder = param.placeholder || '请选择';
    		var first = param.first || false; //是否默认选中第一行
    		var selectFontColor = param.selectFontColor || '#9F6277'; //默认选中文本颜色,默认#9F6277
    		var onlyIconControl = param.onlyIconControl || false; //只能点击图标展开收缩,默认false
    		var onlyLeafClick = param.onlyLeafClick || false; //只有点击叶子节点才执行点击方法,默认false
    		var treeid = 'tree_' + elem.substring(1);
    
    		//渲染html
    		var select = $(elem);
    		if (select.next().length > 0) {
    			//删除layui渲染的下拉框
    			select.next().remove();
    		}
    		var disabled = select.attr('disabled');
    		var disabledClass = disabled ? 'layui-disabled' : '';
    		var option = $('<option>');
    		var form_select = $('<div class="layui-unselect layui-form-select layui-treeselect" style="width:' + width + ';">');
    		var select_title = $('<div class="layui-select-title">');
    		var input = $('<input type="text" placeholder="' + placeholder + '" readonly class="layui-input layui-unselect ' +
    			disabledClass + '" ' + disabled + '>');
    		var edge = $('<i class="layui-edge"></i>');
    		var anim = $('<dl class="layui-anim layui-anim-upbit" style="display: none;">');
    		var dd = $('<dd>');
    		dd.css('height', height);
    		var treeDiv = $('<div id="' + treeid + '">');
    		//组装入页面
    		select_title.append(input);
    		select_title.append(edge);
    		dd.append(treeDiv);
    		anim.append(dd);
    		form_select.append(select_title);
    		form_select.append(anim);
    		select.after(form_select);
    		select.append(option);
    		//绑定事件
    		select_title.on('click', function() {
    			var isDisabled = $(this).parent().prev().attr('disabled');
    			if (!isDisabled) {
    				$(this).next().toggle();
    			}
    		});
    		//初始化渲染树形组件1
    		treelazy.render({
    			elem: '#' + treeid, //绑定元素
    			id: treeid,
    			onlyIconControl: onlyIconControl,
    			onlyLeafClick: onlyLeafClick,
    			selectFontColor: selectFontColor,
    			load: function(node, render) {
    				param.load(node, function(datas) {
    					if (first && node.level == 0) {
    						option.val(datas[0].id);
    						input.val(datas[0].text);
    					}
    					render(datas);
    				});
    			},
    			click: function(obj) {
    				//返回选中记录
    				option.val(obj.data.id);
    				input.val(obj.data.text);
    				//收回下拉框
    				// $(elem).next().removeClass('layui-form-selected');
    				$(elem).next().find('.layui-anim').hide();
    				//回调点击方法
    				param.click ? param.click(obj) : '';
    			}
    		});
    		$(document).on("click", function(e) {
    			//点击下拉框外的区域时,关闭下拉框
    			var target = $(e.target).parents('.layui-treeselect');
    			var targetId = target.prev().attr('id');
    			if (target.length == 0 || targetId != elem.substring(1)) {
    				// $(elem).next().removeClass('layui-form-selected');
    				$(elem).next().find('.layui-anim').hide();
    			}
    		});
    	}
    	treelazy.tabletreeselect = function(param) {
    		//传入参数
    		var _tID = param.tableID;
    		var _td = param.td;
    		var _colName = param.colName;
    		//获取参数
    		var $ = layui.$,
    			table = layui.table,
    			treelazy = layui.treelazy;
    		var _rowIndex = _td.parent().data('index'); //获取下标
    		var animID = _tID + '_' + _colName + '_anim';
    		var cell = _td.find('.layui-table-cell').eq(0);
    		//获取单元格内容
    		var value = table.cache[_tID][_rowIndex][_colName]; //id:实际值
    		var text = cell.text(); //显示值
    		//设置单元格获取焦点时的样式
    		cell.css({
    			'border': '1px solid #008CBA',
    			'padding': '0',
    			'box-shadow': '1px 1px 20px rgba(0, 10, 10, .15)'
    		});
    		//构建单元格中下拉框的ID
    		var selectId = "select_" + _tID + "_" + _rowIndex;
    		//如果没有构建下拉框,则开始构建
    		if ($("#" + selectId).length == 0) {
    			var closeFlag = true; //标记是否销毁表格下拉框
    			var selectDiv = $('<div class="layui-form-select layui-table-select">');
    			var input = $('<input type="text" id="' + selectId + '" value="' + text +
    				'" readonly="" class="layui-input">');
    			input.data('value', value);
    			var edge = $('<i class="layui-edge"></i>');
    			//下拉图标点击事件
    			edge.on('click', function(e) {
    				input.trigger('click');
    			});
    			//下拉框失去焦点事件:判断是否销毁下拉框
    			input.on('blur', function(e) {
    				if (closeFlag) {
    					closeTableselect();
    				} else {
    					input.focus();
    				}
    			});
    			//下拉框点击事件:切换下拉框显示隐藏
    			input.on('click', function(e) {
    				if ($("#" + animID).hasClass('layui-hide')) {
    					$("#" + animID).removeClass('layui-hide')
    				} else {
    					$("#" + animID).addClass('layui-hide')
    				}
    			});
    			//将下拉框载入单元格
    			selectDiv.append(input).append(edge);
    			cell.append(selectDiv);
    			input.focus();
    			//计算下拉框弹出框的位置及样式
    			if ($("#" + animID).length == 0) {
    				//自动创建弹出框
    				var tree_id = animID + '_tree';
    				var $anim = $('<div class="layui-hide layui-table-select-anim" id="' + animID + '">');
    				var $anim_select = $('<div class="layui-form-select">');
    				var $anim_upbit = $('<dl class="layui-anim layui-anim-upbit" style="display: block;">');
    				var $anim_dd = $('<dd style="height: 200px;">');
    				var $anim_tree = $('<div id="' + tree_id + '"></div>');
    				//载入body
    				$anim_dd.append($anim_tree);
    				$anim_upbit.append($anim_dd);
    				$anim_select.append($anim_upbit);
    				$anim.append($anim_select);
    				$('body').append($anim);
    				//初始化渲染下拉树
    				treelazy.render({
    					elem: '#' + tree_id, //绑定元素
    					id: tree_id,
    					showCheckbox: false,
    					onlyIconControl: true,
    					onlyLeafClick: false,
    					load: function(node, render) {
    						if (param.load) {
    							param.load(node, render);
    						} else {
    
    						}
    					},
    					click: function(obj) {
    						$("#" + animID).addClass('layui-hide');
    						var id = obj.data.id;
    						var text = obj.data.text;
    						var tableselect = $(".layui-table-select");
    						if (tableselect.length > 0) {
    							tableselect.find('input').val(text);
    							tableselect.find('input').data("value", id);
    						}
    						if (param.click) {
    							param.click(obj);
    						}
    					}
    				});
    			}
    			$("#" + animID).find(".layui-form-select").width(cell.width());
    			var animTop = cell.offset().top - 1;
    			var animLeft = cell.offset().left;
    			var winHeight = $(window).height();
    			var animHeight = $("#" + animID).find('dd').height();
    			if (animTop >= winHeight - animHeight) {
    				animTop = animTop - animHeight - cell.height() - 18;
    			}
    			$("#" + animID).css({
    				'position': 'absolute',
    				'left': cell.offset().left + 'px',
    				'top': animTop + 'px'
    			});
    			//下拉框弹出框鼠标止悬停时,标记不销毁下拉框
    			$("#" + animID).find('dd').on('mouseover', function(e) {
    				closeFlag = false;
    			}).on('mouseleave', function(e) {
    				closeFlag = true;
    			});
    			//下拉框鼠标止悬停时,标记不销毁下拉框
    			input.next().on('mouseover', function(e) {
    				closeFlag = false;
    			}).on('mouseleave', function(e) {
    				closeFlag = true;
    			});
    			//窗口尺寸变化时,销毁下拉框
    			$(window).resize(function() {
    				closeTableselect();
    			});
    			//表格滚动时,销毁下拉框
    			cell.parents('.layui-table-main').scroll(function() {
    				closeTableselect();
    			});
    			// 关闭表格中的下拉树形组件方法
    			function closeTableselect() {
    				cell.css({
    					'border': 'none',
    					'padding': '0 6px',
    					'box-shadow': 'none'
    				});
    				var value = selectDiv.find('input').data('value');
    				var text = selectDiv.find('input').val();
    				table.cache[_tID][_rowIndex][_colName] = value;
    				cell.text(text);
    				selectDiv.remove();
    				$("#" + animID).addClass('layui-hide');
    			}
    		}
    	}
    	//默认配置
    	Class.prototype.config = {
    		data: [] //数据
    
    			,
    		showCheckbox: false //是否显示复选框
    			,
    		showLine: true //是否开启连接线
    			,
    		accordion: false //是否开启手风琴模式
    			,
    		onlyIconControl: false //是否仅允许节点左侧图标控制展开收缩
    			,
    		isJump: false //是否允许点击节点时弹出新窗口跳转
    			,
    		edit: false //是否开启节点的操作图标
    			//,showSearch: false  //是否打开节点过滤
    			//,drag: false  //是否开启节点拖拽
    
    			,
    		text: {
    			defaultNodeName: '未命名' //节点默认名称
    				,
    			none: '无数据' //数据为空时的文本提示
    		}
    	};
    
    	//重载实例
    	Class.prototype.reload = function(options) {
    		var that = this;
    
    		layui.each(options, function(key, item) {
    			if (item.constructor === Array) delete that.config[key];
    		});
    
    		that.config = $.extend(true, {}, that.config, options);
    		that.render();
    	};
    
    	//主体渲染
    	Class.prototype.render = function() {
    
    		var that = this,
    			options = that.config,
    			datas = options.data;
    		var initNode = {
    			level: 0
    		}
    		options.load(initNode, function(datas) {
    			that.init(datas, initNode);
    		});
    		return {
    			config: options,
    			setChecked: that.setChecked
    		};
    	};
    	Class.prototype.init = function(datas, node) {
    		var that = this;
    		var ELEM_SET = 'layui-tree-set';
    		var ELEM_PACK = 'layui-tree-pack';
    		var config = this.config;
    		var elem = config.elem; //#tree
    		var checkedId = config.checkedId;
    		var showCheckbox = config.showCheckbox; //是否显示复选框
    		var onlyIconControl = config.onlyIconControl; //是否仅允许节点左侧图标控制展开收缩
    		var onlyLeafClick = config.onlyLeafClick || false; //只有点击页子节点才执行点击事件
    		var ICONS = config.icons || {
    			ICON_ADD: ICON_ADD,
    			ICON_SUB: ICON_SUB,
    			ICON_FILE: 'layui-icon-file'
    		};
    		var selectFontColor = config.selectFontColor || '#555'; //选中节点文本颜色
    		var root = $(elem);
    		var id = that.index;
    		var layFilter = 'LAY-tree-' + id;
    		this.config.layFilter = layFilter;
    		var tree = root.find('.layui-tree');
    		var parentNode = tree;
    		var setHide = '';
    		var checkedClass = '';
    		var checked = false;
    		//创建根节点
    		if (parentNode.length == 0) {
    			setHide = 'layui-tree-setHide'; //根节点不显示线
    			//创建根节点
    			parentNode = $('<div class="layui-tree layui-form layui-tree-line" lay-filter="' + layFilter + '">');
    			root.append(parentNode);
    		} else if (node.elem) {
    			parentNode = node.elem.parents(".layui-tree-entry").eq(0).next('.layui-tree-pack');
    			//如果没有 pack,则说明需要渲染
    			if (parentNode.length == 0) {
    				parentNode = $('<div class="layui-tree-pack" style="display: block;">');
    				if (node.elem) {
    					checked = node.elem.parents('span').next().next().hasClass('layui-form-checked');
    					checkedClass = checked ? 'checked' : '';
    				}
    			} else {
    				//不需要渲染
    				return;
    			}
    			node.elem.parents(".layui-tree-set").eq(0).append(parentNode);
    		}
    		//创建节点
    		$.each(datas, function(index, item) {
    			var lineShort = index == datas.length - 1 ? ' layui-tree-setLineShort' : ''; //末节点显示线
    			var leaf = item.leaf;
    			var dataid = item.id;
    			var div_set = $('<div data-id="' + dataid + '" class="layui-tree-set ' + setHide + lineShort + '">');
    			var div_entry = $("<div class='layui-tree-entry'></div>");
    			var div_main = $("<div class='layui-tree-main'></div>");
    			var treeIcon = leaf ? '' : 'layui-tree-icon';
    			var icon = leaf ? ICONS.ICON_FILE : ICONS.ICON_ADD;
    			var span = $("<span class='layui-tree-iconClick " + treeIcon + "'></span>");
    			var i = $("<i class='layui-icon " + icon + "'></i>");
    			if (!leaf) {
    				i.bind('click', function() {
    					addition_click();
    				});
    
    				function addition_click() {
    					var level = i.parents(".layui-tree-set").length;
    					var loadNode = {
    						level: level,
    						data: item
    					}
    					config.load(loadNode, function(datas) {
    						var spread = i.hasClass(ICONS.ICON_ADD);
    						if (spread) { //展开
    							i.addClass(ICONS.ICON_SUB).removeClass(ICONS.ICON_ADD);
    							i.parents('.layui-tree-entry').next(".layui-tree-pack").slideDown(200);
    						} else {
    							i.addClass(ICONS.ICON_ADD).removeClass(ICONS.ICON_SUB);
    							i.parents('.layui-tree-entry').next(".layui-tree-pack").slideUp(200);
    						}
    						loadNode.elem = i;
    						that.init(datas, loadNode);
    					});
    				}
    			}
    
    			var text = $("<span class='layui-tree-txt'>" + item.text + "</span>");
    			text.bind('click', function() {
    				if (!onlyIconControl) {
    					i.trigger('click');
    				}
    				if ((onlyLeafClick && leaf) || !onlyLeafClick) {
    					root.find('.text_click').removeClass('text_click').css('color', '#555');
    					text.addClass('text_click');
    					root.find('.text_click').css('color', selectFontColor);
    					config.click ? config.click({
    						data: item,
    						pid: 0
    					}) : '';
    				}
    			});
    
    			span.append(i);
    			div_main.append(span);
    			if (showCheckbox) {
    				if (checkedId) {
    					//如果动态设置了选中,则判断新节点是否在其中
    					if ($.inArray(parseInt(dataid), checkedId) == -1) {
    						checkedClass = '';
    					} else {
    						checkedClass = 'checked';
    					}
    				}
    				var checkbox = $("<input type='checkbox' name='layuiTreeCheck' lay-skin='primary' value='" + dataid + "' " +
    					checkedClass +
    					">");
    				div_main.append(checkbox);
    			}
    			div_main.append(text);
    			div_entry.append(div_main);
    			div_set.append(div_entry);
    			parentNode.append(div_set);
    		});
    		if (showCheckbox) {
    			that.renderCheckbox();
    		}
    
    	}
    	//渲染复选框
    	Class.prototype.renderCheckbox = function(options) {
    		var that = this;
    		var root = $(that.config.elem);
    		form.render('checkbox', that.config.layFilter);
    		var checkbox = root.find('input[name="layuiTreeCheck"]');
    		var checkedids = [];
    		checkbox.each(function() {
    			let checked = $(this)[0].checked;
    			if (checked) {
    				checkedids.push($(this)[0].value);
    			}
    		});
    		//给复选框绑定事件
    		root.find('.layui-form-checkbox').bind('click', function() {
    			//消除动态选择的数组
    			delete that.config.checkedId;
    			var elemCheckbox = $(this).prev('input[name="layuiTreeCheck"]');
    			var checked = elemCheckbox.prop('checked');
    			//同步子节点选中状态
    			var childs = elemCheckbox.parents('.layui-tree-entry').eq(0).next().find('input[name="layuiTreeCheck"]');
    			childs.each(function() {
    				this.checked = checked;
    			});
    			//同步父选中状态
    			var setParentsChecked = function(thisNodeElem) {
    				//若无父节点,则终止递归
    				if (!thisNodeElem.parents('.' + ELEM_SET)[0]) return;
    				var state, parentPack = thisNodeElem.parent('.' + ELEM_PACK),
    					parentNodeElem = parentPack.parent(),
    					parentCheckbox = parentPack.prev().find('input[name="layuiTreeCheck"]');
    				//如果子节点有任意一条选中,则父节点为选中状态
    				if (checked) {
    					parentCheckbox.prop('checked', checked);
    				} else { //如果当前节点取消选中,则根据计算“兄弟和子孙”节点选中状态,来同步父节点选中状态
    					parentPack.find('input[name="layuiTreeCheck"]').each(function() {
    						if (this.checked) {
    							state = true;
    						}
    					});
    
    					//如果兄弟子孙节点全部未选中,则父节点也应为非选中状态
    					state || parentCheckbox.prop('checked', false);
    				}
    				//向父节点递归
    				setParentsChecked(parentNodeElem);
    			}
    			setParentsChecked(elemCheckbox.parents('.' + ELEM_SET).eq(0));
    			that.renderCheckbox();
    		});
    	}
    
    	function renderCheckbox() {
    		form.render('checkbox', that.config.layFilter);
    		//给复选框绑定事件
    		root.find('.layui-form-checkbox').bind('click', function() {
    			var elemCheckbox = $(this).prev('input[name="layuiTreeCheck"]');
    			var checked = elemCheckbox.prop('checked');
    			//同步子节点选中状态
    			var childs = elemCheckbox.parents('.layui-tree-entry').eq(0).next().find('input[name="layuiTreeCheck"]');
    			childs.each(function() {
    				this.checked = checked;
    			});
    			//同步父选中状态
    			var setParentsChecked = function(thisNodeElem) {
    				//若无父节点,则终止递归
    				if (!thisNodeElem.parents('.' + ELEM_SET)[0]) return;
    				var state, parentPack = thisNodeElem.parent('.' + ELEM_PACK),
    					parentNodeElem = parentPack.parent(),
    					parentCheckbox = parentPack.prev().find('input[name="layuiTreeCheck"]');
    				//如果子节点有任意一条选中,则父节点为选中状态
    				if (checked) {
    					parentCheckbox.prop('checked', checked);
    				} else { //如果当前节点取消选中,则根据计算“兄弟和子孙”节点选中状态,来同步父节点选中状态
    					parentPack.find('input[name="layuiTreeCheck"]').each(function() {
    						if (this.checked) {
    							state = true;
    						}
    					});
    
    					//如果兄弟子孙节点全部未选中,则父节点也应为非选中状态
    					state || parentCheckbox.prop('checked', false);
    				}
    				//向父节点递归
    				setParentsChecked(parentNodeElem);
    			}
    			setParentsChecked(elemCheckbox.parents('.' + ELEM_SET).eq(0));
    			renderCheckbox();
    			//调用事件
    			that.config.checkboxClick ? that.config.checkboxClick() : '';
    		});
    	}
    	//渲染表单
    	Class.prototype.renderForm = function(type) {
    		form.render(type, 'LAY-tree-' + this.index);
    	};
    	//节点解析
    	Class.prototype.treelazy = function(elem, children) {
    		var that = this,
    			options = that.config,
    			data = children || options.data;
    
    		//遍历数据
    		layui.each(data, function(index, item) {
    			var hasChild = item.children && item.children.length > 0,
    				packDiv = $('<div class="layui-tree-pack" ' + (item.spread ? 'style="display: block;"' : '') + '"></div>'),
    				entryDiv = $(['<div data-id="' + item.id + '" class="layui-tree-set' + (item.spread ? " layui-tree-spread" :
    						"") + (item.checked ? " layui-tree-checkedFirst" : "") + '">', '<div ' + (options.drag && !item.fixed ?
    						'draggable="true"' : '') + ' class="layui-tree-entry">', '<div class="layui-tree-main">'
    					//箭头
    					,
    					function() {
    						if (options.showLine) {
    							if (hasChild) {
    								return '<span class="layui-tree-iconClick layui-tree-icon"><i class="layui-icon ' + (item.spread ?
    									"layui-icon-subtraction" : "layui-icon-addition") + '"></i></span>';
    							} else {
    								return '<span class="layui-tree-iconClick"><i class="layui-icon layui-icon-file"></i></span>';
    							};
    						} else {
    							return '<span class="layui-tree-iconClick"><i class="layui-tree-iconArrow ' + (hasChild ? "" : HIDE) +
    								'"></i></span>';
    						};
    					}()
    
    					//复选框
    					,
    					function() {
    						return options.showCheckbox ? '<input type="checkbox" name="layuiTreeCheck" lay-skin="primary" ' + (item.disabled ?
    							"disabled" : "") + '  value="' + item.id + '">' : '';
    					}()
    
    					//节点
    					,
    					function() {
    						if (options.isJump && item.href) {
    							return '<a href="' + item.href + '" target="_blank" class="' + ELEM_TEXT + '">' + (item.title || item.label ||
    								options.text.defaultNodeName) + '</a>';
    						} else {
    							return '<span class="' + ELEM_TEXT + (item.disabled ? ' ' + DISABLED : '') + '">' + (item.title || item.label ||
    								options.text.defaultNodeName) + '</span>';
    						}
    					}(), '</div>'
    
    					//节点操作图标
    					,
    					function() {
    						if (!options.edit) return '';
    
    						var editIcon = {
    								add: '<i class="layui-icon layui-icon-add-1"  data-type="add"></i>',
    								update: '<i class="layui-icon layui-icon-edit" data-type="update"></i>',
    								del: '<i class="layui-icon layui-icon-delete" data-type="del"></i>'
    							},
    							arr = ['<div class="layui-btn-group layui-tree-btnGroup">'];
    
    						if (options.edit === true) {
    							options.edit = ['update', 'del']
    						}
    
    						if (typeof options.edit === 'object') {
    							layui.each(options.edit, function(i, val) {
    								arr.push(editIcon[val] || '')
    							});
    							return arr.join('') + '</div>';
    						}
    					}(), '</div></div>'
    				].join(''));
    
    			//如果有子节点,则递归继续生成树
    			if (hasChild) {
    				entryDiv.append(packDiv);
    				that.treelazy(packDiv, item.children);
    			};
    
    			elem.append(entryDiv);
    
    			//若有前置节点,前置节点加连接线
    			if (entryDiv.prev('.' + ELEM_SET)[0]) {
    				entryDiv.prev().children('.layui-tree-pack').addClass('layui-tree-showLine');
    			};
    
    			//若无子节点,则父节点加延伸线
    			if (!hasChild) {
    				entryDiv.parent('.layui-tree-pack').addClass('layui-tree-lineExtend');
    			};
    
    			//展开节点操作
    			that.spread(entryDiv, item);
    
    			//选择框
    			if (options.showCheckbox) {
    				that.checkClick(entryDiv, item);
    			}
    
    			//操作节点
    			options.edit && that.operate(entryDiv, item);
    
    		});
    	};
    
    	//展开节点
    	Class.prototype.spread = function(elem, item) {
    		var that = this,
    			options = that.config,
    			entry = elem.children('.' + ELEM_ENTRY),
    			elemMain = entry.children('.' + ELEM_MAIN),
    			elemIcon = entry.find('.' + ICON_CLICK),
    			elemText = entry.find('.' + ELEM_TEXT),
    			touchOpen = options.onlyIconControl ? elemIcon : elemMain //判断展开通过节点还是箭头图标
    			,
    			state = '';
    
    		//展开收缩
    		touchOpen.on('click', function(e) {
    			var packCont = elem.children('.' + ELEM_PACK),
    				iconClick = touchOpen.children('.layui-icon')[0] ? touchOpen.children('.layui-icon') : touchOpen.find(
    					'.layui-tree-icon').children('.layui-icon');
    
    			//若没有子节点
    			if (!packCont[0]) {
    				state = 'normal';
    			} else {
    				if (elem.hasClass(ELEM_SPREAD)) {
    					elem.removeClass(ELEM_SPREAD);
    					packCont.slideUp(200);
    					iconClick.removeClass(ICON_SUB).addClass(ICON_ADD);
    				} else {
    					elem.addClass(ELEM_SPREAD);
    					packCont.slideDown(200);
    					iconClick.addClass(ICON_SUB).removeClass(ICON_ADD);
    
    					//是否手风琴
    					if (options.accordion) {
    						var sibls = elem.siblings('.' + ELEM_SET);
    						sibls.removeClass(ELEM_SPREAD);
    						sibls.children('.' + ELEM_PACK).slideUp(200);
    						sibls.find('.layui-tree-icon').children('.layui-icon').removeClass(ICON_SUB).addClass(ICON_ADD);
    					};
    				};
    			};
    		});
    
    		//点击回调
    		elemText.on('click', function() {
    			var othis = $(this);
    
    			//判断是否禁用状态
    			if (othis.hasClass(DISABLED)) return;
    
    			//判断展开收缩状态
    			if (elem.hasClass(ELEM_SPREAD)) {
    				state = options.onlyIconControl ? 'open' : 'close';
    			} else {
    				state = options.onlyIconControl ? 'close' : 'open';
    			}
    
    			//点击产生的回调
    			options.click && options.click({
    				elem: elem,
    				state: state,
    				data: item
    			});
    		});
    	};
    
    	//计算复选框选中状态
    	Class.prototype.setCheckbox = function(elem, item, elemCheckbox) {
    		var that = this,
    			options = that.config,
    			checked = elemCheckbox.prop('checked');
    
    		//同步子节点选中状态
    		if (typeof item.children === 'object' || elem.find('.' + ELEM_PACK)[0]) {
    			var childs = elem.find('.' + ELEM_PACK).find('input[name="layuiTreeCheck"]');
    			childs.each(function() {
    				if (this.disabled) return; //不可点击则跳过
    				this.checked = checked;
    			});
    		};
    
    		//同步父选中状态
    		var setParentsChecked = function(thisNodeElem) {
    			//若无父节点,则终止递归
    			if (!thisNodeElem.parents('.' + ELEM_SET)[0]) return;
    
    			var state, parentPack = thisNodeElem.parent('.' + ELEM_PACK),
    				parentNodeElem = parentPack.parent(),
    				parentCheckbox = parentPack.prev().find('input[name="layuiTreeCheck"]');
    
    
    			//如果子节点有任意一条选中,则父节点为选中状态
    			if (checked) {
    				parentCheckbox.prop('checked', checked);
    			} else { //如果当前节点取消选中,则根据计算“兄弟和子孙”节点选中状态,来同步父节点选中状态
    				parentPack.find('input[name="layuiTreeCheck"]').each(function() {
    					if (this.checked) {
    						state = true;
    					}
    				});
    
    				//如果兄弟子孙节点全部未选中,则父节点也应为非选中状态
    				state || parentCheckbox.prop('checked', false);
    			}
    
    			//向父节点递归
    			setParentsChecked(parentNodeElem);
    		};
    
    		setParentsChecked(elem);
    
    		that.renderForm('checkbox');
    	};
    
    	//复选框选择
    	Class.prototype.checkClick = function(elem, item) {
    		var that = this,
    			options = that.config,
    			entry = elem.children('.' + ELEM_ENTRY),
    			elemMain = entry.children('.' + ELEM_MAIN);
    
    		elemMain.on('click', 'input[name="layuiTreeCheck"]+', function(e) {
    			layui.stope(e); //阻止点击节点事件
    
    			var elemCheckbox = $(this).prev(),
    				checked = elemCheckbox.prop('checked');
    
    			if (elemCheckbox.prop('disabled')) return;
    
    			that.setCheckbox(elem, item, elemCheckbox);
    
    			//复选框点击产生的回调
    			options.oncheck && options.oncheck({
    				elem: elem,
    				checked: checked,
    				data: item
    			});
    		});
    	};
    
    	//节点操作
    	Class.prototype.operate = function(elem, item) {
    		var that = this,
    			options = that.config,
    			entry = elem.children('.' + ELEM_ENTRY),
    			elemMain = entry.children('.' + ELEM_MAIN);
    
    		entry.children('.layui-tree-btnGroup').on('click', '.layui-icon', function(e) {
    			layui.stope(e); //阻止节点操作
    
    			var type = $(this).data("type"),
    				packCont = elem.children('.' + ELEM_PACK),
    				returnObj = {
    					data: item,
    					type: type,
    					elem: elem
    				};
    			//增加
    			if (type == 'add') {
    				//若节点本身无子节点
    				if (!packCont[0]) {
    					//若开启连接线,更改图标样式
    					if (options.showLine) {
    						elemMain.find('.' + ICON_CLICK).addClass('layui-tree-icon');
    						elemMain.find('.' + ICON_CLICK).children('.layui-icon').addClass(ICON_ADD).removeClass('layui-icon-file');
    						//若未开启连接线,显示箭头
    					} else {
    						elemMain.find('.layui-tree-iconArrow').removeClass(HIDE);
    					};
    					//节点添加子节点容器
    					elem.append('<div class="layui-tree-pack"></div>');
    				};
    
    				//新增节点
    				var key = options.operate && options.operate(returnObj),
    					obj = {};
    				obj.title = options.text.defaultNodeName;
    				obj.id = key;
    				that.treelazy(elem.children('.' + ELEM_PACK), [obj]);
    
    				//放在新增后面,因为要对元素进行操作
    				if (options.showLine) {
    					//节点本身无子节点
    					if (!packCont[0]) {
    						//遍历兄弟节点,判断兄弟节点是否有子节点
    						var siblings = elem.siblings('.' + ELEM_SET),
    							num = 1,
    							parentPack = elem.parent('.' + ELEM_PACK);
    						layui.each(siblings, function(index, i) {
    							if (!$(i).children('.' + ELEM_PACK)[0]) {
    								num = 0;
    							};
    						});
    
    						//若兄弟节点都有子节点
    						if (num == 1) {
    							//兄弟节点添加连接线
    							siblings.children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    							siblings.children('.' + ELEM_PACK).children('.' + ELEM_SET).removeClass(ELEM_LINE_SHORT);
    							elem.children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    							//父级移除延伸线
    							parentPack.removeClass(ELEM_EXTEND);
    							//同层节点最后一个更改线的状态
    							parentPack.children('.' + ELEM_SET).last().children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(
    								ELEM_LINE_SHORT);
    						} else {
    							elem.children('.' + ELEM_PACK).children('.' + ELEM_SET).addClass(ELEM_LINE_SHORT);
    						};
    					} else {
    						//添加延伸线
    						if (!packCont.hasClass(ELEM_EXTEND)) {
    							packCont.addClass(ELEM_EXTEND);
    						};
    						//子节点添加延伸线
    						elem.find('.' + ELEM_PACK).each(function() {
    							$(this).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    						});
    						//如果前一个节点有延伸线
    						if (packCont.children('.' + ELEM_SET).last().prev().hasClass(ELEM_LINE_SHORT)) {
    							packCont.children('.' + ELEM_SET).last().prev().removeClass(ELEM_LINE_SHORT);
    						} else {
    							//若之前的没有,说明处于连接状态
    							packCont.children('.' + ELEM_SET).last().removeClass(ELEM_LINE_SHORT);
    						};
    						//若是最外层,要始终保持相连的状态
    						if (!elem.parent('.' + ELEM_PACK)[0] && elem.next()[0]) {
    							packCont.children('.' + ELEM_SET).last().removeClass(ELEM_LINE_SHORT);
    						};
    					};
    				};
    				if (!options.showCheckbox) return;
    				//若开启复选框,同步新增节点状态
    				if (elemMain.find('input[name="layuiTreeCheck"]')[0].checked) {
    					var packLast = elem.children('.' + ELEM_PACK).children('.' + ELEM_SET).last();
    					packLast.find('input[name="layuiTreeCheck"]')[0].checked = true;
    				};
    				that.renderForm('checkbox');
    
    				//修改
    			} else if (type == 'update') {
    				var text = elemMain.children('.' + ELEM_TEXT).html();
    				elemMain.children('.' + ELEM_TEXT).html('');
    				//添加输入框,覆盖在文字上方
    				elemMain.append('<input type="text" class="layui-tree-editInput">');
    				//获取焦点
    				elemMain.children('.layui-tree-editInput').val(text).focus();
    				//嵌入文字移除输入框
    				var getVal = function(input) {
    					var textNew = input.val().trim();
    					textNew = textNew ? textNew : options.text.defaultNodeName;
    					input.remove();
    					elemMain.children('.' + ELEM_TEXT).html(textNew);
    
    					//同步数据
    					returnObj.data.title = textNew;
    
    					//节点修改的回调
    					options.operate && options.operate(returnObj);
    				};
    				//失去焦点
    				elemMain.children('.layui-tree-editInput').blur(function() {
    					getVal($(this));
    				});
    				//回车
    				elemMain.children('.layui-tree-editInput').on('keydown', function(e) {
    					if (e.keyCode === 13) {
    						e.preventDefault();
    						getVal($(this));
    					};
    				});
    
    				//删除
    			} else {
    				options.operate && options.operate(returnObj); //节点删除的回调
    				returnObj.status = 'remove'; //标注节点删除
    
    				//若删除最后一个,显示空数据提示
    				if (!elem.prev('.' + ELEM_SET)[0] && !elem.next('.' + ELEM_SET)[0] && !elem.parent('.' + ELEM_PACK)[0]) {
    					elem.remove();
    					that.elem.append(that.elemNone);
    					return;
    				};
    				//若有兄弟节点
    				if (elem.siblings('.' + ELEM_SET).children('.' + ELEM_ENTRY)[0]) {
    					//若开启复选框
    					if (options.showCheckbox) {
    						//若开启复选框,进行下步操作
    						var elemDel = function(elem) {
    							//若无父结点,则不执行
    							if (!elem.parents('.' + ELEM_SET)[0]) return;
    							var siblingTree = elem.siblings('.' + ELEM_SET).children('.' + ELEM_ENTRY),
    								parentTree = elem.parent('.' + ELEM_PACK).prev(),
    								checkState = parentTree.find('input[name="layuiTreeCheck"]')[0],
    								state = 1,
    								num = 0;
    							//若父节点未勾选
    							if (checkState.checked == false) {
    								//遍历兄弟节点
    								siblingTree.each(function(i, item1) {
    									var input = $(item1).find('input[name="layuiTreeCheck"]')[0]
    									if (input.checked == false && !input.disabled) {
    										state = 0;
    									};
    									//判断是否全为不可勾选框
    									if (!input.disabled) {
    										num = 1;
    									};
    								});
    								//若有可勾选选择框并且已勾选
    								if (state == 1 && num == 1) {
    									//勾选父节点
    									checkState.checked = true;
    									that.renderForm('checkbox');
    									//向上遍历祖先节点
    									elemDel(parentTree.parent('.' + ELEM_SET));
    								};
    							};
    						};
    						elemDel(elem);
    					};
    					//若开启连接线
    					if (options.showLine) {
    						//遍历兄弟节点,判断兄弟节点是否有子节点
    						var siblings = elem.siblings('.' + ELEM_SET),
    							num = 1,
    							parentPack = elem.parent('.' + ELEM_PACK);
    						layui.each(siblings, function(index, i) {
    							if (!$(i).children('.' + ELEM_PACK)[0]) {
    								num = 0;
    							};
    						});
    						//若兄弟节点都有子节点
    						if (num == 1) {
    							//若节点本身无子节点
    							if (!packCont[0]) {
    								//父级去除延伸线,因为此时子节点里没有空节点
    								parentPack.removeClass(ELEM_EXTEND);
    								siblings.children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    								siblings.children('.' + ELEM_PACK).children('.' + ELEM_SET).removeClass(ELEM_LINE_SHORT);
    							};
    							//若为最后一个节点
    							if (!elem.next()[0]) {
    								elem.prev().children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    							} else {
    								parentPack.children('.' + ELEM_SET).last().children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(
    									ELEM_LINE_SHORT);
    							};
    							//若为最外层最后一个节点,去除前一个结点的连接线
    							if (!elem.next()[0] && !elem.parents('.' + ELEM_SET)[1] && !elem.parents('.' + ELEM_SET).eq(0).next()[0]) {
    								elem.prev('.' + ELEM_SET).addClass(ELEM_LINE_SHORT);
    							};
    						} else {
    							//若为最后一个节点且有延伸线
    							if (!elem.next()[0] && elem.hasClass(ELEM_LINE_SHORT)) {
    								elem.prev().addClass(ELEM_LINE_SHORT);
    							};
    						};
    					};
    
    				} else {
    					//若无兄弟节点
    					var prevDiv = elem.parent('.' + ELEM_PACK).prev();
    					//若开启了连接线
    					if (options.showLine) {
    						prevDiv.find('.' + ICON_CLICK).removeClass('layui-tree-icon');
    						prevDiv.find('.' + ICON_CLICK).children('.layui-icon').removeClass(ICON_SUB).addClass('layui-icon-file');
    						//父节点所在层添加延伸线
    						var pare = prevDiv.parents('.' + ELEM_PACK).eq(0);
    						pare.addClass(ELEM_EXTEND);
    
    						//兄弟节点最后子节点添加延伸线
    						pare.children('.' + ELEM_SET).each(function() {
    							$(this).children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    						});
    					} else {
    						//父节点隐藏箭头
    						prevDiv.find('.layui-tree-iconArrow').addClass(HIDE);
    					};
    					//移除展开属性
    					elem.parents('.' + ELEM_SET).eq(0).removeClass(ELEM_SPREAD);
    					//移除节点容器
    					elem.parent('.' + ELEM_PACK).remove();
    				};
    
    				elem.remove();
    
    
    			};
    		});
    	};
    
    	//拖拽
    	Class.prototype.drag = function() {
    		var that = this,
    			options = that.config;
    
    		that.elem.on('dragstart', '.' + ELEM_ENTRY, function() {
    			var parent = $(this).parent('.' + ELEM_SET),
    				pares = parent.parents('.' + ELEM_SET)[0] ? parent.parents('.' + ELEM_SET).eq(0) : '未找到父节点';
    
    			//开始拖拽触发的回调
    			options.dragstart && options.dragstart(parent, pares);
    		});
    
    		that.elem.on('dragend', '.' + ELEM_ENTRY, function(e) {
    			var e = e || event,
    				disY = e.clientY,
    				olds = $(this),
    				setParent = olds.parent('.' + ELEM_SET),
    				setHeight = setParent.height(),
    				setTop = setParent.offset().top,
    				elemSet = that.elem.find('.' + ELEM_SET),
    				elemHeight = that.elem.height(),
    				elemTop = that.elem.offset().top,
    				maxTop = elemHeight + elemTop - 13;
    			//原父节点
    			var isTree = setParent.parents('.' + ELEM_SET)[0],
    				nextOld = setParent.next()[0];
    			if (isTree) {
    				var parentPack = setParent.parent('.' + ELEM_PACK),
    					parentSet = setParent.parents('.' + ELEM_SET).eq(0),
    					warpPack = parentSet.parent('.' + ELEM_PACK),
    					parentTop = parentSet.offset().top,
    					siblingOld = setParent.siblings(),
    					num = parentSet.children('.' + ELEM_PACK).children('.' + ELEM_SET).length;
    			};
    			//原节点操作
    			var setDel = function(parentSet) {
    				//若为最后一个节点操作
    				if (!isTree && !nextOld) {
    					that.elem.children('.' + ELEM_SET).last().children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(
    						ELEM_LINE_SHORT);
    				};
    				//若为最外层节点,不做下列操作
    				if (!isTree) {
    					setParent.removeClass('layui-tree-setHide');
    					return;
    				};
    
    				//若为唯一子节点
    				if (num == 1) {
    					if (options.showLine) {
    						parentSet.find('.' + ICON_CLICK).removeClass('layui-tree-icon');
    						parentSet.find('.' + ICON_CLICK).children('.layui-icon').removeClass(ICON_SUB).addClass('layui-icon-file');
    						warpPack.addClass(ELEM_EXTEND);
    						warpPack.children('.' + ELEM_SET).children('.' + ELEM_PACK).each(function() {
    							$(this).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    						});
    					} else {
    						parentSet.find('.layui-tree-iconArrow').addClass(HIDE);
    					};
    					parentSet.children('.' + ELEM_PACK).remove();
    					parentSet.removeClass(ELEM_SPREAD);
    				} else {
    					//若开启连接线
    					if (options.showLine) {
    						//遍历兄弟节点,判断兄弟节点是否有子节点
    						var number = 1;
    						layui.each(siblingOld, function(index, i) {
    							if (!$(i).children('.' + ELEM_PACK)[0]) {
    								number = 0;
    							};
    						});
    
    						//若兄弟节点都有子节点
    						if (number == 1) {
    							//若节点本身无子节点
    							if (!setParent.children('.' + ELEM_PACK)[0]) {
    								//父级去除延伸线,因为此时子节点里没有空节点
    								parentPack.removeClass(ELEM_EXTEND);
    								siblingOld.children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    								siblingOld.children('.' + ELEM_PACK).children('.' + ELEM_SET).removeClass(ELEM_LINE_SHORT);
    							};
    							//若为最后一个节点
    							parentPack.children('.' + ELEM_SET).last().children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(
    								ELEM_LINE_SHORT);
    							//若为最外层最后一个节点,去除前一个结点的连接线
    							if (!nextOld && !parentSet.parents('.' + ELEM_SET)[0] && !parentSet.next()[0]) {
    								parentPack.children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    							};
    						} else {
    							//若为最后一个节点且有延伸线
    							if (!nextOld && setParent.hasClass(ELEM_LINE_SHORT)) {
    								parentPack.children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    							};
    						};
    					};
    					//若开启复选框
    					if (options.showCheckbox) {
    						//若开启复选框,进行下步操作
    						var elemRemove = function(elem) {
    							//若无父结点,则不执行
    							if (elem) {
    								if (!elem.parents('.' + ELEM_SET)[0]) return;
    							} else {
    								if (!parentSet[0]) return;
    							};
    							var siblingTree = elem ? elem.siblings().children('.' + ELEM_ENTRY) : siblingOld.children('.' +
    									ELEM_ENTRY),
    								parentTree = elem ? elem.parent('.' + ELEM_PACK).prev() : parentPack.prev(),
    								checkState = parentTree.find('input[name="layuiTreeCheck"]')[0],
    								state = 1,
    								ndig = 0;
    							//若父节点未勾选
    							if (checkState.checked == false) {
    								//遍历兄弟节点
    								siblingTree.each(function(i, item1) {
    									var input = $(item1).find('input[name="layuiTreeCheck"]')[0];
    									if (input.checked == false && !input.disabled) {
    										state = 0
    									};
    									//判断是否全为不可勾选框
    									if (!input.disabled) {
    										ndig = 1
    									};
    								});
    								//若有可勾选选择框并且已勾选
    								if (state == 1 && ndig == 1) {
    									//勾选父节点
    									checkState.checked = true;
    									that.renderForm('checkbox');
    									//向上遍历祖先节点
    									elemRemove(parentTree.parent('.' + ELEM_SET) || parentSet);
    								};
    							};
    						};
    						elemRemove();
    					};
    				};
    			};
    
    			//查找
    			elemSet.each(function() {
    				//筛选可插入位置
    				if ($(this).height() != 0) {
    					//若在本身位置
    					if ((disY > setTop && disY < setTop + setHeight)) {
    						options.dragend && options.dragend('drag error');
    						return;
    					};
    					//若仅有一个子元素
    					if (num == 1 && disY > parentTop && disY < setTop + setHeight) {
    						options.dragend && options.dragend('drag error');
    						return;
    					};
    					var thisTop = $(this).offset().top;
    
    					//若位于元素上
    					if ((disY > thisTop) && (disY < thisTop + 15)) {
    						//若元素无子节点
    						if (!$(this).children('.' + ELEM_PACK)[0]) {
    							if (options.showLine) {
    								$(this).find('.' + ICON_CLICK).eq(0).addClass('layui-tree-icon');
    								$(this).find('.' + ICON_CLICK).eq(0).children('.layui-icon').addClass(ICON_ADD).removeClass(
    									'layui-icon-file');
    							} else {
    								$(this).find(".layui-tree-iconArrow").removeClass(HIDE);
    							};
    							$(this).append('<div class="layui-tree-pack"></div>');
    						};
    						//插入元素
    						$(this).children('.' + ELEM_PACK).append(setParent);
    						setDel(parentSet);
    						//若开启连接线,更改线状态
    						if (options.showLine) {
    							var children = $(this).children('.' + ELEM_PACK).children('.' + ELEM_SET);
    							setParent.children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    							if (children.length == 1) {
    								//遍历兄弟节点,判断兄弟节点是否有子节点
    								var siblings = $(this).siblings('.' + ELEM_SET),
    									ss = 1,
    									parentPack = $(this).parent('.' + ELEM_PACK);
    								layui.each(siblings, function(index, i) {
    									if (!$(i).children('.' + ELEM_PACK)[0]) {
    										ss = 0;
    									};
    								});
    								//若兄弟节点都有子节点
    								if (ss == 1) {
    									//兄弟节点添加连接线
    									siblings.children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    									siblings.children('.' + ELEM_PACK).children('.' + ELEM_SET).removeClass(ELEM_LINE_SHORT);
    									$(this).children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    									//父级移除延伸线
    									parentPack.removeClass(ELEM_EXTEND);
    									//同层节点最后一个去除连接线
    									parentPack.children('.' + ELEM_SET).last().children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(
    										ELEM_LINE_SHORT).removeClass('layui-tree-setHide');
    								} else {
    									$(this).children('.' + ELEM_PACK).children('.' + ELEM_SET).addClass(ELEM_LINE_SHORT).removeClass(
    										'layui-tree-setHide');
    								};
    							} else {
    								//若原子节点含有延伸线
    								if (setParent.prev('.' + ELEM_SET).hasClass(ELEM_LINE_SHORT)) {
    									setParent.prev('.' + ELEM_SET).removeClass(ELEM_LINE_SHORT);
    									setParent.addClass(ELEM_LINE_SHORT);
    								} else {
    									//清除之前状态
    									setParent.removeClass('layui-tree-setLineShort layui-tree-setHide');
    									//若添加节点无子节点
    									if (!setParent.children('.' + ELEM_PACK)[0]) {
    										//兄弟节点子节点添加延伸线
    										setParent.siblings('.' + ELEM_SET).find('.' + ELEM_PACK).each(function() {
    											$(this).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    										});
    									} else {
    										setParent.prev('.' + ELEM_SET).children('.' + ELEM_PACK).children('.' + ELEM_SET).last().removeClass(
    											ELEM_LINE_SHORT);
    									};
    								};
    								//若无下兄弟节点
    								if (!$(this).next()[0]) {
    									setParent.addClass(ELEM_LINE_SHORT);
    								};
    							};
    						};
    						//若开启复选框,同步新增节点状态
    						if (options.showCheckbox) {
    							if ($(this).children('.' + ELEM_ENTRY).find('input[name="layuiTreeCheck"]')[0].checked) {
    								var packLast = setParent.children('.' + ELEM_ENTRY);
    								packLast.find('input[name="layuiTreeCheck"]+').click();
    							};
    						};
    						options.dragend && options.dragend('drag success', setParent, $(this));
    						return false;
    
    						//若位于元素上方
    					} else if (disY < thisTop) {
    						$(this).before(setParent);
    						setDel(parentSet);
    						//若开启连接线,更改线状态
    						if (options.showLine) {
    							var packCont = setParent.children('.' + ELEM_PACK),
    								setFirst = $(this).parents('.' + ELEM_SET).eq(0),
    								setPackLast = setFirst.children('.' + ELEM_PACK).children('.' + ELEM_SET).last();
    							if (packCont[0]) {
    								setParent.removeClass(ELEM_LINE_SHORT);
    								packCont.children('.' + ELEM_SET).last().removeClass(ELEM_LINE_SHORT);
    								//遍历兄弟节点,判断兄弟节点是否有子节点
    								var siblings = setParent.siblings('.' + ELEM_SET),
    									ss = 1;
    								layui.each(siblings, function(index, i) {
    									if (!$(i).children('.' + ELEM_PACK)[0]) {
    										ss = 0;
    									};
    								});
    								//若兄弟节点都有子节点
    								if (ss == 1) {
    									if (setFirst[0]) {
    										//兄弟节点添加连接线
    										siblings.children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    										siblings.children('.' + ELEM_PACK).children('.' + ELEM_SET).removeClass(ELEM_LINE_SHORT);
    										//同层节点最后一个添加延伸线
    										setPackLast.children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT).removeClass(
    											ELEM_SHOW);
    									};
    								} else {
    									setParent.children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    								};
    
    								//若是最外层,要始终保持相连的状态
    								if (!setFirst.parent('.' + ELEM_PACK)[0] && setFirst.next()[0]) {
    									setPackLast.removeClass(ELEM_LINE_SHORT);
    								};
    							} else {
    								if (!setFirst.hasClass(ELEM_EXTEND)) {
    									setFirst.addClass(ELEM_EXTEND);
    								};
    								//子节点添加延伸线
    								setFirst.find('.' + ELEM_PACK).each(function() {
    									$(this).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    								});
    								//若是最外层,要始终保持相连的状态
    								// if(!setFirst.parent('.'+ELEM_PACK)[0] && setFirst.next()[0]){
    								//   //setFirst.children('.'+ELEM_PACK).children('.'+ELEM_SET).last().removeClass(ELEM_LINE_SHORT);
    								// };
    							};
    							//若移到最外层
    							if (!setFirst[0]) {
    								//隐藏前置连接线
    								setParent.addClass('layui-tree-setHide');
    								setParent.children('.' + ELEM_PACK).children('.' + ELEM_SET).last().removeClass(ELEM_LINE_SHORT);
    							};
    						};
    						//开启复选框且有父节点,同步新增节点状态
    						if (setFirst[0] && options.showCheckbox) {
    							if (setFirst.children('.' + ELEM_ENTRY).find('input[name="layuiTreeCheck"]')[0].checked) {
    								var packLast = setParent.children('.' + ELEM_ENTRY);
    								packLast.find('input[name="layuiTreeCheck"]+').click();
    							};
    						};
    						options.dragend && options.dragend('拖拽成功,插入目标节点上方', setParent, $(this));
    						return false;
    
    						//若位于最下方
    					} else if (disY > maxTop) {
    						that.elem.children('.' + ELEM_SET).last().children('.' + ELEM_PACK).addClass(ELEM_SHOW);
    						that.elem.append(setParent);
    						setDel(parentSet);
    						//最外层保持连接
    						setParent.prev().children('.' + ELEM_PACK).children('.' + ELEM_SET).last().removeClass(ELEM_LINE_SHORT);
    						//隐藏前置连接线
    						setParent.addClass('layui-tree-setHide');
    						//最后一个子节点加延伸
    						setParent.children('.' + ELEM_PACK).children('.' + ELEM_SET).last().addClass(ELEM_LINE_SHORT);
    						options.dragend && options.dragend('拖拽成功,插入最外层节点', setParent, that.elem);
    						return false;
    					};
    				};
    			});
    		});
    	};
    
    	//部分事件
    	Class.prototype.events = function() {
    		var that = this,
    			options = that.config,
    			checkWarp = that.elem.find('.layui-tree-checkedFirst');
    
    		//初始选中
    		layui.each(checkWarp, function(i, item) {
    			$(item).children('.' + ELEM_ENTRY).find('input[name="layuiTreeCheck"]+').trigger('click');
    		});
    
    		//搜索
    		that.elem.find('.layui-tree-search').on('keyup', function() {
    			var input = $(this),
    				val = input.val(),
    				pack = input.nextAll(),
    				arr = [];
    
    			//遍历所有的值
    			pack.find('.' + ELEM_TEXT).each(function() {
    				var entry = $(this).parents('.' + ELEM_ENTRY);
    				//若值匹配,加一个类以作标识
    				if ($(this).html().indexOf(val) != -1) {
    					arr.push($(this).parent());
    
    					var select = function(div) {
    						div.addClass('layui-tree-searchShow');
    						//向上父节点渲染
    						if (div.parent('.' + ELEM_PACK)[0]) {
    							select(div.parent('.' + ELEM_PACK).parent('.' + ELEM_SET));
    						};
    					};
    					select(entry.parent('.' + ELEM_SET));
    				};
    			});
    
    			//根据标志剔除
    			pack.find('.' + ELEM_ENTRY).each(function() {
    				var parent = $(this).parent('.' + ELEM_SET);
    				if (!parent.hasClass('layui-tree-searchShow')) {
    					parent.addClass(HIDE);
    				};
    			});
    			if (pack.find('.layui-tree-searchShow').length == 0) {
    				that.elem.append(that.elemNone);
    			};
    
    			//节点过滤的回调
    			options.onsearch && options.onsearch({
    				elem: arr
    			});
    		});
    
    		//还原搜索初始状态
    		that.elem.find('.layui-tree-search').on('keydown', function() {
    			$(this).nextAll().find('.' + ELEM_ENTRY).each(function() {
    				var parent = $(this).parent('.' + ELEM_SET);
    				parent.removeClass('layui-tree-searchShow ' + HIDE);
    			});
    			if ($('.layui-tree-emptyText')[0]) $('.layui-tree-emptyText').remove();
    		});
    	};
    
    	//得到选中节点
    	Class.prototype.getChecked = function() {
    		var that = this,
    			options = that.config,
    			checkId = [],
    			checkData = [];
    		//遍历节点找到选中索引
    		$(options.elem).find('.layui-form-checked').each(function() {
    			//如果是叶子节点,则直接放入
    			var pSpan = $(this).prev().prev().find('.layui-icon');
    			if (pSpan.hasClass('layui-icon-file')) {
    				checkId.push(parseInt($(this).prev()[0].value));
    			} else {
    				//如果不是叶子节点,判断其子节点复选框个数与被选中子节点复选框个数是否相等
    				var child = $(this).parents('.' + ELEM_ENTRY).eq(0).next();
    				var ckCount = child.find('.layui-form-checkbox').length;
    				var ckdCount = child.find('.layui-form-checked').length;
    				if (ckCount == ckdCount) {
    					checkId.push(parseInt($(this).prev()[0].value));
    				}
    			}
    
    		});
    		return checkId;
    	};
    
    	//设置选中节点
    	Class.prototype.setChecked = function(checkedId, clearOther) {
    		var that = this,
    			options = that.config;
    		clearOther = clearOther || true; //默认清除其他
    		//清除其他
    		if (clearOther) {
    			$(options.elem).find('.layui-form-checked').prev('input[name="layuiTreeCheck"]').prop('checked', false);
    		}
    		//若返回数字
    		var checkedArr = [];
    		if (typeof checkedId === 'number') {
    			checkedArr.push(checkedId);
    		} else {
    			checkedArr = checkedId;
    		};
    		options.checkedId = checkedArr;
    		//初始选中
    		for (let i = 0; i < checkedArr.length; i++) {
    			let dataid = checkedArr[i];
    			var input = $(options.elem).find('input[value="' + dataid + '"]');
    			if (input.length > 0 && !input[0].checked) { //若未选中
    				input.prop('checked', true);
    				input.parents('.' + ELEM_PACK).prev().find('input[name="layuiTreeCheck"]').each(function() {
    					this.checked = true;
    				});
    			}
    		}
    		that.renderCheckbox();
    	};
    
    	//展开指定节点
    	var time;
    	Class.prototype.expand = function() {
    		var that = this,
    			options = that.config;
    		var ICONS = options.icons || {
    			ICON_ADD: ICON_ADD,
    			ICON_SUB: ICON_SUB,
    			ICON_FILE: 'layui-icon-file'
    		};
    		if (options.expandAll) {
    			$(options.elem).find('.' + ELEM_PACK).slideDown(200);
    			$(options.elem).find('.' + ICONS.ICON_ADD).addClass(ICONS.ICON_SUB).removeClass(ICONS.ICON_ADD);
    		} else {
    			var expand = function() {
    				var addNodes = $(options.elem).find('.' + ICONS.ICON_ADD); //待展开所有节点
    				if (addNodes.length == 0) {
    					//展开所有后关闭计时器
    					// alert('已全部展开!');
    					that.config.expandAll = true;
    					clearInterval(time);
    					var successEvent = that.config.expandSuccess;
    					successEvent ? successEvent() : '';
    					return;
    				}
    				for (let i = 0; i < addNodes.length; i++) {
    					if (addNodes.eq(i).hasClass(ICONS.ICON_ADD)) {
    						addNodes.eq(i).trigger('click');
    					}
    				}
    			}
    			time = setInterval(expand, 400);
    		}
    	};
    
    	//折叠指定节点
    	Class.prototype.fold = function() {
    		if (time != null) {
    			clearInterval(time);
    		}
    		var that = this,
    			options = that.config;
    		var ICONS = options.icons || {
    			ICON_ADD: ICON_ADD,
    			ICON_SUB: ICON_SUB,
    			ICON_FILE: 'layui-icon-file'
    		};
    		$(options.elem).find('.' + ELEM_PACK).hide();
    		$(options.elem).find('.' + ICONS.ICON_SUB).addClass(ICONS.ICON_ADD).removeClass(ICONS.ICON_SUB);
    	}
    
    	//记录所有实例
    	thisModule.that = {}; //记录所有实例对象
    	thisModule.config = {}; //记录所有实例配置项
    
    	//重载实例
    	treelazy.reload = function(id, options) {
    		var that = thisModule.that[id];
    		that.reload(options);
    
    		return thisModule.call(that);
    	};
    
    	//获得选中的节点数据
    	treelazy.getChecked = function(id) {
    		var that = thisModule.that[id];
    		return that.getChecked();
    	};
    
    	//设置选中节点
    	treelazy.setChecked = function(id, checkedId, clear) {
    		var that = thisModule.that[id];
    		return that.setChecked(checkedId, clear);
    	};
    
    	//展开指定节点
    	treelazy.expand = function(id) {
    		var that = thisModule.that[id];
    		return that.expand();
    	};
    
    	//折叠指定节点
    	treelazy.fold = function(id) {
    		var that = thisModule.that[id];
    		return that.fold();
    	};
    	treelazy.select = function(options) {
    		console.log(options);
    	};
    	//核心入口
    	treelazy.render = function(options) {
    		var inst = new Class(options);
    		return thisModule.call(inst);
    	};
    
    	//核心入口
    	treelazy.select = function(options) {
    		var inst = new Class(options);
    		return thisModule.call(inst);
    	}
    	exports(MOD_NAME, treelazy);
    })
    
    

    相关CSS样式

    /* layui表格中的下拉框样式 */
    .layui-table-select input {
    	border: none;
    }
    
    .layui-table-select input:hover {
    	border-color: #008CBA !important;
    }
    
    .layui-table-select-anim dl {
    	border: none;
    	border-top: 1px solid #E9E9E9;
    	box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
    }
    
    .layui-table-select-anim dl dd {
    	overflow: overlay;
    }
    
    .layui-table-select-anim dl dd:hover {
    	background: white !important;
    }
    
    /* 滚动条高宽 */
    .layui-table-select-anim dl dd::-webkit-scrollbar {
    	width: 10px;
    }
    
    /* 滚动条里面滑块 */
    .layui-table-select-anim dl dd::-webkit-scrollbar-thumb {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.2);
    }
    
    /* 滚动条里面轨道 */
    .layui-table-select-anim dl dd::-webkit-scrollbar-track {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.1);
    }
    /**** layui下拉树样式 ****/
    .layui-treeselect dl dd {
    	background: white;
    	color: #555;
    	overflow: auto;
    }
    
    .layui-treeselect dl dd.layui-this {
    	background: white;
    	color: #555;
    }
    
    .layui-treeselect dl dd:hover {
    	background: white;
    }
    
    .layui-treeselect .layui-input {
    	color: #666;
    }
    
    .layui-treeselect .layui-disabled {
    	background: #F6F6F6;
    	color: #999 !important;
    }
    
    /* 滚动条样式 */
    /* 滚动条高宽 */
    .layui-treeselect dl dd{
    	overflow: overlay;
    }
    .layui-treeselect dl dd::-webkit-scrollbar {
    	width: 10px;
    }
    
    /* 滚动条里面滑块 */
    .layui-treeselect dl dd::-webkit-scrollbar-thumb {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.2);
    }
    
    /* 滚动条里面轨道 */
    .layui-treeselect dl dd::-webkit-scrollbar-track {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.1);
    }
    

    一、layui表格中下拉树形组件:

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<link rel="stylesheet" href="../layui-master/dist/css/layui.css" />
    		<title>表格中部门选择下拉框</title>
    		<style>
    			html,
    			body {
    				overflow: hidden;
    			}
    		</style>
    	</head>
    	<body>
    		<div class="layui-fluid">
    			<div class="layui-row">
    				<table id="table" lay-filter="table" class="layui-hide"></table>
    			</div>
    		</div>
    	</body>
    	<script src="../layui-master/dist/layui.js" charset="utf-8"></script>
    	<script>
    		var tableID = "table";
    		layui.config({
    			base: '../../page/modules/'
    		}).extend({
    			treelazy: 'customcomponents/treelazy'
    		}).use(['layer', 'table', 'treelazy'], function() {
    			var $ = layui.$,
    				layer = layui.layer,
    				treelazy = layui.treelazy,
    				table = layui.table;
    
    
    			//初始化渲染表格
    			var datas = [];
    			for (let i = 0; i < 20; i++) {
    				datas.push({
    					id: i + 1
    				});
    			}
    			var tableIns = table.render({
    				elem: '#' + tableID,
    				height: 'full-1',
    				size: 'sm',
    				limit: 100,
    				page: true,
    				cols: [
    					[{
    							type: 'numbers'
    						},
    						{
    							field: 'id',
    							title: 'ID'
    						},
    						{
    							field: 'name',
    							title: '人员名称',
    							edit: 'text'
    						},
    						{
    							field: 'wsid',
    							title: '部门',
    							event: 'wsidEvent'
    						},
    						{
    							field: 'memo',
    							title: '备注'
    						}
    					]
    				],
    				data: datas
    			});
    			/********* 监听区 ********/
    			table.on('row(table)', function(obj) {
    				obj.tr.addClass("layui-table-click").siblings().removeClass("layui-table-click");
    			});
    			table.on('tool(' + tableID + ')', function(obj) {
    				var data = obj.data,
    					event = obj.event,
    					tr = obj.tr; //获得当前行 tr 的DOM对象;
    				switch (event) {
    					case 'wsidEvent':
    						treelazy.tabletreeselect({
    							tableID: tableID,
    							td: $(this),
    							colName: 'wsid',
    							load: function(node, render) {
    								var pid = 0;
    								if (node.level > 0) {
    									pid = node.data.id;
    								}
    								if (node.level == 0) {
    									render([{
    										id: 1,
    										text: '一级部门',
    										leaf: false
    									}, {
    										id: 2,
    										text: '一级部门',
    										leaf: false
    									}, {
    										id: 3,
    										text: '一级部门',
    										leaf: false
    									}, {
    										id: 4,
    										text: '一级部门',
    										leaf: false
    									}, {
    										id: 5,
    										text: '一级部门',
    										leaf: false
    									}]);
    								}
    								if (node.level == 1) {
    									render([{
    										id: 22,
    										text: '二级部门1',
    										leaf: true
    									}, {
    										id: 33,
    										text: '二级部门2',
    										leaf: true
    									}]);
    								}
    							},
    							click: function(obj) {
    								// console.log(obj.data);
    							}
    						});
    						break;
    				}
    			});
    		});
    	</script>
    </html>
    
    

    二、css样式:

    /**** layui下拉树样式 ****/
    .layui-treeselect dl dd {
    	background: white;
    	color: #555;
    	overflow: auto;
    }
    
    .layui-treeselect dl dd.layui-this {
    	background: white;
    	color: #555;
    }
    
    .layui-treeselect dl dd:hover {
    	background: white;
    }
    
    .layui-treeselect .layui-input {
    	color: #666;
    }
    
    .layui-treeselect .layui-disabled {
    	background: #F6F6F6;
    	color: #999 !important;
    }
    
    /* 滚动条样式 */
    /* 滚动条高宽 */
    .layui-treeselect dl dd{
    	overflow: overlay;
    }
    .layui-treeselect dl dd::-webkit-scrollbar {
    	width: 10px;
    }
    
    /* 滚动条里面滑块 */
    .layui-treeselect dl dd::-webkit-scrollbar-thumb {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.2);
    }
    
    /* 滚动条里面轨道 */
    .layui-treeselect dl dd::-webkit-scrollbar-track {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.1);
    }
    /* layui表格中的下拉框样式 */
    .layui-table-select input {
    	border: none;
    }
    
    .layui-table-select input:hover {
    	border-color: #008CBA !important;
    }
    
    .layui-table-select-anim dl {
    	border: none;
    	border-top: 1px solid #E9E9E9;
    	box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
    }
    
    .layui-table-select-anim dl dd {
    	overflow: overlay;
    }
    
    .layui-table-select-anim dl dd:hover {
    	background: white !important;
    }
    
    /* 滚动条高宽 */
    .layui-table-select-anim dl dd::-webkit-scrollbar {
    	width: 10px;
    }
    
    /* 滚动条里面滑块 */
    .layui-table-select-anim dl dd::-webkit-scrollbar-thumb {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.2);
    }
    
    /* 滚动条里面轨道 */
    .layui-table-select-anim dl dd::-webkit-scrollbar-track {
    	border-radius: 10px 2px 2px 10px;
    	-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    	background: rgba(0, 0, 0, 0.1);
    }
    
    展开全文
  • layui树形组件使用(tree.render())基于ssm实现功能 一、演示效果 二、后端返回数据格式 注意:使用树形组件回显的字段必须有id,title,checked。否则会无数据,并且父节点一定要为false,子节点打勾的为true。 ...

    layui树形组件使用(tree.render())基于ssm实现功能

    一、演示效果
    在这里插入图片描述
    二、后端返回数据格式
    在这里插入图片描述
    注意:使用树形组件回显的字段必须有id,title,checked。否则会无数据,并且父节点一定要为false,子节点打勾的为true。

    三、前端代码
    1.HTML部分

    <script type="text/html" id="barDemo">
    	<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="setModule"><i class="layui-icon">&#xe620;</i>设置权限</a>
    </script>
    <!--设置权限-->
    <div id="diaSetRight" style="display: none;" title="设置权限" style="width:300px;height:600px; margin: 10px auto;">
    	<table id="tabEdit">
    		<tr>
    			<td>
    				<div id="rightTree"></div>
    			</td>
    		</tr>
    		<tr>
    			<td style="text-align: center; padding: 10px;">
    				<a id="setRole" href="#" class="layui-btn"><i class="layui-icon">&#xe605;</i>保存设置</a>
    			</td>
    		</tr>
    	</table>
    </div>
    

    2.js部分

    //监听数据行工具栏按钮事件
    table.on('tool(test)', function(obj) { //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
    	var data = obj.data; //获得当前行数据
    	var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
    	var tr = obj.tr; //获得当前行 tr 的DOM对象
    
    	if(layEvent === 'setModule') { //设置模块
    		arr = [];
    		$.post(globalData.server + "roles/GetModulesByRoleIdLayUI", {
    			token: globalData.token,
    			rolesIds: data.id
    		}, function(r) {
    			tree.render({
    				elem: '#rightTree',
    				data: r,
    				id: 'roleTreeId',
    				showCheckbox: true
    			})
    			cur_roleId = data.id;
    		}, "json");
    		//打开设置权限窗口
    		setIndex = layer.open({
    			type: 1,
    			content: $('#diaSetRight'),
    			title: "正在设置角色[" + data.name + "]的权限模块",
    			area: ['300px', '400px']
    		});
    	}
    });
    
    //给角色设置权限
    $("#setRole").click(function() {
    	var nodes = tree.getChecked('roleTreeId');
    	//字符串拼接基本功,要求手熟
    	for(var i = 0; i < nodes.length; i++) {
    		getChildenId(nodes[i]); //调用递归的方法来获取所有选中节点的Id
    	}
    	//调用远程接口保存设置
    	$.post(globalData.server + "roles/SetSysRights", {
    		parentIds: arr.join(","),
    		rId: cur_roleId,
    		token: globalData.token
    	}, function(r) {
    		if(r) {
    			layer.msg('保存权限成功!', {
    				icon: 1,
    				time: 1000
    			}, function() {
    				layer.close(setIndex); //关闭修改弹出层
    				window.top.getMenu();
    			});
    		} else {
    			layer.msg('保存权限失败!', {
    				icon: 2,
    				time: 1000
    			})
    		}
    	}, "json");
    });
    
    //var active={del:3,reload:1,load:2};
    $('.demoTable .layui-btn').on('click', function() {
    	var type = $(this).data('type');
    	active[type] ? active[type].call(this) : '';
    });
    
    });
    var arr = [];
    //递归获取选中节点的Id
    function getChildenId(node) {
    	if(node != null) {
    		arr.push(node.id);
    		for(var i = 0; node.children != null && i < node.children.length; i++) {
    			getChildenId(node.children[i]);
    		}
    	}
    }
    

    四、后端代码
    1.mapper接口

    /**
     * 根据角色id查询全部树形<用户设置权限>
     * @param rolesIds List<ModulesTreeNode>
     * @return
     */
    List<ModulesTreeNode> selectAllTree(String rolesIds);
    
    /**
     * 移除角色权限
     * @param roleid
     * @param moduleid
     * @return
     */
    int deleteByUidAndModuleid(String roleid,String moduleid);
     
     /**
      * 分配角色权限
      * @param id
      * @param roleid
      * @param moduleid
      * @return
      */
    int insertByUidAndModuleid(String id,String roleid,String moduleid);
    

    2.service层

    /**
     * 根据角色id查询全部树形<用户设置权限>
     * @param rolesIds List<ModulesTreeNode>
     * @return
     */
    List<ModulesTreeNode> selectAllTree(String rolesIds);
    
    /**
     * 移除角色权限
     * @param roleid
     * @param moduleid
     * @return
     */
    int deleteByUidAndModuleid(String roleid,String moduleid);
     
     /**
      * 分配角色权限
      * @param id
      * @param roleid
      * @param moduleid
      * @return
      */
    int insertByUidAndModuleid(String id,String roleid,String moduleid);
    

    3.serviceImpl层

    @Override
    public List<ModulesTreeNode> selectAllTree(String rolesIds) {
    	// TODO Auto-generated method stub
    	return modulesMapper.selectAllTree(rolesIds);
    }
    
    @Override
    public int deleteByUidAndModuleid(String roleid, String moduleid) {
    	// TODO Auto-generated method stub
    	return rolesModulesMapper.deleteByUidAndModuleid(roleid, moduleid);
    }
    
    @Override
    public int insertByUidAndModuleid(String id, String roleid, String moduleid) {
    	// TODO Auto-generated method stub
    	return rolesModulesMapper.insertByUidAndModuleid(id, roleid, moduleid);
    }
    

    4.controller层

    /**
    * 查询所有的权限
    * 这里是查询所有的权限模块,然后给夫模块赋予false前台才可以显示树形组件
    * @return List
    */
    public List<ModulesTreeNode> getRolesTreeNodes(String rolesIds) {
    	List<ModulesTreeNode> modulesTreeNodes = modulesService.selectAllTree(rolesIds);
    	for (ModulesTreeNode modulesTreeNode : modulesTreeNodes) {
    		if (modulesTreeNode.getParentid()==0) {
    			modulesTreeNode.setChecked(false);
    		}
    	}
    	return modulesTreeNodes;
    }
    
    /**
    * 生成模块类型树
    * @return List
    */
    @RequestMapping("/GetModulesByRoleIdLayUI")
    public List<ModulesTreeNode> getRolesTreeNode(String rolesIds) {
    	List<ModulesTreeNode> rolesTreeList = this.getRolesTreeNodes(rolesIds);
    	List<ModulesTreeNode> rolesTreeNodes = new ArrayList<ModulesTreeNode>();
    	for (ModulesTreeNode rolesTreeNode : rolesTreeList) {
    		if (rolesTreeNode.getParentid()==0) {
    			rolesTreeNodes.add(findChildren(rolesTreeNode, rolesTreeList));
    		}
    	}
    	return rolesTreeNodes;
    }
    
    /**
    * 查找子类型
    * @return List
    */
    public ModulesTreeNode findChildren(ModulesTreeNode rolesTreeNode, List<ModulesTreeNode> rolesTreeList) {
    	for (ModulesTreeNode item : rolesTreeList) {
    		 if (rolesTreeNode.getId()==item.getParentid()) {
    			 if(rolesTreeNode.getChildren()==null) {
    				 rolesTreeNode.setChildren(new ArrayList<ModulesTreeNode>());
    			 } 
    			 rolesTreeNode.getChildren().add(findChildren(item,rolesTreeList));
    		 } 
    	}
    	return rolesTreeNode;
    }
    
    /**
    * 修改角色权限
    * 首先先要根据角色id把本身的权限删除,然后在进行添加权限
    * @return boolean 
    */
    @RequestMapping("/SetSysRights")
    @Transactional
    public boolean SetSysRights(String parentIds,String rId) {
    	//根据rId删除权限
    	rolesModulesService.deleteByUidAndModuleid(rId,"");
    	if (parentIds != null && !"".equals(parentIds) && parentIds != "") {//parentIds为空则视为取消全部权限
    		int flag = 0;
    		String[] m = parentIds.split(",");
    		for (int i = 0; i < m.length; i++) {
    			String id = UUIDUtil.getUUID();
    			flag = rolesModulesService.insertByUidAndModuleid(id, rId, m[i]);
    		}
    		if (flag<=0) {
    			return false;
    		}
    	}
    	return true;
    }
    

    5.mapper.xml
    注:我的数据库设计没有checked字段,所以我在sql里面添加了此字段并赋予boolean值

    <select id="selectAllTree" resultType="modulesTreeNode">
    	    SELECT
    		distinct m.id,
    		m. NAME title,
    		m.parentid,m.weight,
    		CASE
    	WHEN m.id IN (
    		SELECT
    			moduleid
    		FROM
    			rolemodules
    		WHERE
    			roleid = #{rolesIds}
    	) THEN
    		'true'
    	ELSE
    		'false'
    	END checked
    	FROM
    		modules m
    	LEFT JOIN rolemodules rm ON m.Id = rm.moduleid
    	ORDER BY
    		weight DESC
    </select>
    
    <delete id="deleteByUidAndModuleid">
        delete from rolemodules
        where RoleId = #{roleid} 
        <if test="moduleid != null and moduleid != ''">
        	and ModuleId = #{moduleid}
        </if>
    </delete>
    
    <insert id="insertByUidAndModuleid">
        insert into rolemodules(Id,RoleId,ModuleId) values(#{id},#{roleid},#{moduleid})
    </insert>
    

    到此就结束了!!!!!感谢大家的支持哦!!!!
    温馨提示:1.在设计表的时候要设计checked字段,不然就像我一样sql写的比较麻烦
    2.我使用了token的拦截,童鞋们可以根据自身情况使用。

    展开全文
  • layui提供了两种初始化节点选中状态的方式 ...layui树形组件此时无法重现用户的节点勾选情况了,怎么办? 这个时候就不能从前台的角度来解决问题了,因为layui树形组件的规则就是这样的。 二 通过数
  • layui 树形组件使用

    千次阅读 2020-01-15 15:35:05
    layui 部门列表 <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head th:include="shared/_layout::header('后台管理登录')"> </head> <body> <button type=...
  • 前台页面HTML <!... <... <...Layui</title> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta n
  • layui 树形组件复选框

    千次阅读 2020-05-19 15:47:09
    第一步:导入的layui必须是2.5后的版本,2.5之前的 弄不了 前端代码: 1、这是图片第一步的搜索框 <div class="layui-form-item"> <label class="layui-form-label" style="width: 120px;">通知...
  • layui树形组件源数据 ——递归添加

    千次阅读 2020-06-18 22:55:22
    上一篇博客记录了用ztree插件写的树形结构,这篇文章主要是记录使用layui写的树形结构所踩的坑,在写layui中写到了动态的向源数据中添加数据,用到了递归来添加。使用layui树形结构每一次加载后会折叠结构,体验...
  • 标题 如何利用递归来给layui树形组件绑定sqlServer递归表的数据? 上图是我的数据库内容 public ActionResult GetArea() { List<City> rootList = new List<City>(); foreach(var item in context....
  • layui 树形组件(tree)支持双击事件

    千次阅读 2020-06-18 16:06:21
    在使用layui v2.5.6 时,发现树形组件存在一些功能的缺失,比如没有双击事件,网上并没有具体的解决方案,看了一些使用layui的项目,都引入其他树形组件进行替换,个人感觉原生组件的样式与框架更适合,所以对其功能...
  • ajax动态加载layui树形组件

    千次阅读 2019-08-16 23:43:40
    树形组件 ,chrome=1"> <link rel="stylesheet" th:href="/layui.css"> <body> <div id="demo" class="demo-tree-more"></div> <div class="layui-form-item"> <div class="layui-input-block" style="margin...
  • /** * 跳转树形菜单页面 */ @RequestMapping("/toTree") public ModelAndView toTree(){ ModelAndView modelAndView=new ModelAndView(); modelAndView.setViewName("tree"); return modelAndView; } /** * 获取...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 138
精华内容 55
关键字:

layui树形组件