diff --git a/HARD b/HARD new file mode 100644 index 0000000..e69de29 diff --git a/examples/atree.html b/examples/atree.html new file mode 100644 index 0000000..b8b27f5 --- /dev/null +++ b/examples/atree.html @@ -0,0 +1,144 @@ + + + + + + + 树模块 - layui + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/tree.html b/examples/tree.html index ea5f801..49449c3 100644 --- a/examples/tree.html +++ b/examples/tree.html @@ -1,182 +1,147 @@ - - - - 树模块 - layui + + +树模块 - layui - + - + - - + - + - - + + } + return arr; + }(); + start = start || 1; + layui.each(node, function(index, item){ + if(start < 10 && index < 9){ + var child = [ + { + name: (1 + index + start).toString().replace(/(\d)/, '$1$1$1$1$1$1$1$1$1') + } + ]; + node[index].children = child; + createTree(child, index + start + 1); + } + }); + return node; + }; - + layui.tree({ + elem: '#demo1' //指定元素 + ,nodes: createTree() + }); + +}); + + +
+# layui.tree-v2 备忘
+* check参数 - checkbox、radio的支持
+* 拖拽的支持
+
- - \ No newline at end of file + diff --git a/src/lay/modules/atree.js b/src/lay/modules/atree.js new file mode 100644 index 0000000..cfbd22d --- /dev/null +++ b/src/lay/modules/atree.js @@ -0,0 +1,360 @@ +/** + + @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' + }; + + var enterSkin = 'layui-tree-enter', + Tree = function(options) { + this.options = options; + 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; + }; + //图标 + var icon = { + arrow: ['', ''] //箭头 + , + checkbox: ['', ''] //复选框 + , + leaf: '' //叶节点 + }; + + //初始化 + Tree.prototype.init = function(elem) { + var that = this; + elem.addClass('layui-box layui-tree'); //添加tree样式 + if(that.options.skin) { + elem.addClass('layui-tree-skin-' + that.options.skin); + } + that.tree(elem); + that.on(elem); + }; + + //树节点解析 + Tree.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 ul = $(''); + var li = that.getNode(item, hasChild); + //如果有子节点,则递归继续生成树 + if(hasChild) { + li.append(ul); + that.tree(ul, item[that.childrenKey]); + } + //伸展节点 + that.spread(li, item); + that.bindUlEvent(li, item); + elem.append(li); + + }); + }; + +//节点dom拼接 + Tree.prototype.getDom = function() { + var that = this, + options = that.options + return { + spread: function(item, hasChild) { + return hasChild ? '' + ( + item.spread ? icon.arrow[1] : icon.arrow[0] + ) + '' : ''; + }, + checkbox: function(item) { + return options.check ? ( + '' + ( + options.check === 'checkbox' ? icon.checkbox[0] : ( + options.check === 'radio' ? icon.radio[0] : '' + ) + ) + '' + ) : ''; + }, + node: function(item) { + return '' + + ('' + (item[that.nameKey] || '未命名') + '') + }, + menu: function(item) { + return '
' + + 'Add' + + 'Delete' + + '
' + } + } + + } + //获取树节点 + Tree.prototype.getNode = function(item, hasChild) { + var that = this, + options = that.options + var dom = that.getDom(); + var li = $(['
  • ' + //展开箭头 + , + dom.spread(item, hasChild) + + //复选框/单选框 + , + dom.checkbox(item) + + //节点 + , + dom.node(item) + //菜单 + , + dom.menu() + , + '
  • ' + ].join('')); + return li; + } + + //父绑定事件 + Tree.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); + } + + //选中回调函数 + Tree.prototype.change = function() { + var that = this, + options = that.options; + options.change(changeList); + }, + + //新增方法回调 + Tree.prototype.add = function(elem, item) { + var that = this, + options = that.options; + var addBtn = elem.children('.layui-tree-menu').children('.layui-tree-add') + var arrow = elem.children('.layui-tree-spread') + var ul = elem.children('ul'), + a = elem.children('a'); + var addEvent = function(e) { + layui.stope(e); + var _addEvent = { + add: function(itemAddObj) { + if(!ul[0]) { + ul = $(''); + elem.append(ul); + } + if(!arrow[0]) { + arrow = $('' + icon.arrow[1] + ''); + elem.prepend(arrow); + that.spread(elem, item); + } + if(!elem.data('spread')) { + that.open(elem, ul, arrow) + } + var li = that.getNode(itemAddObj, false); + that.bindUlEvent(li, itemAddObj); + ul.append(li); + } + } + options.addClick(item, elem, _addEvent.add) + } + addBtn.on('click', addEvent); + } + + //删除方法回调 + Tree.prototype.delete = function(elem, item) { + var that = this, + options = that.options; + var deleteBtn = elem.children('.layui-tree-menu').children('.layui-tree-delete') + var ul = elem.children('ul'), + a = elem.children('a'); + var deleteEvent = function(e) { + layui.stope(e); + var _deleteEvent = { + done: function() { + elem.html(''); + } + } + options.deleteClick(item, elem, _deleteEvent.done) + } + deleteBtn.on('click', deleteEvent); + } + + //点击节点回调 + Tree.prototype.click = function(elem, item) { + var that = this, + options = that.options; + elem.children('a').on('click', function(e) { + layui.stope(e); + options.click(item) + }); + }; + + //节点选择 + Tree.prototype.checkbox = function(elem, item) { + var that = this, + options = that.options; + var checkbox = elem.children('.layui-tree-check') + var ul = elem.children('ul'), + a = elem.children('a'); + var check = function() { + var index = layui.findObj(changeList, item); + if(elem.data('check')) { + elem.data('check', null) + checkbox.html(icon.checkbox[0]); + } else { + elem.data('check', true); + checkbox.html(icon.checkbox[1]); + } + if(index === -1) { + changeList.push(item); + } else { + changeList.splice(index, 1); + } + that.change(); + } + checkbox.on('click', check); + + }; + + //伸展节点 + Tree.prototype.spread = function(elem, item) { + var that = this, + options = that.options; + var arrow = elem.children('.layui-tree-spread') + var ul = elem.children('ul'), + a = elem.children('a'); + //如果没有子节点,则不执行 + if(!ul[0]) return; + arrow.on('click', function() { + that.open(elem, ul, arrow) + }); + } + + //打开节点 + Tree.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]); + } + }; + //通用事件 + Tree.prototype.on = function(elem) { + var that = this, + options = that.options; + var dragStr = 'layui-tree-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(); + } + }); + } + }; + + //拖拽节点 + Tree.prototype.move = {}; + Tree.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 tree = new Tree(options = options || {}); + var elem = $(options.elem); + if(!elem[0]) { + return hint.error('layui.tree 没有找到' + options.elem + '元素'); + } + tree.init(elem); + }); +}); \ No newline at end of file diff --git a/src/lay/modules/tree.js b/src/lay/modules/tree.js index 12204fd..1aef5a8 100644 --- a/src/lay/modules/tree.js +++ b/src/lay/modules/tree.js @@ -1,360 +1,215 @@ /** - @Name:layui.tree2.0 树组件 - @Author:smallwei + @Name:layui.tree 树组件 + @Author:贤心 @License:MIT */ - -layui.define('jquery', function(exports) { - "use strict"; - - var $ = layui.$, - hint = layui.hint(); - //勾选集合 - var changeList = []; - //变量别名 - var props ={ - name: 'name', - id: 'id', - children:'children' - }; - - var enterSkin = 'layui-tree-enter', - Tree = function(options) { - this.options = options; - 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; - }; - //图标 - var icon = { - arrow: ['', ''] //箭头 - , - checkbox: ['', ''] //复选框 - , - leaf: '' //叶节点 - }; - - //初始化 - Tree.prototype.init = function(elem) { - var that = this; - elem.addClass('layui-box layui-tree'); //添加tree样式 - if(that.options.skin) { - elem.addClass('layui-tree-skin-' + that.options.skin); - } - that.tree(elem); - that.on(elem); - }; - - //树节点解析 - Tree.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 ul = $(''); - var li = that.getNode(item, hasChild); - //如果有子节点,则递归继续生成树 - if(hasChild) { - li.append(ul); - that.tree(ul, item[that.childrenKey]); - } - //伸展节点 - that.spread(li, item); - that.bindUlEvent(li, item); - elem.append(li); - - }); - }; - -//节点dom拼接 - Tree.prototype.getDom = function() { - var that = this, - options = that.options - return { - spread: function(item, hasChild) { - return hasChild ? '' + ( - item.spread ? icon.arrow[1] : icon.arrow[0] - ) + '' : ''; - }, - checkbox: function(item) { - return options.check ? ( - '' + ( - options.check === 'checkbox' ? icon.checkbox[0] : ( - options.check === 'radio' ? icon.radio[0] : '' - ) - ) + '' - ) : ''; - }, - node: function(item) { - return '' + - ('' + (item[that.nameKey] || '未命名') + '') - }, - menu: function(item) { - return '
    ' + - 'Add' + - 'Delete' + - '
    ' - } - } - - } - //获取树节点 - Tree.prototype.getNode = function(item, hasChild) { - var that = this, - options = that.options - var dom = that.getDom(); - var li = $(['
  • ' - //展开箭头 - , - dom.spread(item, hasChild) - - //复选框/单选框 - , - dom.checkbox(item) - - //节点 - , - dom.node(item) - //菜单 - , - dom.menu() - , - '
  • ' - ].join('')); - return li; - } - - //父绑定事件 - Tree.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); - } - - //选中回调函数 - Tree.prototype.change = function() { - var that = this, - options = that.options; - options.change(changeList); - }, - - //新增方法回调 - Tree.prototype.add = function(elem, item) { - var that = this, - options = that.options; - var addBtn = elem.children('.layui-tree-menu').children('.layui-tree-add') - var arrow = elem.children('.layui-tree-spread') - var ul = elem.children('ul'), - a = elem.children('a'); - var addEvent = function(e) { - layui.stope(e); - var _addEvent = { - add: function(itemAddObj) { - if(!ul[0]) { - ul = $(''); - elem.append(ul); - } - if(!arrow[0]) { - arrow = $('' + icon.arrow[1] + ''); - elem.prepend(arrow); - that.spread(elem, item); - } - if(!elem.data('spread')) { - that.open(elem, ul, arrow) - } - var li = that.getNode(itemAddObj, false); - that.bindUlEvent(li, itemAddObj); - ul.append(li); - } - } - options.addClick(item, elem, _addEvent.add) - } - addBtn.on('click', addEvent); - } - - //删除方法回调 - Tree.prototype.delete = function(elem, item) { - var that = this, - options = that.options; - var deleteBtn = elem.children('.layui-tree-menu').children('.layui-tree-delete') - var ul = elem.children('ul'), - a = elem.children('a'); - var deleteEvent = function(e) { - layui.stope(e); - var _deleteEvent = { - done: function() { - elem.html(''); - } - } - options.deleteClick(item, elem, _deleteEvent.done) - } - deleteBtn.on('click', deleteEvent); - } - - //点击节点回调 - Tree.prototype.click = function(elem, item) { - var that = this, - options = that.options; - elem.children('a').on('click', function(e) { - layui.stope(e); - options.click(item) - }); - }; - - //节点选择 - Tree.prototype.checkbox = function(elem, item) { - var that = this, - options = that.options; - var checkbox = elem.children('.layui-tree-check') - var ul = elem.children('ul'), - a = elem.children('a'); - var check = function() { - var index = layui.findObj(changeList, item); - if(elem.data('check')) { - elem.data('check', null) - checkbox.html(icon.checkbox[0]); - } else { - elem.data('check', true); - checkbox.html(icon.checkbox[1]); - } - if(index === -1) { - changeList.push(item); - } else { - changeList.splice(index, 1); - } - that.change(); - } - checkbox.on('click', check); - - }; - - //伸展节点 - Tree.prototype.spread = function(elem, item) { - var that = this, - options = that.options; - var arrow = elem.children('.layui-tree-spread') - var ul = elem.children('ul'), - a = elem.children('a'); - //如果没有子节点,则不执行 - if(!ul[0]) return; - arrow.on('click', function() { - that.open(elem, ul, arrow) - }); - } - - //打开节点 - Tree.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]); - } - }; - //通用事件 - Tree.prototype.on = function(elem) { - var that = this, - options = that.options; - var dragStr = 'layui-tree-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(); - } - }); - } - }; - - //拖拽节点 - Tree.prototype.move = {}; - Tree.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('tree', function(options) { - var tree = new Tree(options = options || {}); - var elem = $(options.elem); - if(!elem[0]) { - return hint.error('layui.tree 没有找到' + options.elem + '元素'); - } - tree.init(elem); - }); -}); \ No newline at end of file + + +layui.define('jquery', function(exports){ + "use strict"; + + var $ = layui.$ + ,hint = layui.hint(); + + var enterSkin = 'layui-tree-enter', Tree = function(options){ + this.options = options; + }; + + //图标 + var icon = { + arrow: ['', ''] //箭头 + ,checkbox: ['', ''] //复选框 + ,radio: ['', ''] //单选框 + ,branch: ['', ''] //父节点 + ,leaf: '' //叶节点 + }; + + //初始化 + Tree.prototype.init = function(elem){ + var that = this; + elem.addClass('layui-box layui-tree'); //添加tree样式 + if(that.options.skin){ + elem.addClass('layui-tree-skin-'+ that.options.skin); + } + that.tree(elem); + that.on(elem); + }; + + //树节点解析 + Tree.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.children && item.children.length > 0; + var ul = $(''); + var li = $(['
  • ' + //展开箭头 + ,function(){ + return hasChild ? ''+ ( + item.spread ? icon.arrow[1] : icon.arrow[0] + ) +'' : ''; + }() + + //复选框/单选框 + ,function(){ + return options.check ? ( + ''+ ( + options.check === 'checkbox' ? icon.checkbox[0] : ( + options.check === 'radio' ? icon.radio[0] : '' + ) + ) +'' + ) : ''; + }() + + //节点 + ,function(){ + return '' + + (''+ ( + hasChild ? ( + item.spread ? icon.branch[1] : icon.branch[0] + ) : icon.leaf + ) +'') //节点图标 + + (''+ (item.name||'未命名') +''); + }() + + ,'
  • '].join('')); + + //如果有子节点,则递归继续生成树 + if(hasChild){ + li.append(ul); + that.tree(ul, item.children); + } + + elem.append(li); + + //触发点击节点回调 + typeof options.click === 'function' && that.click(li, item); + + //伸展节点 + that.spread(li, item); + + //拖拽节点 + options.drag && that.drag(li, item); + }); + }; + + //点击节点回调 + Tree.prototype.click = function(elem, item){ + var that = this, options = that.options; + elem.children('a').on('click', function(e){ + layui.stope(e); + options.click(item) + }); + }; + + //伸展节点 + Tree.prototype.spread = function(elem, item){ + var that = this, options = that.options; + var arrow = elem.children('.layui-tree-spread') + var ul = elem.children('ul'), a = elem.children('a'); + + //执行伸展 + var open = function(){ + if(elem.data('spread')){ + elem.data('spread', null) + ul.removeClass('layui-show'); + arrow.html(icon.arrow[0]); + a.find('.layui-icon').html(icon.branch[0]); + } else { + elem.data('spread', true); + ul.addClass('layui-show'); + arrow.html(icon.arrow[1]); + a.find('.layui-icon').html(icon.branch[1]); + } + }; + + //如果没有子节点,则不执行 + if(!ul[0]) return; + + arrow.on('click', open); + a.on('dblclick', open); + } + + //通用事件 + Tree.prototype.on = function(elem){ + var that = this, options = that.options; + var dragStr = 'layui-tree-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(); + } + }); + } + }; + + //拖拽节点 + Tree.prototype.move = {}; + Tree.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('tree', function(options){ + var tree = new Tree(options = options || {}); + var elem = $(options.elem); + if(!elem[0]){ + return hint.error('layui.tree 没有找到'+ options.elem +'元素'); + } + tree.init(elem); + }); +}); diff --git a/src/layui.js b/src/layui.js index f1ff6e0..aa1aa1d 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' //常用元素操作