layui.define('grid', function (exports) {
var Grid = layui.grid;
var TreeGrid = {
config: Grid.config,
createNew: function (option) {
var grid = Grid.createNew(option);
grid.pageSize = undefined;
grid.id = option.id || 'id';
grid.parentid = option.parentid || 'parentid';
grid.root = option.root || 0;
grid.order = option.order || grid.id;
grid.asc = option.asc || 'asc';
grid.loadRow = option.loadRow; //懒加载
//grid.onCollapse = option.onCollapse;
//grid.onExpand = option.onExpand;
grid.dataSuccess = function (pageData) {
if (option.dataSuccess) option.dataSuccess(pageData);
var treeRows = [];
HELPER.treeData(pageData.rows, treeRows, grid.root);
grid.pageData.rows = treeRows;
};
var EXPANDER = '',
INDENT = '';
var HELPER = {
treeData: function (rows, tree, pid) {
if (Object.prototype.toString.call(rows) != '[object Array]')
rows = [rows];
var items = [];
$.each(rows, function (_, item) {
if (item[grid.parentid] == pid)
items.push(item);
});
items.sort(function (a, b) {
var x = a[grid.order],
y = b[grid.order];
return x == y ? 0 : (x > y ? 1 : -1);
});
if (items.length > 0) {
$.each(items, function (_, item) {
tree.push(item);
HELPER.treeData(rows, tree, item[grid.id]);
});
}
},
nodeId: function (node) {
var template = /treegrid-([A-Za-z0-9_-]+)/;
if (template.test(node.attr('class')))
return template.exec(node.attr('class'))[1];
else
return null;
},
nodePid: function (node) {
var template = /treegrid-parent-([A-Za-z0-9_-]+)/;
if (template.test(node.attr('class')))
return template.exec(node.attr('class'))[1];
else
return null;
},
//展开
expanded: function (flag, id) {
var trs, tr;
if (id != undefined) {
tr = grid.elem.find('.grid-body tr.treegrid-' + id);
tr.removeClass('treegrid-collapse').addClass('treegrid-expanded');
trs = tr.nextAll();
} else
trs = grid.elem.find('.grid-body tbody tr');
trs.each(function (_, t) {
t = $(t);
if (tr && t.find('span.treegrid-indent,span.treegrid-expander').length <= tr.find('span.treegrid-indent,span.treegrid-expander').length) {
return false;
}
var pid = HELPER.nodePid(t),
pNode = t.prevAll('.treegrid-' + pid);
if (flag || pNode.hasClass('treegrid-expanded') || id == undefined && HELPER.nodeId(pNode) == grid.root)
t.show();
if (t.hasClass('treegrid-collapse') && flag || id == undefined && pid == null)
t.removeClass('treegrid-collapse').addClass('treegrid-expanded');
});
grid.resize();
},
//折叠
cellapsed: function (flag, id) {
var trs, tr;
if (id != undefined) {
tr = grid.elem.find('.grid-body tbody tr.treegrid-' + id);
tr.removeClass('treegrid-expanded').addClass('treegrid-collapse');
trs = tr.nextAll();
} else
trs = grid.elem.find('.grid-body tbody tr');
trs.each(function (_, t) {
t = $(t);
if (tr && t.find('span.treegrid-indent,span.treegrid-expander').length <= tr.find('span.treegrid-indent,span.treegrid-expander').length) {
return false;
}
var pid = HELPER.nodePid(t);
if (pid != null)
t.hide();
if (t.hasClass('treegrid-expanded') && (flag) || id == undefined && pid == null)
t.removeClass('treegrid-expanded').addClass('treegrid-collapse');
});
grid.resize();
},
//节点展开、折叠事件
onExpand: function () {
var tr = $(this).parents('tr').last(),
id = HELPER.nodeId(tr);
if (tr.hasClass('treegrid-expanded')) {
HELPER.cellapsed(false, id);
} else {
HELPER.expanded(false, id);
}
event.stopPropagation(); //阻止冒泡 rowClick
},
//懒加载事件
onLoadRow: function () {
var that = $(this);
var tr = that.parents('tr').last().removeClass('treegrid-collapse').addClass('treegrid-loading'),
id = HELPER.nodeId(tr);
that.unbind('click');
/*grid.loadRow(id, function (rows) {
console.log(123);
grid.insertChild(rows, id);
that.on('click', HELPER.onExpand);
tr.removeClass('treegrid-loading').addClass('treegrid-expanded');
});*/
grid.loadRow({
pid: id,
children: function (rows) {
tr.removeClass('treegrid-loading');
if (!rows) {
tr.addClass('treegrid-wrong');
}
else if (rows.length > 0) {
grid.insertChild(rows, id);
that.on('click', HELPER.onExpand);
tr.addClass('treegrid-expanded');
} else {
that.replaceWith(INDENT);
}
}
});
},
treeDom: function (trs, rows) {
if (Object.prototype.toString.call(rows) != '[object Array]')
rows = [rows];
$.each(trs, function (i, tr) {
tr = $(tr),
id = rows[i][grid.id],
pid = rows[i][grid.parentid];
tr.addClass('treegrid-' + id);
if (pid != grid.root) tr.addClass('treegrid-parent-' + pid);
//多选事件绑定
if (!grid.singleSelect) {
tr.click(function () {
var selected = $(this).hasClass('selected');
private_childSelect($(this), selected);
var _pid = HELPER.nodePid($(this));
if (_pid != null)
private_parentSelect(selected, _pid);
});
}
});
function private_childSelect($tr, selected) {
$tr.nextAll().each(function (_, tr) {
if ($(tr).find('span.treegrid-indent,span.treegrid-expander').length <= $tr.find('span.treegrid-indent,span.treegrid-expander').length) {
return false;
}
selected ? $(tr).addClass('selected') : $(tr).removeClass('selected');
if ($(tr).find('td:first :checkbox').length > 0)
$(tr).find('td:first :checkbox')[0].checked = selected;
});
}
function private_parentSelect(selected, pid) {
var tr = grid.elem.find('tr.treegrid-' + pid);
if (tr.length > 0) {
if (selected && !tr.hasClass('selected')) {
tr.addClass('selected');
if (tr.find('td:first :checkbox').length > 0)
tr.find('td:first :checkbox')[0].checked = true;
}
else if (tr.nextAll('tr.treegrid-parent-' + pid + '.selected').length == 0) {
tr.removeClass('selected');
if (tr.find('td:first :checkbox').length > 0)
tr.find('td:first :checkbox')[0].checked = false;
}
pid = HELPER.nodePid(tr);
if (pid != null)
private_parentSelect(selected, pid);
}
}
$.each(trs, function (_, tr) {
tr = $(tr);
var id = HELPER.nodeId(tr),
pid = HELPER.nodePid(tr);
if (tr.next('.treegrid-parent-' + id).length > 0) {
$(EXPANDER).on('click', HELPER.onExpand).prependTo(tr.addClass('treegrid-expanded').find('td:eq(0)'));
} else if (grid.loadRow && grid.pageData.rows[tr.index()]._children) {
$(EXPANDER).on('click', HELPER.onLoadRow).prependTo(tr.addClass('treegrid-collapse').find('td:eq(0)'));
} else {
tr.find('td:eq(0)').prepend(INDENT);
}
if (grid.elem.find('tr.treegrid-' + pid).length > 0) {
var prevIndentLen = grid.elem.find('tr.treegrid-' + pid).find('.treegrid-expander').prevAll().length;
var pindent = '';
for (var i = 0; i < prevIndentLen; i++) {
pindent += INDENT;
}
tr.find('td:eq(0)').prepend(pindent + INDENT);
}
});
grid.resize();
}
}
grid.success = function () {
if (option.success)
option.success();
HELPER.treeDom(grid.elem.find('.grid-body tbody tr'), grid.pageData.rows);
/*
if (option.onCollapse) {
}
if (option.onExpand) {
}*/
};
//折叠
grid.collapse = function (id) {
HELPER.cellapsed(false, id);
}
//折叠全部
grid.collapseAll = function (id) {
HELPER.cellapsed(true, id);
}
//展开
grid.expand = function (id) {
HELPER.expanded(false, id);
}
//展开全部
grid.expandAll = function (id) {
HELPER.expanded(true, id);
}
//获取子节数据
grid.getChild = function (pid) {
var rows = [],
tr = grid.elem.find('.grid-body tr.treegrid-' + pid),
index = tr.index();
$.each(tr.nextAll('.treegrid-parent-' + pid), function () {
rows.push(grid.pageData.rows[$(this).index()]);
});
return rows;
}
//获取子节点数据,包含子节点的延伸
grid.getChildAll = function (pid) {
var rows = [],
tr = grid.elem.find('.grid-body tr.treegrid-' + pid),
index = tr.index();
$.each(tr.nextAll(),function(i,t){
var t=$(t);
if (t.find('span.treegrid-indent,span.treegrid-expander').length <= tr.find('span.treegrid-indent,span.treegrid-expander').length) {
return false;
}
rows.push(grid.pageData[index + i]);
});
return rows;
}
//添加同级节点
grid.insertNode = function (rows, pid) {
pid = pid != undefined ? pid : grid.root;
var index = undefined;
if (pid != grid.root) {
var tr = grid.elem.find('.grid-body tr.treegrid-' + pid);
index = tr.index();
pid = HELPER.nodePid(tr);
}
var newRow = [];
HELPER.treeData(rows, newRow, pid);
var trs = grid.insert(newRow, index);
HELPER.treeDom(trs, newRow);
}
//添加子节点
grid.insertChild = function (rows, pid) {
pid = pid != undefined ? pid : grid.root;
var index = undefined;
if (pid != grid.root) {
var tr = grid.elem.find('.grid-body tr.treegrid-' + pid);
index = tr.index();
index++;
tr.addClass('treegrid-expanded');
if (tr.find('td').first().find('span.treegrid-expander').length == 0) {
tr.find('td').first().find('span.treegrid-indent').last().removeClass('treegrid-indent').addClass('treegrid-expander').on('click', HELPER.onExpand);
} else {
$.each(tr.nextAll(), function (i, t) {
var t = $(t);
if (t.find('span.treegrid-indent,span.treegrid-expander').length <= tr.find('span.treegrid-indent,span.treegrid-expander').length) {
return false;
}
index++;
if (HELPER.nodePid(t) == pid) t.show();
});
}
}
if (index >= grid.pageData.rows.length)
index = undefined;
var newRow = [];
HELPER.treeData(rows, newRow, pid);
var trs = grid.insert(newRow, index);
HELPER.treeDom(trs, newRow);
}
//修改节点
grid.updateNode = function (row,id) {
if (id == undefined) {
//console.log('treegrid error:参数id错误');
return;
}
var tr = grid.elem.find('.grid-body tr.treegrid-' + id);
var index = tr.index();
var trs = grid.update(row, index);
HELPER.treeDom(trs, row);
}
//删除节点及其子节点
grid.deleteNode = function (id) {
if (id == undefined) {
//console.log('treegrid error:参数id错误');
return;
}
var tr = grid.elem.find('.grid-body tr.treegrid-' + id);
var index = tr.index(),
idx = [index];
$.each(tr.nextAll(), function (i, t) {
var t = $(t);
if (t.find('span.treegrid-indent,span.treegrid-expander').length <= tr.find('span.treegrid-indent,span.treegrid-expander').length) {
return false;
}
index++;
idx.push(index);
});
grid.delete(idx);
}
grid.editNode = function (id) {
var index, trs, rows;
if (id != undefined) {
var tr = grid.elem.find('.grid-body tbody tr.treegrid-' + id);
index = tr.index();
}
grid.edit(index);
if (index != undefined && index >= 0) {
trs = grid.elem.find('.grid-body tbody tr:eq(' + index + ')');
rows = grid.pageData.rows[index];
} else {
trs = grid.elem.find('.grid-body tbody tr');
rows = grid.pageData.rows;
}
HELPER.treeDom(trs, rows);
}
grid.endEditNode = function (id) {
var index, trs, rows;
if (id != undefined) {
var tr = grid.elem.find('.grid-body tbody tr.treegrid-' + id);
index = tr.index();
}
grid.endEdit(index);
if (index != undefined && index >= 0) {
trs = grid.elem.find('.grid-body tbody tr:eq(' + index + ')');
rows = grid.pageData.rows[index];
} else {
trs = grid.elem.find('.grid-body tbody tr');
rows = grid.pageData.rows;
}
HELPER.treeDom(trs, rows);
}
return grid;
}
};
exports('treegrid', TreeGrid);
layui.link(layui.cache.base + 'css/grid.css', null, 'gridcss');
});