diff --git a/HARD b/HARD
new file mode 100644
index 00000000..e69de29b
diff --git a/doc/atree.md b/doc/atree.md
new file mode 100644
index 00000000..00d2304f
--- /dev/null
+++ b/doc/atree.md
@@ -0,0 +1,24 @@
+# atree2.0.0属性含义
+* spreadAll 设置checkbox全部选中
+* check勾选风格,不写没有勾选框
+* props 设置key属性别名
+ - addBtnLabel:新增按钮标题
+ - deleteBtnLabel:删除按钮标题
+ - name:树显示的标题
+ - id:主键对应的字段名
+ - children:子类对应的字段名
+ - checkbox:选中对应的字段名
+ - spread:是否展开对应的字段名
+* change选中回调函数
+ - val:选中的对象数组
+* click点击标题回调函数
+ - item:当前点击的对象
+* addClick:新增回调函数
+ - item:当前父节点的对象
+ - elem:当前节点的dom对象
+ - done:添加到dom节点的方法
+* deleteClick:删除回调函数
+ - item:当前父节点的对象
+ - elem:当前节点的dom对象
+ - done:删除dom节点的方法
+
\ No newline at end of file
diff --git a/examples/atree.html b/examples/atree.html
new file mode 100644
index 00000000..85d8a542
--- /dev/null
+++ b/examples/atree.html
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+ 树模块 - layui
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/css/layui.css b/src/css/layui.css
index c62c75e7..bca21b9d 100644
--- a/src/css/layui.css
+++ b/src/css/layui.css
@@ -912,6 +912,27 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-tree-drag{display: none; position: absolute; left: -666px; top: -666px; background-color: #f2f2f2; padding: 5px 10px; border: 1px dotted #000; white-space: nowrap}
.layui-tree-drag i{padding-right: 5px;}
+/** atree **/
+.layui-atree{line-height: 26px;}
+.layui-atree li{position:relative;text-overflow: ellipsis; overflow:hidden; white-space: nowrap;}
+.layui-atree li a,
+.layui-atree li .layui-atree-spread{display: inline-block; vertical-align: top;font-size: 12px; height: 26px; *display: inline; *zoom:1; cursor: pointer;color: #c0c4cc}
+.layui-atree li a{font-size: 0;}
+.layui-atree li a i{font-size: 16px;}
+.layui-atree li a cite{padding: 0 6px; font-size: 14px; font-style: normal;color: #606266;}
+.layui-atree li i{padding-left: 6px; -moz-user-select: none;}
+.layui-atree li .layui-atree-check{font-size: 16px;color: #dcdfe6}
+.layui-atree li .layui-atree-check:hover{color: #409eff;}
+.layui-atree li .layui-atree-check.is-checked{color: #409eff;}
+.layui-atree li ul{ display:none;margin-left: 40px;}
+.layui-atree li .layui-atree-enter{line-height: 24px; border: 1px dotted #000;}
+.layui-atree-drag{display: none; position: absolute; left: -666px; top: -666px; background-color: #f2f2f2; padding: 5px 10px; border: 1px dotted #000; white-space: nowrap}
+.layui-atree-drag i{padding-right: 5px;}
+.layui-atree-node{position: relative;}
+.layui-atree-node:hover { background-color:#eee;}
+.layui-atree-menu{position: absolute;top:0;right: 0;z-index:1024;}
+.layui-atree-menu span{margin-left: 10px;}
+
/** 导航菜单 **/
.layui-nav{position: relative; padding: 0 20px; background-color: #393D49; color: #fff; border-radius: 2px; font-size: 0; box-sizing: border-box;}
.layui-nav *{font-size: 14px;}
diff --git a/src/font/iconfont.eot b/src/font/iconfont.eot
index 51c4f895..1524ef0c 100644
Binary files a/src/font/iconfont.eot and b/src/font/iconfont.eot differ
diff --git a/src/font/iconfont.svg b/src/font/iconfont.svg
index e05b1895..88235dff 100644
--- a/src/font/iconfont.svg
+++ b/src/font/iconfont.svg
@@ -9,9 +9,9 @@ Created by iconfont
-
+
-
+
-
+
-
+
@@ -75,7 +75,7 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
@@ -84,10 +84,10 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
-
+
@@ -111,7 +111,7 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
@@ -156,7 +156,7 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
@@ -171,7 +171,7 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
@@ -195,7 +195,7 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
@@ -204,13 +204,13 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
-
+
@@ -222,7 +222,7 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
@@ -231,7 +231,7 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
-
+
@@ -327,6 +327,9 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
+
+
+
@@ -339,6 +342,9 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
+
+
+
diff --git a/src/font/iconfont.ttf b/src/font/iconfont.ttf
index 43a31613..f6c86825 100644
Binary files a/src/font/iconfont.ttf and b/src/font/iconfont.ttf differ
diff --git a/src/font/iconfont.woff b/src/font/iconfont.woff
index 7fd98e35..409d2a22 100644
Binary files a/src/font/iconfont.woff and b/src/font/iconfont.woff differ
diff --git a/src/lay/modules/atree.js b/src/lay/modules/atree.js
new file mode 100644
index 00000000..98671179
--- /dev/null
+++ b/src/lay/modules/atree.js
@@ -0,0 +1,420 @@
+/**
+
+ @Name:layui.atree2.0 树组件
+ @Author:smallwei
+ @License:MIT
+
+ */
+
+layui.define('jquery', function(exports) {
+ "use strict";
+
+ var $ = layui.$,
+ hint = layui.hint();
+ //勾选集合
+ var changeList = [];
+ //变量别名
+ var props = {
+ name: 'name',
+ id: 'id',
+ children: 'children',
+ checkbox: 'checkbox',
+ spread: 'spread',
+ deleteBtnLabelKey: 'delete',
+ addBtnLabelKey: 'add',
+ };
+
+ var enterSkin = 'layui-atree-enter',
+ Atree = function(options) {
+ this.options = options;
+ this.nodes = options.nodes || [];
+ this.props = this.options.props || props;
+ this.nameKey = this.props.name || props.name;
+ this.idKey = this.props.id || props.id;
+ this.childrenKey = this.props.children || props.children;
+ this.checkboxKey = this.props.checkbox || props.checkbox;
+ this.spreadKey = this.props.spread || props.spread;
+ this.addBtnLabelKey = this.props.addBtnLabel || props.addBtnLabel;
+ this.deleteBtnLabelKey = this.props.deleteBtnLabel || props.deleteBtnLabel;
+ };
+ //图标
+ var icon = {
+ arrow: ['', ''] //箭头
+ ,
+ checkbox: ['', ''] //复选框
+ ,
+ leaf: '' //叶节点
+ };
+
+ //初始化
+ Atree.prototype.init = function(elem) {
+ var that = this;
+ elem.addClass('layui-box layui-atree'); //添加tree样式
+ if(that.options.skin) {
+ elem.addClass('layui-atree-skin-' + that.options.skin);
+ }
+ that.tree(elem);
+ that.on(elem);
+ };
+
+ //树节点解析
+ Atree.prototype.tree = function(elem, children) {
+ var that = this,
+ options = that.options
+ var nodes = children || options.nodes;
+ layui.each(nodes, function(index, item) {
+ var hasChild = item[that.childrenKey] && item[that.childrenKey].length > 0;
+ var dom = that.getDom(item);
+ var ul = $(dom.ul(item));
+ var li = $(that.getNode(item));
+
+ //如果被选中加入checkbox集合里
+ if(item[that.checkboxKey]) {
+ changeList.push(item);
+ }
+
+ //如果有子节点,则递归继续生成树
+ if(hasChild) {
+ li.append(ul);
+ that.tree(ul, item[that.childrenKey]);
+ }
+ //伸展节点
+ that.spread(li, item);
+ that.bindUlEvent(li, item);
+ elem.append(li);
+
+ });
+ };
+
+ //节点dom拼接
+ Atree.prototype.getDom = function(item) {
+ var that = this,
+ options = that.options,
+ item = item,
+ hasChild = item[that.childrenKey] && item[that.childrenKey].length > 0;
+ return {
+ spread: function() {
+ return hasChild ? '' + (
+ item[that.spreadKey] || options.spreadAll ? icon.arrow[1] : icon.arrow[0]
+ ) + '' : '';
+ },
+ checkbox: function() {
+ return options.check ? (
+ '' + (
+ item[that.checkboxKey] ? icon.checkbox[1] : icon.checkbox[0]
+ ) + ''
+ ) : '';
+ },
+ ul: function() {
+ return ''
+ },
+ node: function() {
+ return '' +
+ ('' + (item[that.nameKey] || '未命名') + '')
+ },
+ menu: function() {
+ return ''
+ }
+ }
+
+ }
+ //获取树节点
+ Atree.prototype.getNode = function(item) {
+ var that = this,
+ options = that.options
+ var dom = that.getDom(item);
+ var li = [''
+ //展开箭头
+ ,
+ dom.spread()
+
+ //复选框
+ ,
+ dom.checkbox()
+
+ //节点
+ ,
+ dom.node()
+ //菜单
+ ,
+ dom.menu(),
+ '
'
+ ].join('');
+ return li;
+ }
+
+ //父绑定事件
+ Atree.prototype.bindUlEvent = function(li, item) {
+ var that = this,
+ options = that.options
+ //触发点击节点回调
+ typeof options.click === 'function' && that.click(li, item);
+
+ //节点选择
+ typeof options.change === 'function' && options.check === 'checkbox' && that.checkbox(li, item);
+
+ //新增方法
+ typeof options.addClick === 'function' && that.add(li, item);
+
+ //删除方法
+ typeof options.deleteClick === 'function' && that.delete(li, item);
+
+ //拖拽节点
+ options.drag && that.drag(li, item);
+ }
+
+ //选中回调函数
+ Atree.prototype.change = function() {
+ var that = this,
+ options = that.options;
+ options.change(changeList);
+ },
+
+ //新增方法回调
+ Atree.prototype.add = function(elem, item) {
+ var that = this,
+ options = that.options;
+ var node = elem.children('.layui-atree-node');
+ var addBtn = node.children('.layui-atree-menu').children('.layui-atree-add')
+ var arrow = node.children('.layui-atree-spread')
+ var ul = elem.children('ul'),
+ a = node.children('a');
+ var addEvent = function(e) {
+ layui.stope(e);
+ var _addEvent = {
+ add: function(itemAddObj) {
+ if(!item[that.childrenKey]) {
+ item[that.childrenKey] = [];
+ }
+ item[that.childrenKey].push(itemAddObj);
+ var dom = that.getDom(item);
+ if(!ul[0]) {
+ ul = $(dom.ul())
+ elem.append(ul);
+ }
+ if(!arrow[0]) {
+ arrow = $(dom.spread());
+ node.prepend(arrow);
+ that.spread(elem, item);
+ }
+ if(!elem.data('spread')) {
+ that.open(elem, ul, arrow)
+ }
+ var li = $(that.getNode(itemAddObj));
+ that.bindUlEvent(li, itemAddObj);
+ ul.append(li);
+ }
+ }
+ options.addClick(item, elem, _addEvent.add)
+ }
+ addBtn.on('click', addEvent);
+ }
+
+ //删除方法回调
+ Atree.prototype.delete = function(elem, item) {
+ var that = this,
+ options = that.options;
+ var node = elem.children('.layui-atree-node');
+ var deleteBtn = node.children('.layui-atree-menu').children('.layui-atree-delete')
+ var ul = elem.children('ul'),
+ a = elem.children('a');
+ var deleteEvent = function(e) {
+ layui.stope(e);
+ var _deleteEvent = {
+ done: function() {
+ var parent = elem.parent();
+ var arrow = parent.parent().children('.layui-atree-spread')
+ if(parent.children('li').length === 1) {
+ arrow.remove();
+ }
+ elem.remove();
+ }
+ }
+ options.deleteClick(item, elem, _deleteEvent.done)
+ }
+ deleteBtn.on('click', deleteEvent);
+ }
+
+ //点击节点回调
+ Atree.prototype.click = function(elem, item) {
+ var that = this,
+ options = that.options;
+ var node = elem.children('.layui-atree-node');
+ node.children('a').on('click', function(e) {
+ layui.stope(e);
+ options.click(item)
+ });
+ };
+
+ //节点选择
+ Atree.prototype.checkbox = function(elem, item) {
+ var that = this,
+ options = that.options;
+ var node = elem.children('.layui-atree-node');
+ var checkbox = node.children('.layui-atree-check')
+ var ul = elem.children('ul'),
+ a = node.children('a');
+ var whileAllCheck = function(dom, item, type) {
+ var list = dom.children('.layui-show').find('li');
+ var children = item ? item.children || [] : [];
+ for(var i = 0; i < list.length; i++) {
+ var li = $(list[i]);
+ setCheck(li, children[i], type);
+ whileAllCheck(li, children[i], type);
+ }
+ }
+ var setCheck = function(elem, item, type) {
+ var checkbox = elem.children('.layui-atree-node').find('.layui-atree-check');
+ if(type) {
+ elem.data('check', true)
+ checkbox.html(icon.checkbox[1])
+ checkbox.addClass(' is-checked');
+ } else {
+ elem.data('check', null);
+ checkbox.removeClass(' is-checked');
+ checkbox.html(icon.checkbox[0])
+ }
+ if(item) {
+ var index = layui.findObj(changeList, item[that.idKey], that.idKey);
+ if(index === -1 && type === true) {
+ changeList.push(item);
+ } else if(type === false) {
+ changeList.splice(index, 1);
+ }
+ }
+ }
+ var check = function() {
+ var checkFlag;
+ if(elem.data('check')) {
+ checkFlag = false;
+ } else {
+ checkFlag = true;
+ }
+ setCheck(elem, item, checkFlag)
+ whileAllCheck(elem, item, checkFlag);
+ that.change();
+ }
+ checkbox.on('click', check);
+
+ };
+
+ //伸展节点
+ Atree.prototype.spread = function(elem, item) {
+ var that = this,
+ options = that.options;
+ var node = elem.children('.layui-atree-node');
+ var arrow = node.children('.layui-atree-spread')
+ var ul = elem.children('ul'),
+ a = node.children('a');
+ //如果没有子节点,则不执行
+ if(!ul[0]) return;
+ arrow.on('click', function() {
+ that.open(elem, ul, arrow)
+ });
+ }
+
+ //打开节点
+ Atree.prototype.open = function(elem, ul, arrow) {
+ if(elem.data('spread')) {
+ elem.data('spread', null)
+ ul.removeClass('layui-show');
+ arrow.html(icon.arrow[0]);
+ } else {
+ elem.data('spread', true);
+ ul.addClass('layui-show');
+ arrow.html(icon.arrow[1]);
+ }
+ };
+ //通用事件
+ Atree.prototype.on = function(elem) {
+ var that = this,
+ options = that.options;
+ var dragStr = 'layui-atree-drag';
+
+ //屏蔽选中文字
+ elem.find('i').on('selectstart', function(e) {
+ return false
+ });
+
+ //拖拽
+ if(options.drag) {
+ $(document).on('mousemove', function(e) {
+ var move = that.move;
+ if(move.from) {
+ var to = move.to,
+ treeMove = $('');
+ e.preventDefault();
+ $('.' + dragStr)[0] || $('body').append(treeMove);
+ var dragElem = $('.' + dragStr)[0] ? $('.' + dragStr) : treeMove;
+ (dragElem).addClass('layui-show').html(move.from.elem.children('a').html());
+ dragElem.css({
+ left: e.pageX + 10,
+ top: e.pageY + 10
+ })
+ }
+ }).on('mouseup', function() {
+ var move = that.move;
+ if(move.from) {
+ move.from.elem.children('a').removeClass(enterSkin);
+ move.to && move.to.elem.children('a').removeClass(enterSkin);
+ that.move = {};
+ $('.' + dragStr).remove();
+ }
+ });
+ }
+ };
+
+ //拖拽节点
+ Atree.prototype.move = {};
+ Atree.prototype.drag = function(elem, item) {
+ var that = this,
+ options = that.options;
+ var a = elem.children('a'),
+ mouseenter = function() {
+ var othis = $(this),
+ move = that.move;
+ if(move.from) {
+ move.to = {
+ item: item,
+ elem: elem
+ };
+ othis.addClass(enterSkin);
+ }
+ };
+ a.on('mousedown', function() {
+ var move = that.move
+ move.from = {
+ item: item,
+ elem: elem
+ };
+ });
+ a.on('mouseenter', mouseenter).on('mousemove', mouseenter)
+ .on('mouseleave', function() {
+ var othis = $(this),
+ move = that.move;
+ if(move.from) {
+ delete move.to;
+ othis.removeClass(enterSkin);
+ }
+ });
+ };
+
+ //暴露接口
+ exports('atree', function(options) {
+ var atree = new Atree(options = options || {});
+ var elem = $(options.elem);
+ if(!elem[0]) {
+ return hint.error('layui.atree 没有找到' + options.elem + '元素');
+ }
+ atree.init(elem);
+ });
+});
\ No newline at end of file
diff --git a/src/layui.js b/src/layui.js
index 351a6975..90e0d180 100644
--- a/src/layui.js
+++ b/src/layui.js
@@ -56,6 +56,7 @@
,layedit: 'modules/layedit' //富文本编辑器
,form: 'modules/form' //表单集
,upload: 'modules/upload' //上传
+ ,atree: 'modules/atree' //新树结构
,tree: 'modules/tree' //树结构
,table: 'modules/table' //表格
,element: 'modules/element' //常用元素操作
@@ -430,7 +431,20 @@
error: error
}
};
+ //判断对象是否相等
+ Layui.prototype.isEqualObj = function(obj1,obj2){
+ return JSON.stringify(obj1)===JSON.stringify(obj2)
+ }
+ //寻找对象是否存在数组中
+ Layui.prototype.findObj = function(list,value,key) {
+ var that = this,
+ result = -1;
+ that.each(list, function(index, item) {
+ if(item[key] == value)result = index;
+ })
+ return result;
+ }
//遍历
Layui.prototype.each = function(obj, fn){
var key