一、表格树:
1、先将插件源码进行下载,新建 tableTree.js 文件,将源码放进去
2、将 tableTree.js 文件 配置之后,在需要使用的页面进行引入:
layui.define(["tableTree"],function (exports) {
var tableTree = layui.tableTree;
var handleList = function() {
let tableData = [{
"pid": "0",
"title": "1",
"parentTitle": null,
"sid": "1111111111",
"children": null
},
{
"pid": "1111111111",
"title": "1-1",
"parentTitle": "1",
"sid": "2"
},
{
"pid": "1111111111",
"title": "1-2",
"parentTitle": "1",
"sid": "3"
},
{
"pid": "0",
"title": "2",
"parentTitle": null,
"sid": "2222222"
},{
"pid": "0",
"title": "3",
"parentTitle": null,
"sid": "3333333"
},{
"pid": "0",
"title": "4",
"parentTitle": null,
"sid": "44444"
},{
"pid": "0",
"title": "5",
"parentTitle": null,
"sid": "5555"
},{
"pid": "5555",
"title": "5",
"parentTitle": "5",
"sid": "6"
}]
renderTable(tableData)
}
var renderTable = function (tableData) {
tableTree.render({
id: 'test',
tree: {
iconIndex: 3,
isPidData: true,
idName: 'sid',
pidName: 'pid',
openName: 'open',
},
elem: '#test',
skin: 'line'
, page: false
, limit: 100
,cols: [[
{
field: 'id', hide: true },
{
type: 'radio'}
, {
field: 'title', title: '名称', align: 'left', width: 200 }
, {
field: 'opt', title: '操作', templet:
return '<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i> </a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i></a>'
}
]],
data: tableData,
done: function () {
}
, event: true
})
};
tableTree.on('checkbox(test)', function (obj) {
var data = obj.data;
console.log('拿到的当前行的数据', data)
});
tableTree.on("tool(test)", function (obj) {
var data = obj.data;
var layEvent = obj.event;
var tr = obj.tr;
if ("del" === layEvent) {
console.log(删除的数据', data)
} else if ("edit" === layEvent) {
console.log(操作的数据', data)
}
});
var Class = {
init: function () {
handleList()
return this;
},
};
}
);
效果图:

插件源码如下:
layui.define(['laytpl', 'form', 'util'], function (exports) {
var $ = layui.jquery;
var laytpl = layui.laytpl;
var form = layui.form;
var util = layui.util;
var device = layui.device();
var MOD_NAME = 'treeTable';
var _instances = {
};
var defaultOption = {
elem: undefined,
cols: undefined,
url: undefined,
method: undefined,
where: undefined,
contentType: undefined,
headers: undefined,
parseData: undefined,
request: {
pidName: 'pid'},
toolbar: undefined,
defaultToolbar: undefined,
width: undefined,
height: undefined,
cellMinWidth: 90,
done: undefined,
data: undefined,
title: undefined,
skin: undefined,
even: undefined,
size: undefined,
text: {
none: '无数据'
},
reqData: undefined,
useAdmin: false,
tree: {
idName: 'id',
pidName: 'pid',
childName: 'children',
haveChildName: 'haveChild',
openName: 'open',
iconIndex: 0,
arrowType: undefined,
onlyIconControl: undefined,
getIcon: function (d) {
var haveChild = d[this.haveChildName];
if (haveChild !== undefined) haveChild = haveChild === true || haveChild === 'true';
else if (d[this.childName]) haveChild = d[this.childName].length > 0;
if (haveChild) return '<i class="ew-tree-icon layui-icon layui-icon-layer"></i>';
else return '<i class="ew-tree-icon layui-icon layui-icon-file"></i>';
}
}
};
var colDefaultOption = {
field: undefined,
title: undefined,
width: undefined,
minWidth: undefined,
type: 'normal',
fixed: undefined,
hide: undefined,
unresize: undefined,
style: undefined,
align: undefined,
colspan: undefined,
rowspan: undefined,
templet: undefined,
toolbar: undefined,
'class': undefined,
singleLine: undefined
};
var TreeTable = function (options) {
_instances[options.elem.substring(1)] = this;
this.reload(options);
};
TreeTable.prototype.initOptions = function (opt) {
var that = this;
function initCol(item) {
if (!item.INIT_OK) item = $.extend({
INIT_OK: true}, colDefaultOption, item);
if (item.type === 'space') {
if (!item.width) item.width = 15;
item.minWidth = item.width;
} else if (item.type === 'numbers') {
if (!item.width) item.width = 40;
item.minWidth = item.width;
if (!item.singleLine) item.singleLine = false;
if (!item.unresize) item.unresize = true;
if (!item.align) item.align = 'center';
} else if (item.type === 'checkbox' || item.type === 'radio') {
if (!item.width) item.width = 48;
item.minWidth = item.width;
if (!item.singleLine) item.singleLine = false;
if (!item.unresize) item.unresize = true;
if (!item.align) item.align = 'center';
}
if (item.toolbar) item.type = 'tool';
return item;
}
if ('Array' !== isClass(opt.cols[0])) opt.cols = [opt.cols];
for (var m = 0; m < opt.cols.length; m++) {
for (var n = 0; n < opt.cols[m].length; n++) {
opt.cols[m][n].INIT_OK = undefined;
opt.cols[m][n].key = undefined;
opt.cols[m][n].colGroup = undefined;
opt.cols[m][n].HAS_PARENT = undefined;
opt.cols[m][n].parentKey = undefined;
opt.cols[m][n].PARENT_COL_INDEX = undefined;
}
}
var colArrays = [], colIndex = 0;
for (var i1 = 0; i1 < opt.cols.length; i1++) {
var item1 = opt.cols[i1];
for (var i2 = 0; i2 < item1.length; i2++) {
var item2 = item1[i2];
if (!item2) {
item1.splice(i2, 1);
continue;
}
item2 = initCol(item2);
item2.key = i1 + '-' + i2;
var CHILD_COLS = undefined;
if (item2.colGroup || item2.colspan > 1) {
item2.colGroup = true;
item2.type = 'group';
CHILD_COLS = [];
colIndex++;
var childIndex = 0;
for (var i22 = 0; i22 < opt.cols[i1 + 1].length; i22++) {
var item22 = $.extend({
INIT_OK: true}, colDefaultOption, opt.cols[i1 + 1][i22]);
if (item22.HAS_PARENT || (childIndex > 1 && childIndex == item2.colspan)) {
opt.cols[i1 + 1][i22] = item22;
continue;
}
item22.HAS_PARENT = true;
item22.parentKey = i1 + '-' + i2;
item22.key = (i1 + 1) + '-' + i22;
item22.PARENT_COL_INDEX = colIndex;
item22 = initCol(item22);
CHILD_COLS.push(item22);
childIndex = childIndex + parseInt(item22.colspan > 1 ? item22.colspan : 1);
opt.cols[i1 + 1][i22] = item22;
}
}
item2.CHILD_COLS = CHILD_COLS;
if (!item2.PARENT_COL_INDEX) colArrays.push(item2);
opt.cols[i1][i2] = item2;
}
}
this.options = $.extend(true, {
}, defaultOption, opt);
this.options.colArrays = colArrays;
if (this.options.url) {
this.options.reqData = function (data, callback) {
if (!that.options.where) that.options.where = {
};
if (data) that.options.where[that.options.request.pidName] = data[that.options.tree.idName];
(that.options.useAdmin ? layui.admin : $).ajax({
url: that.options.url,
data: that.options.contentType && that.options.contentType.indexOf('application/json') === 0 ? JSON.stringify(that.options.where) : that.options.where,
headers: that.options.headers,
type: that.options.method,
dataType: 'json',
contentType: that.options.contentType,
success: function (res) {
if (that.options.parseData) res = that.options.parseData(res);
if (res.code == 0) callback(res.data);
else callback(res.msg || '加载失败');
},
error: function (xhr) {
callback(xhr.status + ' - ' + xhr.statusText);
}
});
};
} else if (this.options.data && this.options.data.length > 0 && this.options.tree.isPidData) {
this.options.data = tt.pidToChildren(this.options.data, this.options.tree.idName, this.options.tree.pidName, this.options.tree.childName);
}
if ('default' === this.options.toolbar) {
this.options.toolbar = [
'<div>',
' <div class="ew-tree-table-tool-item" title="添加" lay-event="add">',
' <i class="layui-icon layui-icon-add-1"></i>',
' </div>',
' <div class="ew-tree-table-tool-item" title="修改" lay-event="update">',
' <i class="layui-icon layui-icon-edit"></i>',
' </div>',
' <div class="ew-tree-table-tool-item" title="删除" lay-event="delete">',
' <i class="layui-icon layui-icon-delete"></i>',
' </div>',
'</div>'
].join('');
}
if (this.options.defaultToolbar === undefined) this.options.defaultToolbar = ['filter', 'exports', 'print'];
if (typeof this.options.tree.getIcon === 'string') {
var icon = this.options.tree.getIcon;
this.options.tree.getIcon = function (d) {
if (icon !== 'ew-tree-icon-style2') return icon;
var haveChild = d[this.haveChildName];
if (haveChild !== undefined) haveChild = haveChild === true || haveChild === 'true';
else if (d[this.childName]) haveChild = d[this.childName].length > 0;
if (haveChild) return '<i class="ew-tree-icon ew-tree-icon-folder"></i>';
else return '<i class="ew-tree-icon ew-tree-icon-file"></i>';
}
}
};
TreeTable.prototype.init = function () {
var options = this.options;
var $elem = $(options.elem);
var tbFilter = options.elem.substring(1);
$elem.removeAttr('lay-filter');
if ($elem.next('.ew-tree-table').length === 0) {
$elem.css('display', 'none');
$elem.after([
'<div class="layui-form ew-tree-table" lay-filter="', tbFilter, '" style="', options.style || '', '">',
' <div class="ew-tree-table-tool" style="display: none;"></div>',
' <div class="ew-tree-table-head">',
' <table class="layui-table"></table>',
' </div>',
' <div class="ew-tree-table-box">',
' <table class="layui-table"></table>',
' <div class="ew-tree-table-loading">',
' <i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>',
' </div>',
' <div class="ew-tree-table-empty">', options.text.none || '', '</div>',
' </div>',
'</div>'
].join(''));
}
var components = this.getComponents();
if (options.skin) components.$table.attr('lay-skin', options.skin);
if (options.size) components.$table.attr('lay-size', options.size);
if (options.even) components.$table.attr('lay-even', options.even);
components.$toolbar.empty();
if (options.toolbar === false || options.toolbar === undefined) {
components.$toolbar.hide();
} else {
components.$toolbar.show();
if (typeof options.toolbar === 'string') {
laytpl($(options.toolbar).html()).render({
}, function (html) {
components.$toolbar.html('<div style="display: inline-block;">' + html + '</div>');
});
}
var tbRights = ['<div class="ew-tree-table-tool-right">'];
for (var i = 0; i < options.defaultToolbar.length; i++) {
var tbItem;
if ('filter' === options.defaultToolbar[i]) {
tbItem = {
title: '筛选', layEvent: 'LAYTABLE_COLS', icon: 'layui-icon-cols'};
} else if ('exports' === options.defaultToolbar[i]) {
tbItem = {
title: '导出', layEvent: 'LAYTABLE_EXPORT', icon: 'layui-icon-export'};
} else if ('print' === options.defaultToolbar[i]) {
tbItem = {
title: '打印', layEvent: 'LAYTABLE_PRINT', icon: 'layui-icon-print'};
} else {
tbItem = options.defaultToolbar[i];
}
if (tbItem) {
tbRights.push('<div class="ew-tree-table-tool-item"');
tbRights.push(' title="' + tbItem.title + '"');
tbRights.push(' lay-event="' + tbItem.layEvent + '">');
tbRights.push('<i class="layui-icon ' + tbItem.icon + '"></i></div>');
}
}
components.$toolbar.append(tbRights.join('') + '</div>');
}
if (options.width) {
components.$view.css('width', options.width);
components.$tHeadGroup.css('width', options.width);
components.$tBodyGroup.css('width', options.width);
}
var colgroupHtml = this.resize(true);
var headHtml = '<thead>' + this.renderBodyTh() + '</thead>';
components.$tBodyGroup.children('style').remove();
if (options.height) {
components.$tHead.html(colgroupHtml + headHtml);
components.$tBody.html(colgroupHtml + '<tbody></tbody>');
if (options.height.indexOf('full-') === 0) {
var h = parseFloat(options.height.substring(5)) + components.$toolbar.outerHeight()
+ components.$tHeadGroup.outerHeight() + 1;
components.$tBodyGroup.append([
'<style>[lay-filter="', tbFilter, '"] .ew-tree-table-box {',
' height: ', getPageHeight() - h, 'px;',
' height: -moz-calc(100vh - ', h, 'px);',
' height: -webkit-calc(100vh - ', h, 'px);',
' height: calc(100vh - ', h, 'px);',
'}</style>'
].join(''));
components.$tBodyGroup.data('full', h);
components.$tBodyGroup.css('height', '');
} else {
components.$tBodyGroup.css('height', options.height);
components.$tBodyGroup.data('full', '');
}
components.$tHeadGroup.show();
} else {
components.$tHeadGroup.hide();
var trH = {
lg: 50, sm: 30, md: 38};
components.$tBodyGroup.append([
'<style>[lay-filter="', tbFilter, '"] .ew-tree-table-box:before {',
' content: "";',
' position: absolute;',
' top: 0; left: 0; right: 0;',
' height: ' + (trH[options.size || 'md'] * options.cols.length) + 'px;',
' background-color: #f2f2f2;',
' border-bottom: 1px solid #e6e6e6;',
'}</style>'
].join(''));
components.$tBody.html(colgroupHtml + headHtml + '<tbody></tbody>');
}
form.render('checkbox', tbFilter);
function patchHide($tr) {
var parentKey = $tr.data('parent'), pCol;
if (!parentKey) return;
var $parent = components.$table.children('thead').children('tr').children('[data-key="' + parentKey + '"]');
var colspan = $parent.attr('colspan') - 1;
$parent.attr('colspan', colspan);
if (colspan === 0) $parent.addClass('layui-hide');
patchHide($parent);
}
components.$table.children('thead').children('tr').children('th.layui-hide').each(function () {
patchHide($(this));
});
if (options.reqData) {
this.options.data = undefined;
this.renderBodyAsync();
} else if (options.data && options.data.length > 0) {
this.renderBodyData(options.data);
} else {
components.$loading.hide();
components.$empty.show();
}
};
TreeTable.prototype.bindEvents = function () {
var that = this;
var options = this.options;
var components = this.getComponents();
var $allBody = components.$table.children('tbody');
var member = function (ext) {
var $tr = $(this);
if (!$tr.is('tr')) {
var $temp = $tr.parent('tr');
if ($temp.length > 0) $tr = $temp;
else $tr = $tr.parentsUntil('tr').last().parent();
}
var data = that.getDataByTr($tr);
var obj = {
tr: $tr,
data: data,
del: function () {
var index = $tr.data('index');
var indent = parseInt($tr.data('indent'));
$tr.nextAll('tr').each(function () {
if (parseInt($(this).data('indent')) <= indent) return false;
$(this).remove();
});
var indexLength = (typeof index === 'number' ? 1 : index.split('-').length);
$tr.nextAll('tr').each(function () {
var $this = $(this);
if (parseInt($this.data('indent')) < indent) return false;
var _index = $this.data('index').toString