fix(atree): 2.0.0-beta

This commit is contained in:
smallwei 2018-07-19 20:53:05 +08:00
parent a34c39a1dd
commit ea24b7635d
3 changed files with 389 additions and 362 deletions

View File

@ -33,6 +33,8 @@
// drag: true, // drag: true,
spreadAll:true, spreadAll:true,
props:{ props:{
addBtnLabel:'新增',
deleteBtnLabel:'删除',
name: 'name', name: 'name',
id: 'id', id: 'id',
children:'children', children:'children',

View File

@ -7,389 +7,414 @@
*/ */
layui.define('jquery', function(exports) { layui.define('jquery', function(exports) {
"use strict"; "use strict";
var $ = layui.$, var $ = layui.$,
hint = layui.hint(); hint = layui.hint();
//勾选集合 //勾选集合
var changeList = []; var changeList = [];
//变量别名 //变量别名
var props ={ var props = {
name: 'name', name: 'name',
id: 'id', id: 'id',
children:'children', children: 'children',
checkbox:'checkbox', checkbox: 'checkbox',
spread:'spread' spread: 'spread',
}; deleteBtnLabelKey: 'delete',
addBtnLabelKey: 'add',
};
var enterSkin = 'layui-tree-enter', var enterSkin = 'layui-tree-enter',
Tree = function(options) { Tree = function(options) {
this.options = options; this.options = options;
this.nodes = options.nodes || []; this.nodes = options.nodes || [];
this.props = this.options.props || props; this.props = this.options.props || props;
this.nameKey = this.props.name || props.name; this.nameKey = this.props.name || props.name;
this.idKey = this.props.id || props.id; this.idKey = this.props.id || props.id;
this.childrenKey = this.props.children || props.children; this.childrenKey = this.props.children || props.children;
this.checkboxKey = this.props.checkbox || props.checkbox; this.checkboxKey = this.props.checkbox || props.checkbox;
this.spreadKey = this.props.spread || props.spread; this.spreadKey = this.props.spread || props.spread;
}; this.addBtnLabelKey = this.props.addBtnLabel || props.addBtnLabel;
//图标 this.deleteBtnLabelKey = this.props.deleteBtnLabel || props.deleteBtnLabel;
var icon = { };
arrow: ['', ''] //箭头 //图标
, var icon = {
checkbox: ['', ''] //复选框 arrow: ['', ''] //箭头
, ,
leaf: '' //叶节点 checkbox: ['', ''] //复选框
}; ,
leaf: '' //叶节点
};
//初始化 //初始化
Tree.prototype.init = function(elem) { Tree.prototype.init = function(elem) {
var that = this; var that = this;
elem.addClass('layui-box layui-tree'); //添加tree样式 elem.addClass('layui-box layui-tree'); //添加tree样式
if(that.options.skin) { if(that.options.skin) {
elem.addClass('layui-tree-skin-' + that.options.skin); elem.addClass('layui-tree-skin-' + that.options.skin);
} }
that.tree(elem); that.tree(elem);
that.on(elem); that.on(elem);
}; };
//树节点解析 //树节点解析
Tree.prototype.tree = function(elem, children) { Tree.prototype.tree = function(elem, children) {
var that = this, var that = this,
options = that.options options = that.options
var nodes = children || options.nodes; var nodes = children || options.nodes;
layui.each(nodes, function(index, item) { layui.each(nodes, function(index, item) {
var hasChild = item[that.childrenKey] && item[that.childrenKey].length > 0; var hasChild = item[that.childrenKey] && item[that.childrenKey].length > 0;
var dom = that.getDom(item); var dom = that.getDom(item);
var ul = $(dom.ul(item)); var ul = $(dom.ul(item));
var li = $(that.getNode(item)); var li = $(that.getNode(item));
//如果被选中加入checkbox集合里 //如果被选中加入checkbox集合里
if(item[that.checkboxKey]){ if(item[that.checkboxKey]) {
changeList.push(item); changeList.push(item);
} }
//如果有子节点,则递归继续生成树 //如果有子节点,则递归继续生成树
if(hasChild) { if(hasChild) {
li.append(ul); li.append(ul);
that.tree(ul, item[that.childrenKey]); that.tree(ul, item[that.childrenKey]);
} }
//伸展节点 //伸展节点
that.spread(li, item); that.spread(li, item);
that.bindUlEvent(li, item); that.bindUlEvent(li, item);
elem.append(li); elem.append(li);
}); });
}; };
//节点dom拼接 //节点dom拼接
Tree.prototype.getDom = function(item) { Tree.prototype.getDom = function(item) {
var that = this, var that = this,
options = that.options, options = that.options,
item = item, item = item,
hasChild = item[that.childrenKey] && item[that.childrenKey].length > 0; hasChild = item[that.childrenKey] && item[that.childrenKey].length > 0;
return { return {
spread: function() { spread: function() {
return hasChild ? '<i class="layui-icon layui-tree-spread">' + ( return hasChild ? '<i class="layui-icon layui-tree-spread">' + (
item[that.spreadKey] || options.spreadAll ? icon.arrow[1] : icon.arrow[0] item[that.spreadKey] || options.spreadAll ? icon.arrow[1] : icon.arrow[0]
) + '</i>' : ''; ) + '</i>' : '';
}, },
checkbox: function() { checkbox: function() {
return options.check ? ( return options.check ? (
'<i class="layui-icon layui-tree-check'+(item[that.checkboxKey]?' is-checked':'')+'">' + ( '<i class="layui-icon layui-tree-check' + (item[that.checkboxKey] ? ' is-checked' : '') + '">' + (
item[that.checkboxKey]? icon.checkbox[1] : icon.checkbox[0] item[that.checkboxKey] ? icon.checkbox[1] : icon.checkbox[0]
) + '</i>' ) + '</i>'
) : ''; ) : '';
}, },
ul:function(){ ul: function() {
return '<ul class="' + (item[that.spreadKey] || options.spreadAll ? "layui-show" : "") + '"></ul>' return '<ul class="' + (item[that.spreadKey] || options.spreadAll ? "layui-show" : "") + '"></ul>'
}, },
node: function() { node: function() {
return '<a href="' + (item.href || 'javascript:;') + '" ' + ( return '<a href="' + (item.href || 'javascript:;') + '" ' + (
options.target && item.href ? 'target=\"' + options.target + '\"' : '' options.target && item.href ? 'target=\"' + options.target + '\"' : ''
) + '>' + ) + '>' +
('<cite>' + (item[that.nameKey] || '未命名') + '</cite></a>') ('<cite>' + (item[that.nameKey] || '未命名') + '</cite></a>')
}, },
menu: function() { menu: function() {
return '<div class="layui-tree-menu">' + return '<div class="layui-tree-menu">' +
'<span class="layui-tree-add">Add</span>' + '<span class="layui-tree-add">' + that.addBtnLabelKey + '</span>' +
'<span class="layui-tree-delete">Delete</span>' + '<span class="layui-tree-delete">' + that.deleteBtnLabelKey + '</span>' +
'</div>' '</div>'
} }
} }
} }
//获取树节点 //获取树节点
Tree.prototype.getNode = function(item) { Tree.prototype.getNode = function(item) {
var that = this, var that = this,
options = that.options options = that.options
var dom = that.getDom(item); var dom = that.getDom(item);
var li = ['<li ' var li = ['<li ' +
+ (item[that.spreadKey] || options.spreadAll ? 'data-spread="' + (item[that.spreadKey] || true) + '"' : '') (item[that.spreadKey] || options.spreadAll ? 'data-spread="' + (item[that.spreadKey] || true) + '"' : '') +
+(item[that.checkboxKey] ? 'data-check="' + item[that.checkboxKey] + '"' : '') (item[that.checkboxKey] ? 'data-check="' + item[that.checkboxKey] + '"' : '') +
+('data-id=' + item[that.idKey]) ('data-id=' + item[that.idKey]) +
+ '><div class="layui-tree-node">' '><div class="layui-tree-node">'
//展开箭头 //展开箭头
, ,
dom.spread() dom.spread()
//复选框 //复选框
, ,
dom.checkbox() dom.checkbox()
//节点 //节点
, ,
dom.node() dom.node()
//菜单 //菜单
, ,
dom.menu() dom.menu(),
, '</div></li>'
'</div></li>' ].join('');
].join(''); return li;
return li; }
}
//父绑定事件 //父绑定事件
Tree.prototype.bindUlEvent = function(li, item) { Tree.prototype.bindUlEvent = function(li, item) {
var that = this, var that = this,
options = that.options options = that.options
//触发点击节点回调 //触发点击节点回调
typeof options.click === 'function' && that.click(li, item); typeof options.click === 'function' && that.click(li, item);
//节点选择 //节点选择
typeof options.change === 'function' && options.check === 'checkbox' && that.checkbox(li, item); typeof options.change === 'function' && options.check === 'checkbox' && that.checkbox(li, item);
//新增方法 //新增方法
typeof options.addClick === 'function' && that.add(li, item); typeof options.addClick === 'function' && that.add(li, item);
//删除方法 //删除方法
typeof options.deleteClick === 'function' && that.delete(li, item); typeof options.deleteClick === 'function' && that.delete(li, item);
//拖拽节点 //拖拽节点
options.drag && that.drag(li, item); options.drag && that.drag(li, item);
} }
//选中回调函数 //选中回调函数
Tree.prototype.change = function() { Tree.prototype.change = function() {
var that = this, var that = this,
options = that.options; options = that.options;
options.change(changeList); options.change(changeList);
}, },
//新增方法回调 //新增方法回调
Tree.prototype.add = function(elem, item) { Tree.prototype.add = function(elem, item) {
var that = this, var that = this,
options = that.options; options = that.options;
var node =elem.children('.layui-tree-node'); var node = elem.children('.layui-tree-node');
var addBtn = node.children('.layui-tree-menu').children('.layui-tree-add') var addBtn = node.children('.layui-tree-menu').children('.layui-tree-add')
var arrow = node.children('.layui-tree-spread') var arrow = node.children('.layui-tree-spread')
var ul = elem.children('ul'), var ul = elem.children('ul'),
a = node.children('a'); a = node.children('a');
var addEvent = function(e) { var addEvent = function(e) {
layui.stope(e); layui.stope(e);
var _addEvent = { var _addEvent = {
add: function(itemAddObj) { add: function(itemAddObj) {
if(!item[that.childrenKey]){ if(!item[that.childrenKey]) {
item[that.childrenKey] = []; item[that.childrenKey] = [];
} }
item[that.childrenKey].push(itemAddObj); item[that.childrenKey].push(itemAddObj);
var dom = that.getDom(item); var dom = that.getDom(item);
if(!ul[0]) { if(!ul[0]) {
ul = $(dom.ul()) ul = $(dom.ul())
elem.append(ul); elem.append(ul);
} }
if(!arrow[0]) { if(!arrow[0]) {
arrow = $(dom.spread()); arrow = $(dom.spread());
elem.prepend(arrow); node.prepend(arrow);
that.spread(elem, item); that.spread(elem, item);
} }
if(!elem.data('spread')) { if(!elem.data('spread')) {
that.open(elem, ul, arrow) that.open(elem, ul, arrow)
} }
var li = $(that.getNode(itemAddObj)); var li = $(that.getNode(itemAddObj));
that.bindUlEvent(li, itemAddObj); that.bindUlEvent(li, itemAddObj);
ul.append(li); ul.append(li);
} }
} }
options.addClick(item, elem, _addEvent.add) options.addClick(item, elem, _addEvent.add)
} }
addBtn.on('click', addEvent); addBtn.on('click', addEvent);
} }
//删除方法回调 //删除方法回调
Tree.prototype.delete = function(elem, item) { Tree.prototype.delete = function(elem, item) {
var that = this, var that = this,
options = that.options; options = that.options;
var node =elem.children('.layui-tree-node'); var node = elem.children('.layui-tree-node');
var deleteBtn = node.children('.layui-tree-menu').children('.layui-tree-delete') var deleteBtn = node.children('.layui-tree-menu').children('.layui-tree-delete')
var ul = elem.children('ul'), var ul = elem.children('ul'),
a = elem.children('a'); a = elem.children('a');
var deleteEvent = function(e) { var deleteEvent = function(e) {
layui.stope(e); layui.stope(e);
var _deleteEvent = { var _deleteEvent = {
done: function() { done: function() {
var parent =elem.parent(); var parent = elem.parent();
var arrow = parent.parent().children('.layui-tree-spread') var arrow = parent.parent().children('.layui-tree-spread')
if(parent.children('li').length===1){ if(parent.children('li').length === 1) {
arrow.remove(); arrow.remove();
} }
elem.remove(); elem.remove();
} }
} }
options.deleteClick(item, elem, _deleteEvent.done) options.deleteClick(item, elem, _deleteEvent.done)
} }
deleteBtn.on('click', deleteEvent); deleteBtn.on('click', deleteEvent);
} }
//点击节点回调 //点击节点回调
Tree.prototype.click = function(elem, item) { Tree.prototype.click = function(elem, item) {
var that = this, var that = this,
options = that.options; options = that.options;
var node =elem.children('.layui-tree-node'); var node = elem.children('.layui-tree-node');
node.children('a').on('click', function(e) { node.children('a').on('click', function(e) {
layui.stope(e); layui.stope(e);
options.click(item) options.click(item)
}); });
}; };
//节点选择 //节点选择
Tree.prototype.checkbox = function(elem, item) { Tree.prototype.checkbox = function(elem, item) {
var that = this, var that = this,
options = that.options; options = that.options;
var node =elem.children('.layui-tree-node'); var node = elem.children('.layui-tree-node');
var checkbox = node.children('.layui-tree-check') var checkbox = node.children('.layui-tree-check')
var ul = elem.children('ul'), var ul = elem.children('ul'),
a = node.children('a'); a = node.children('a');
var check = function() { var whileAllCheck = function(dom, item, type) {
var index = layui.findObj(changeList, item); var list = dom.children('.layui-show').find('li');
if(elem.data('check')) { var children = item ? item.children || [] : [];
elem.data('check', null) for(var i = 0; i < list.length; i++) {
checkbox.removeClass(' is-checked'); var li = $(list[i]);
checkbox.html(icon.checkbox[0]); setCheck(li, children[i], type);
} else { whileAllCheck(li, children[i], type);
elem.data('check', true); }
checkbox.addClass(' is-checked'); }
checkbox.html(icon.checkbox[1]); var setCheck = function(elem, item, type) {
} var checkbox = elem.children('.layui-tree-node').find('.layui-tree-check');
if(index === -1) { if(type) {
changeList.push(item); elem.data('check', true)
} else { checkbox.html(icon.checkbox[1])
changeList.splice(index, 1); checkbox.addClass(' is-checked');
} } else {
that.change(); elem.data('check', null);
} checkbox.removeClass(' is-checked');
checkbox.on('click', check); 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);
}; };
//伸展节点 //伸展节点
Tree.prototype.spread = function(elem, item) { Tree.prototype.spread = function(elem, item) {
var that = this, var that = this,
options = that.options; options = that.options;
var node =elem.children('.layui-tree-node'); var node = elem.children('.layui-tree-node');
var arrow = node.children('.layui-tree-spread') var arrow = node.children('.layui-tree-spread')
var ul = elem.children('ul'), var ul = elem.children('ul'),
a = node.children('a'); a = node.children('a');
//如果没有子节点,则不执行 //如果没有子节点,则不执行
if(!ul[0]) return; if(!ul[0]) return;
arrow.on('click', function() { arrow.on('click', function() {
that.open(elem, ul, arrow) that.open(elem, ul, arrow)
}); });
} }
//打开节点 //打开节点
Tree.prototype.open = function(elem, ul, arrow) { Tree.prototype.open = function(elem, ul, arrow) {
if(elem.data('spread')) { if(elem.data('spread')) {
elem.data('spread', null) elem.data('spread', null)
ul.removeClass('layui-show'); ul.removeClass('layui-show');
arrow.html(icon.arrow[0]); arrow.html(icon.arrow[0]);
} else { } else {
elem.data('spread', true); elem.data('spread', true);
ul.addClass('layui-show'); ul.addClass('layui-show');
arrow.html(icon.arrow[1]); arrow.html(icon.arrow[1]);
} }
}; };
//通用事件 //通用事件
Tree.prototype.on = function(elem) { Tree.prototype.on = function(elem) {
var that = this, var that = this,
options = that.options; options = that.options;
var dragStr = 'layui-tree-drag'; var dragStr = 'layui-tree-drag';
//屏蔽选中文字 //屏蔽选中文字
elem.find('i').on('selectstart', function(e) { elem.find('i').on('selectstart', function(e) {
return false return false
}); });
//拖拽 //拖拽
if(options.drag) { if(options.drag) {
$(document).on('mousemove', function(e) { $(document).on('mousemove', function(e) {
var move = that.move; var move = that.move;
if(move.from) { if(move.from) {
var to = move.to, var to = move.to,
treeMove = $('<div class="layui-box ' + dragStr + '"></div>'); treeMove = $('<div class="layui-box ' + dragStr + '"></div>');
e.preventDefault(); e.preventDefault();
$('.' + dragStr)[0] || $('body').append(treeMove); $('.' + dragStr)[0] || $('body').append(treeMove);
var dragElem = $('.' + dragStr)[0] ? $('.' + dragStr) : treeMove; var dragElem = $('.' + dragStr)[0] ? $('.' + dragStr) : treeMove;
(dragElem).addClass('layui-show').html(move.from.elem.children('a').html()); (dragElem).addClass('layui-show').html(move.from.elem.children('a').html());
dragElem.css({ dragElem.css({
left: e.pageX + 10, left: e.pageX + 10,
top: e.pageY + 10 top: e.pageY + 10
}) })
} }
}).on('mouseup', function() { }).on('mouseup', function() {
var move = that.move; var move = that.move;
if(move.from) { if(move.from) {
move.from.elem.children('a').removeClass(enterSkin); move.from.elem.children('a').removeClass(enterSkin);
move.to && move.to.elem.children('a').removeClass(enterSkin); move.to && move.to.elem.children('a').removeClass(enterSkin);
that.move = {}; that.move = {};
$('.' + dragStr).remove(); $('.' + dragStr).remove();
} }
}); });
} }
}; };
//拖拽节点 //拖拽节点
Tree.prototype.move = {}; Tree.prototype.move = {};
Tree.prototype.drag = function(elem, item) { Tree.prototype.drag = function(elem, item) {
var that = this, var that = this,
options = that.options; options = that.options;
var a = elem.children('a'), var a = elem.children('a'),
mouseenter = function() { mouseenter = function() {
var othis = $(this), var othis = $(this),
move = that.move; move = that.move;
if(move.from) { if(move.from) {
move.to = { move.to = {
item: item, item: item,
elem: elem elem: elem
}; };
othis.addClass(enterSkin); othis.addClass(enterSkin);
} }
}; };
a.on('mousedown', function() { a.on('mousedown', function() {
var move = that.move var move = that.move
move.from = { move.from = {
item: item, item: item,
elem: elem elem: elem
}; };
}); });
a.on('mouseenter', mouseenter).on('mousemove', mouseenter) a.on('mouseenter', mouseenter).on('mousemove', mouseenter)
.on('mouseleave', function() { .on('mouseleave', function() {
var othis = $(this), var othis = $(this),
move = that.move; move = that.move;
if(move.from) { if(move.from) {
delete move.to; delete move.to;
othis.removeClass(enterSkin); othis.removeClass(enterSkin);
} }
}); });
}; };
//暴露接口 //暴露接口
exports('atree', function(options) { exports('atree', function(options) {
var tree = new Tree(options = options || {}); var tree = new Tree(options = options || {});
var elem = $(options.elem); var elem = $(options.elem);
if(!elem[0]) { if(!elem[0]) {
return hint.error('layui.tree 没有找到' + options.elem + '元素'); return hint.error('layui.tree 没有找到' + options.elem + '元素');
} }
tree.init(elem); tree.init(elem);
}); });
}); });

View File

@ -437,11 +437,11 @@
} }
//寻找对象是否存在数组中 //寻找对象是否存在数组中
Layui.prototype.findObj = function(list,obj) { Layui.prototype.findObj = function(list,value,key) {
var that = this, var that = this,
result = -1; result = -1;
that.each(list, function(index, item) { that.each(list, function(index, item) {
if(that.isEqualObj(obj,item))result = index; if(item[key] == value)result = index;
}) })
return result; return result;
} }