mirror of https://github.com/layui/layui
贤心
6 years ago
committed by
GitHub
10 changed files with 652 additions and 16 deletions
@ -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节点的方法 |
||||
|
@ -0,0 +1,151 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
|
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
||||
<title>树模块 - layui</title> |
||||
|
||||
<link rel="stylesheet" href="../src/css/layui.css"> |
||||
|
||||
<style> |
||||
body { |
||||
padding: 50px 100px; |
||||
} |
||||
</style> |
||||
</head> |
||||
|
||||
<body> |
||||
|
||||
<ul id="demo"></ul> |
||||
|
||||
<script src="../src/layui.js"></script> |
||||
<script> |
||||
layui.use('atree', function() { |
||||
var tree = layui.atree({ |
||||
elem: '#demo' //指定元素 |
||||
, |
||||
check: 'checkbox' //勾选风格 |
||||
, |
||||
skin: 'as' //设定皮肤 |
||||
//,target: '_blank' //是否新选项卡打开(比如节点返回href才有效) |
||||
, |
||||
// drag: true, |
||||
spreadAll:true, |
||||
props:{ |
||||
addBtnLabel:'新增', |
||||
deleteBtnLabel:'删除', |
||||
name: 'name', |
||||
id: 'id', |
||||
children:'children', |
||||
checkbox:'checkbox', |
||||
spread:'spread' |
||||
}, |
||||
change:function(val){ |
||||
console.group('change event') |
||||
console.log('Array') |
||||
console.log(val); |
||||
console.groupEnd() |
||||
}, |
||||
click: function(item) { //点击节点回调 |
||||
console.group('click event') |
||||
console.log('Object') |
||||
console.log(item); |
||||
console.groupEnd() |
||||
}, |
||||
addClick:function(item,elem,add){ |
||||
console.group('append event') |
||||
console.log('Object') |
||||
console.log(item); |
||||
console.log('dom') |
||||
console.log(elem); |
||||
console.log('dom add event') |
||||
var item ={ |
||||
name: '测试节点'+new Date().getTime(), |
||||
id:-1 |
||||
} |
||||
add(item) |
||||
console.groupEnd() |
||||
}, |
||||
deleteClick:function(item,elem,done){ |
||||
console.group('delete event') |
||||
console.log('Object') |
||||
console.log(item); |
||||
console.log('dom') |
||||
console.log(elem); |
||||
console.log('dom delete event') |
||||
done(); |
||||
console.groupEnd() |
||||
}, |
||||
nodes: [ //节点 |
||||
{ |
||||
name: '常用文件夹', |
||||
id: 1, |
||||
alias: 'changyong', |
||||
children: [{ |
||||
name: '所有未读', |
||||
id: 11 |
||||
//,href: 'http://www.layui.com/' |
||||
, |
||||
alias: 'weidu' |
||||
}, { |
||||
name: '置顶邮件', |
||||
id: 12 |
||||
}, { |
||||
name: '标签邮件', |
||||
id: 13 |
||||
}] |
||||
}, { |
||||
name: '我的邮箱', |
||||
id: 2, |
||||
spread: true, |
||||
children: [{ |
||||
name: 'QQ邮箱', |
||||
id: 21, |
||||
spread: true, |
||||
children: [{ |
||||
name: '收件箱', |
||||
id: 211, |
||||
spread: true, |
||||
children: [{ |
||||
name: '所有未读', |
||||
checkbox:true, |
||||
id: 2111 |
||||
}, { |
||||
name: '置顶邮件', |
||||
id: 2112 |
||||
}, { |
||||
name: '标签邮件', |
||||
id: 2113 |
||||
}] |
||||
}, { |
||||
name: '已发出的邮件', |
||||
id: 212 |
||||
}, { |
||||
name: '垃圾邮件', |
||||
id: 213 |
||||
}] |
||||
}, { |
||||
name: '阿里云邮', |
||||
id: 22, |
||||
children: [{ |
||||
name: '收件箱', |
||||
id: 221 |
||||
}, { |
||||
name: '已发出的邮件', |
||||
id: 222 |
||||
}, { |
||||
name: '垃圾邮件', |
||||
id: 223 |
||||
}] |
||||
}] |
||||
} |
||||
] |
||||
}); |
||||
|
||||
}); |
||||
</script> |
||||
|
||||
</body> |
||||
|
||||
</html> |
Binary file not shown.
Before Width: | Height: | Size: 271 KiB After Width: | Height: | Size: 272 KiB |
Binary file not shown.
Binary file not shown.
@ -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 ? '<i class="layui-icon layui-atree-spread">' + ( |
||||
item[that.spreadKey] || options.spreadAll ? icon.arrow[1] : icon.arrow[0] |
||||
) + '</i>' : ''; |
||||
}, |
||||
checkbox: function() { |
||||
return options.check ? ( |
||||
'<i class="layui-icon layui-atree-check' + (item[that.checkboxKey] ? ' is-checked' : '') + '">' + ( |
||||
item[that.checkboxKey] ? icon.checkbox[1] : icon.checkbox[0] |
||||
) + '</i>' |
||||
) : ''; |
||||
}, |
||||
ul: function() { |
||||
return '<ul class="' + (item[that.spreadKey] || options.spreadAll ? "layui-show" : "") + '"></ul>' |
||||
}, |
||||
node: function() { |
||||
return '<a href="' + (item.href || 'javascript:;') + '" ' + ( |
||||
options.target && item.href ? 'target=\"' + options.target + '\"' : '' |
||||
) + '>' + |
||||
('<cite>' + (item[that.nameKey] || '未命名') + '</cite></a>') |
||||
}, |
||||
menu: function() { |
||||
return '<div class="layui-atree-menu">' + |
||||
'<span class="layui-atree-add">' + that.addBtnLabelKey + '</span>' + |
||||
'<span class="layui-atree-delete">' + that.deleteBtnLabelKey + '</span>' + |
||||
'</div>' |
||||
} |
||||
} |
||||
|
||||
} |
||||
//获取树节点
|
||||
Atree.prototype.getNode = function(item) { |
||||
var that = this, |
||||
options = that.options |
||||
var dom = that.getDom(item); |
||||
var li = ['<li ' + |
||||
(item[that.spreadKey] || options.spreadAll ? 'data-spread="' + (item[that.spreadKey] || true) + '"' : '') + |
||||
(item[that.checkboxKey] ? 'data-check="' + item[that.checkboxKey] + '"' : '') + |
||||
('data-id=' + item[that.idKey]) + |
||||
'><div class="layui-atree-node">' |
||||
//展开箭头
|
||||
, |
||||
dom.spread() |
||||
|
||||
//复选框
|
||||
, |
||||
dom.checkbox() |
||||
|
||||
//节点
|
||||
, |
||||
dom.node() |
||||
//菜单
|
||||
, |
||||
dom.menu(), |
||||
'</div></li>' |
||||
].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 = $('<div class="layui-box ' + dragStr + '"></div>'); |
||||
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); |
||||
}); |
||||
}); |
Loading…
Reference in new issue