init
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,3 @@
|
|||
layui.config({
|
||||
base: '/res/js/modules/' //你存放新模块的目录,注意,不是 layui 的模块目录
|
||||
}).use('index'); //加载入口
|
|
@ -0,0 +1 @@
|
|||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#FAFAFA;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view .layui-code-ol li:first-child{padding-top:10px}.layui-code-view .layui-code-ol li:last-child{padding-bottom:10px}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}
|
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 701 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 299 KiB |
|
@ -0,0 +1,235 @@
|
|||
layui.define(['jquery'], function(exports) {
|
||||
var MOD_NAME = 'treeTable',
|
||||
o = layui.jquery,
|
||||
tree = function() {};
|
||||
tree.prototype.config = function() {
|
||||
return {
|
||||
top_value: 0,
|
||||
primary_key: 'id',
|
||||
parent_key: 'pid',
|
||||
hide_class: 'layui-hide',
|
||||
icon: {
|
||||
open: 'layui-icon layui-icon-triangle-d',
|
||||
close: 'layui-icon layui-icon-triangle-r',
|
||||
left: 16,
|
||||
},
|
||||
cols: [],
|
||||
checked: {},
|
||||
is_click_icon: false,
|
||||
is_checkbox: false,
|
||||
is_cache: true,
|
||||
};
|
||||
}
|
||||
tree.prototype.template = function(e) {
|
||||
var t = this,
|
||||
level = [],
|
||||
tbody = '',
|
||||
is_table = o('table' + e.elem).length || !(e.is_click_icon = true),
|
||||
checkbox = e.is_checkbox ? '<div class="layui-unselect layui-form-checkbox cbx" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div>' : '',
|
||||
checked = checkbox ? checkbox.replace('cbx', 'cbx layui-form-checked') : '',
|
||||
thead = checkbox && '<th style="width:28px;">' + (o.inArray(e.top_value, e.checked.data) > -1 ? checked : checkbox) + '</th>';
|
||||
o.each(t.data(e, e.data), function(idx, item) {
|
||||
var tr = '',
|
||||
is_checked = false,
|
||||
hide_class = (item[e.parent_key] == e.top_value) || (item[e.parent_key] == t.cache(e, item[e.parent_key])) ? '' : e.hide_class;
|
||||
// 设置每行数据层级
|
||||
item.level = level[item[e.primary_key]] = item[e.parent_key] != e.top_value ? (level[item[e.parent_key]] + 1) : 0;
|
||||
// 设置是否为最后一级
|
||||
item.is_end = !e.childs[item[e.primary_key]];
|
||||
o.each(e.cols, function(index, obj) {
|
||||
var style = '';
|
||||
obj.width && (style += 'width:' + obj.width + ';'), obj.align && (style += 'text-align:' + obj.align + ';'), style && (style = 'style="' + style + '"');
|
||||
// 标记设置行checkbox选中
|
||||
if(e.is_checkbox && e.checked && o.inArray(item[e.checked.key], e.checked.data) > -1) {
|
||||
is_checked = true;
|
||||
}
|
||||
// 第一次遍历头部的时候拼接表格头部
|
||||
idx || (thead += '<th ' + style + '>' + obj.title + '</th>');
|
||||
// 指定列加入开启、关闭小图标
|
||||
var icon = (obj.key == e.icon_key && !item.is_end) ? '<i class="' + (t.cache(e, item[e.primary_key]) ? e.icon.open : e.icon.close) + '"></i>' : '<span></span>';
|
||||
// 指定列小图标按照层级向后位移
|
||||
var left = (obj.key == e.icon_key ? level[item[e.primary_key]] * e.icon.left + 'px' : '');
|
||||
icon = icon.replace('>', ' style="margin-left:' + left + ';">');
|
||||
// 拼接行
|
||||
tr += '<td ' + style + (left ? 'data-down' : '') + '>' + icon + (is_table ? '' : (is_checked ? checked : checkbox)) + (obj.template ? obj.template(item) : item[obj.key]) + '</td>';
|
||||
});
|
||||
var box = is_table ? o(is_checked ? checked : checkbox).wrap('<td style="width:28px;">').parent().prop('outerHTML') : '';
|
||||
tbody += '<tr class="' + hide_class + '" data-id="' + item[e.primary_key] + '" data-pid="' + item[e.parent_key] + '">' + box + tr + '</tr>';
|
||||
});
|
||||
// 处理表树和树的赋值模板
|
||||
var table = is_table ? '<thead><tr data-id="' + e.top_value + '">' + thead + '</tr></thead><tbody>' + tbody + '</tbody>' : tbody.replace(/<tr/g, '<ul').replace(/tr>/g, 'ul>').replace(/<td/g, '<li').replace(/td>/g, 'li>');
|
||||
// 确认点击图标或点击列触发展开关闭
|
||||
var click_btn = e.is_click_icon ? '[data-down] i:not(.layui-icon-ok)' : '[data-down]';
|
||||
// 模板渲染并处理点击展开收起等功能
|
||||
o(e.elem).html(table).off('click', click_btn).on('click', click_btn, function() {
|
||||
var tr = o(this).parents('[data-id]'),
|
||||
td = tr.find('[data-down]'),
|
||||
id = tr.data('id'),
|
||||
pid = tr.data('pid'),
|
||||
is_open = (td.find('i:not(.layui-icon-ok)').attr('class') == e.icon.close);
|
||||
if(is_open) {
|
||||
// 展开子级(子级出现、更改图标)
|
||||
td.find('i:not(.layui-icon-ok)').attr('class', e.icon.open);
|
||||
td.parents(e.elem).find('[data-pid=' + id + ']').removeClass(e.hide_class);
|
||||
t.cache(e, id, true);
|
||||
} else {
|
||||
// 关闭子级(更改图标、隐藏所有子孙级)
|
||||
td.find('i:not(.layui-icon-ok)').attr('class', e.icon.close);
|
||||
t.childs_hide(e, id);
|
||||
}
|
||||
// 设置监听展开关闭
|
||||
layui.event.call(this, MOD_NAME, 'tree(flex)', {
|
||||
elem: this,
|
||||
item: e.childs[pid][id],
|
||||
table: e.elem,
|
||||
is_open: is_open,
|
||||
})
|
||||
}).off('click', '.cbx').on('click', '.cbx', function() {
|
||||
var is_checked = o(this).toggleClass('layui-form-checked').hasClass('layui-form-checked'),
|
||||
tr = o(this).parents('[data-id]'),
|
||||
id = tr.data('id'),
|
||||
pid = tr.data('pid');
|
||||
t.childs_checkbox(e, id, is_checked);
|
||||
t.parents_checkbox(e, pid);
|
||||
// 设置监听checkbox选择
|
||||
layui.event.call(this, MOD_NAME, 'tree(box)', {
|
||||
elem: this,
|
||||
item: pid === undefined ? {} : e.childs[pid][id],
|
||||
table: e.elem,
|
||||
is_checked: is_checked,
|
||||
})
|
||||
}).off('click', '[lay-filter]').on('click', '[lay-filter]', function() {
|
||||
var tr = o(this).parents('[data-id]'),
|
||||
id = tr.data('id'),
|
||||
pid = tr.data('pid'),
|
||||
filter = o(this).attr("lay-filter");
|
||||
return layui.event.call(this, MOD_NAME, 'tree(' + filter + ')', {
|
||||
elem: this,
|
||||
item: e.childs[pid][id],
|
||||
})
|
||||
});
|
||||
e.end && e.end(e);
|
||||
};
|
||||
// 同级全部选中父级选中/同级全部取消取消父级
|
||||
tree.prototype.parents_checkbox = function(e, pid) {
|
||||
var po = o(e.elem).find('[data-pid=' + pid + ']'),
|
||||
co = o(e.elem).find('[data-id=' + pid + ']'),
|
||||
len = o(e.elem).find('[data-pid=' + pid + '] .cbx.layui-form-checked').length;
|
||||
if(po.length == len || len == 0) {
|
||||
var pid = co.data('pid');
|
||||
len ? co.find('.cbx').addClass('layui-form-checked') : co.find('.cbx').removeClass('layui-form-checked');
|
||||
pid === undefined || this.parents_checkbox(e, pid);
|
||||
}
|
||||
};
|
||||
// 子级反选
|
||||
tree.prototype.childs_checkbox = function(e, id, is_checked) {
|
||||
var t = this;
|
||||
o(e.elem).find('[data-pid=' + id + ']').each(function() {
|
||||
var checkbox = o(this).find('.cbx');
|
||||
is_checked ? checkbox.addClass('layui-form-checked') : checkbox.removeClass('layui-form-checked');
|
||||
t.childs_checkbox(e, o(this).data('id'), is_checked);
|
||||
})
|
||||
};
|
||||
// 点击收起循环隐藏子级元素
|
||||
tree.prototype.childs_hide = function(e, id) {
|
||||
var t = this;
|
||||
t.cache(e, id, false);
|
||||
o(e.elem).find('[data-pid=' + id + ']:not(.' + e.hide_class + ')').each(function() {
|
||||
var td = o(this).find('[data-down]'),
|
||||
i = td.find('i:not(.layui-icon-ok)');
|
||||
// 关闭更换小图标
|
||||
i.length && i.attr('class', e.icon.close);
|
||||
// 隐藏子级
|
||||
td.parents(e.elem).find('[data-pid=' + id + ']').addClass(e.hide_class);
|
||||
t.childs_hide(e, o(this).data('id'))
|
||||
});
|
||||
};
|
||||
// 重新组合数据,父子级关系跟随
|
||||
tree.prototype.data = function(e) {
|
||||
var lists = [],
|
||||
childs = [];
|
||||
o.each(e.data, function(idx, item) {
|
||||
lists[item[e.primary_key]] = item;
|
||||
if(!childs[item[e.parent_key]]) {
|
||||
childs[item[e.parent_key]] = [];
|
||||
}
|
||||
childs[item[e.parent_key]][item[e.primary_key]] = item;
|
||||
});
|
||||
e.childs = childs;
|
||||
return this.tree_data(e, lists, e.top_value, []);
|
||||
};
|
||||
tree.prototype.tree_data = function(e, lists, pid, data) {
|
||||
var t = this;
|
||||
if(lists[pid]) {
|
||||
data.push(lists[pid]);
|
||||
delete lists[pid]
|
||||
}
|
||||
o.each(e.data, function(index, item) {
|
||||
if(item[e.parent_key] == pid) {
|
||||
data.concat(t.tree_data(e, lists, item[e.primary_key], data))
|
||||
}
|
||||
});
|
||||
return data;
|
||||
};
|
||||
tree.prototype.render = function(e) {
|
||||
var t = this;
|
||||
e = o.extend(t.config(), e);
|
||||
if(e.url) {
|
||||
o.get(e.url, function(res) {
|
||||
e.data = res;
|
||||
t.template(e);
|
||||
})
|
||||
} else {
|
||||
t.template(e);
|
||||
}
|
||||
return e;
|
||||
};
|
||||
// 获取已选值集合
|
||||
tree.prototype.checked = function(e) {
|
||||
var ids = [];
|
||||
o(e.elem).find('.cbx.layui-form-checked').each(function() {
|
||||
var id = o(this).parents('[data-id]').data('id');
|
||||
ids.push(id);
|
||||
})
|
||||
return ids;
|
||||
};
|
||||
// 全部展开
|
||||
tree.prototype.openAll = function(e) {
|
||||
var t = this;
|
||||
o.each(e.data, function(idx, item) {
|
||||
item[e.primary_key] && t.cache(e, item[e.primary_key], true);
|
||||
})
|
||||
t.render(e);
|
||||
}
|
||||
// 全部关闭
|
||||
tree.prototype.closeAll = function(e) {
|
||||
localStorage.setItem(e.elem.substr(1), '');
|
||||
this.render(e);
|
||||
}
|
||||
tree.prototype.on = function(events, callback) {
|
||||
return layui.onevent.call(this, MOD_NAME, events, callback)
|
||||
};
|
||||
// 存储折叠状态
|
||||
tree.prototype.cache = function(e, val, option) {
|
||||
if(!e.is_cache) {
|
||||
return false;
|
||||
}
|
||||
var t = this,
|
||||
name = e.elem.substr(1),
|
||||
val = val.toString(),
|
||||
cache = localStorage.getItem(name) ? localStorage.getItem(name).split(',') : [],
|
||||
index = o.inArray(val, cache);
|
||||
if(option === undefined) {
|
||||
return index == -1 ? false : val
|
||||
}
|
||||
if(option && index == -1) {
|
||||
cache.push(val)
|
||||
}
|
||||
if(!option && index > -1) {
|
||||
cache.splice(index, 1)
|
||||
}
|
||||
localStorage.setItem(name, cache.join(','));
|
||||
};
|
||||
var tree = new tree();
|
||||
exports(MOD_NAME, tree)
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|