Merge pull request #1247 from sunxiaobin89/2.x

修复一些问题和新增一些内容
pull/1249/head
贤心 2023-05-03 23:29:48 +08:00 committed by GitHub
commit 125a8a0c26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 306 additions and 211 deletions

View File

@ -1119,6 +1119,13 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-table-tree-nodeIcon > * {width: 100%;} .layui-table-tree-nodeIcon > * {width: 100%;}
.layui-table-tree-flexIcon,.layui-table-tree-nodeIcon {margin-right: 2px;} .layui-table-tree-flexIcon,.layui-table-tree-nodeIcon {margin-right: 2px;}
.layui-table-tree-flexIcon {cursor: pointer;} .layui-table-tree-flexIcon {cursor: pointer;}
.layui-table-tree [name="layTableCheckbox"] + div.layui-form-checkbox[lay-skin="primary"] .layui-icon-indeterminate:before {height: 2px;}
.layui-table-tree tr[data-level] [name="layTableCheckbox"] + div.layui-form-checked[lay-skin="primary"] i {background-color: #c8f6d4;border-color: #c8f6d4 !important;}
.layui-table-tree tr[data-level="0"] [name="layTableCheckbox"] + div.layui-form-checked[lay-skin="primary"] i {background-color: #16b777;border-color: #16b777 !important;}
.layui-table-tree tr[data-level="1"] [name="layTableCheckbox"] + div.layui-form-checked[lay-skin="primary"] i {background-color: #23ca81;border-color: #23ca81 !important;}
.layui-table-tree tr[data-level="2"] [name="layTableCheckbox"] + div.layui-form-checked[lay-skin="primary"] i {background-color: #34e089;border-color: #34e089 !important;}
.layui-table-tree tr[data-level="3"] [name="layTableCheckbox"] + div.layui-form-checked[lay-skin="primary"] i {background-color: #48fa98;border-color: #48fa98 !important;}
.layui-table-tree tr[data-level="4"] [name="layTableCheckbox"] + div.layui-form-checked[lay-skin="primary"] i {background-color: #87e2bd;border-color: #87e2bd !important;}
/** 文件上传 **/ /** 文件上传 **/
.layui-upload-file{display: none!important; opacity: .01; filter: Alpha(opacity=1);} .layui-upload-file{display: none!important; opacity: .01; filter: Alpha(opacity=1);}

View File

@ -616,9 +616,9 @@
}; };
// 将数组中的成员对象按照某个 key 的 value 值进行排序 // 将数组中的成员对象按照某个 key 的 value 值进行排序
Layui.prototype.sort = function(arr, key, desc){ Layui.prototype.sort = function(arr, key, desc, notClone){
var that = this var that = this
,clone = JSON.parse( ,clone = notClone ? (arr || []) : JSON.parse(
JSON.stringify(arr || []) JSON.stringify(arr || [])
); );

View File

@ -139,7 +139,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// thead 区域模板 // thead 区域模板
var TPL_HEADER = function(options){ var TPL_HEADER = function(options){
var rowCols = '{{#if(item2.colspan){}} colspan="{{=item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{=item2.rowspan}}"{{#}}}'; var rowCols = '{{#var colspan = layui.type(item2.colspan2) === \'number\' ? item2.colspan2 : item2.colspan; if(colspan){}} colspan="{{=colspan}}"{{#} if(item2.rowspan){}} rowspan="{{=item2.rowspan}}"{{#}}}';
options = options || {}; options = options || {};
return ['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" ' return ['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" '
@ -510,7 +510,6 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
} }
item2.key = [options.index, i1, i2].join('-'); item2.key = [options.index, i1, i2].join('-');
item2.hide = item2.hide || false;
item2.colspan = item2.colspan || 0; item2.colspan = item2.colspan || 0;
item2.rowspan = item2.rowspan || 0; item2.rowspan = item2.rowspan || 0;
@ -535,6 +534,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
} else { } else {
item2.colGroup = false; item2.colGroup = false;
} }
item2.hide = item2.hide && !item2.colGroup || false; // 初始化中中间节点的hide信息不做处理否则会出错如果需要必须将其子节点也都同步成hide
}; };
// 初始化列参数 // 初始化列参数
@ -634,10 +634,10 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
hide ? parentColspan-- : parentColspan++; hide ? parentColspan-- : parentColspan++;
parentTh.attr('colspan', parentColspan); parentTh.attr('colspan', parentColspan);
parentTh[parentColspan >= 1 || !hide ? 'removeClass' : 'addClass'](HIDE); // 如果子列显示,父列必然需要显示 parentTh[parentColspan ? 'removeClass' : 'addClass'](HIDE); // 如果子列显示,父列必然需要显示
getThisCol.colspan = parentColspan; //同步 colspan 参 getThisCol.colspan2 = parentColspan; // 更新实际的 colspan
getThisCol.hide = parentColspan >= 1 || !hide; //同步 hide 参数 getThisCol.hide = parentColspan < 1; // 同步 hide 参数
//递归,继续往上查询是否有父列 //递归,继续往上查询是否有父列
var nextParentKey = parentTh.data('parentkey'); var nextParentKey = parentTh.data('parentkey');
@ -872,7 +872,14 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 对参数进行深度或浅扩展 // 对参数进行深度或浅扩展
that.config = $.extend(deep, {}, that.config, options); that.config = $.extend(deep, {}, that.config, options);
if (type !== 'reloadData') {
layui.each(that.config.cols, function (i1, item1) {
layui.each(item1, function (i2, item2) {
delete item2.colspan2;
})
})
delete that.config.HAS_SET_COLS_PATCH;
}
// 执行渲染 // 执行渲染
that.render(type); that.render(type);
}; };
@ -1530,11 +1537,11 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 默认为前端自动排序。如果否,则需自主排序(通常为服务端处理好排序) // 默认为前端自动排序。如果否,则需自主排序(通常为服务端处理好排序)
if(options.autoSort){ if(options.autoSort){
if(opts.type === 'asc'){ //升序 if(opts.type === 'asc'){ //升序
thisData = layui.sort(data, field); thisData = layui.sort(data, field, null, true);
} else if(opts.type === 'desc'){ //降序 } else if(opts.type === 'desc'){ //降序
thisData = layui.sort(data, field, true); thisData = layui.sort(data, field, true, true);
} else { // 清除排序 } else { // 清除排序
thisData = layui.sort(data, table.config.indexName); thisData = layui.sort(data, table.config.indexName, null, true);
delete that.sortKey; delete that.sortKey;
delete options.initSort; delete options.initSort;
} }
@ -2527,7 +2534,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
if (item22.PARENT_COL_INDEX || (childIndex >= 1 && childIndex == (item2.colspan || 1))) return; if (item22.PARENT_COL_INDEX || (childIndex >= 1 && childIndex == (item2.colspan || 1))) return;
item22.PARENT_COL_INDEX = index; item22.PARENT_COL_INDEX = index;
item2.CHILD_COLS.push(item22); item2.CHILD_COLS.push(item22);
childIndex = childIndex + (item22.hide ? 0 : parseInt(item22.colspan > 1 ? item22.colspan : 1)); childIndex = childIndex + (parseInt(item22.colspan > 1 ? item22.colspan : 1));
eachChildCols(index, cols, i2, item22); eachChildCols(index, cols, i2, item22);
} }
}); });

View File

@ -10,6 +10,7 @@ layui.define(['table'], function (exports) {
var form = layui.form; var form = layui.form;
var table = layui.table; var table = layui.table;
var hint = layui.hint(); var hint = layui.hint();
var timer = {}; // 记录定时器 index
// api // api
var treeTable = { var treeTable = {
@ -24,14 +25,16 @@ layui.define(['table'], function (exports) {
that.config = $.extend({}, that.config, options); that.config = $.extend({}, that.config, options);
return that; return that;
}, },
resize: table.resize resize: table.resize,
getOptions: table.getOptions,
hideCol: table.hideCol
}; };
// 操作当前实例 // 操作当前实例
var thisTreeTable = function () { var thisTreeTable = function () {
var that = this var that = this;
, options = that.config var options = that.config
, id = options.id || options.index; var id = options.id || options.index;
return { return {
config: options, config: options,
@ -57,38 +60,28 @@ layui.define(['table'], function (exports) {
} }
// 字符 // 字符
var MOD_NAME = 'treeTable' var MOD_NAME = 'treeTable';
, ELEMTREE = '.layui-table-tree' var HIDE = 'layui-hide';
, THIS = 'layui-this'
, SHOW = 'layui-show'
, HIDE = 'layui-hide'
, HIDE_V = 'layui-hide-v'
, DISABLED = 'layui-disabled'
, NONE = 'layui-none'
, ELEM_VIEW = '.layui-table-view' var ELEM_VIEW = '.layui-table-view';
, ELEM_TOOL = '.layui-table-tool' var ELEM_TREE = '.layui-table-tree';
, ELEM_BOX = '.layui-table-box' var ELEM_TOOL = '.layui-table-tool';
, ELEM_INIT = '.layui-table-init' var ELEM_BOX = '.layui-table-box';
, ELEM_HEADER = '.layui-table-header' var ELEM_HEADER = '.layui-table-header';
, ELEM_BODY = '.layui-table-body' var ELEM_BODY = '.layui-table-body';
, ELEM_MAIN = '.layui-table-main' var ELEM_MAIN = '.layui-table-main';
, ELEM_FIXED = '.layui-table-fixed' var ELEM_FIXED = '.layui-table-fixed';
, ELEM_FIXL = '.layui-table-fixed-l' var ELEM_FIXL = '.layui-table-fixed-l';
, ELEM_FIXR = '.layui-table-fixed-r' var ELEM_FIXR = '.layui-table-fixed-r';
, ELEM_TOTAL = '.layui-table-total'
, ELEM_PAGE = '.layui-table-page'
, ELEM_SORT = '.layui-table-sort'
, ELEM_EDIT = 'layui-table-edit'
, ELEM_HOVER = 'layui-table-hover'
, ELEM_GROUP = 'laytable-cell-group'
var TABLE_TREE = 'layui-table-tree';
var LAY_DATA_INDEX = 'LAY_DATA_INDEX'; var LAY_DATA_INDEX = 'LAY_DATA_INDEX';
var LAY_DATA_INDEX_HISTORY = 'LAY_DATA_INDEX_HISTORY'; var LAY_DATA_INDEX_HISTORY = 'LAY_DATA_INDEX_HISTORY';
var LAY_PARENT_INDEX = 'LAY_PARENT_INDEX'; var LAY_PARENT_INDEX = 'LAY_PARENT_INDEX';
var LAY_CHECKBOX_HALF = 'LAY_CHECKBOX_HALF'; var LAY_CHECKBOX_HALF = 'LAY_CHECKBOX_HALF';
var LAY_EXPAND = 'LAY_EXPAND'; var LAY_EXPAND = 'LAY_EXPAND';
var LAY_HAS_EXPANDED = 'LAY_HAS_EXPANDED'; var LAY_HAS_EXPANDED = 'LAY_HAS_EXPANDED';
var LAY_ASYNC_STATUS = 'LAY_ASYNC_STATUS';
// 构造器 // 构造器
var Class = function (options) { var Class = function (options) {
@ -111,31 +104,31 @@ layui.define(['table'], function (exports) {
}) })
} }
Class.prototype.init = function () { var updateOptions = function (id, options, reload) {
var that = this; var that = getThisTable(id);
var options = that.config; var thatOptionsTemp = $.extend(true, {} , that.getOptions(), options);
var treeOptions = thatOptionsTemp.tree;
// 先初始一个空的表格以便拿到对应的表格实例信息 var childrenKey = treeOptions.customName.children;
var tableIns = table.render($.extend({}, options, {
data: [],
url: '',
done: null
}))
var id = tableIns.config.id;
thisTreeTable.that[id] = that; // 记录当前实例对象
that.tableIns = tableIns;
var treeOptions = options.tree;
var customName = treeOptions.customName;
var isParentKey = customName.isParent;
var childrenKey = customName.children;
// 处理属性 // 处理属性
delete options.hasNumberCol;
delete options.hasChecboxCol;
delete options.hasRadioCol;
table.eachCols(null, function (i1, item1) {
if (item1.type === 'numbers') {
options.hasNumberCol = true;
} else if (item1.type === 'checkbox') {
options.hasChecboxCol = true;
} else if (item1.type === 'radio') {
options.hasRadioCol = true;
}
}, thatOptionsTemp.cols)
var parseData = options.parseData; var parseData = options.parseData;
var done = options.done; var done = options.done;
if (options.url) { if (thatOptionsTemp.url) {
// 异步加载的时候需要处理parseData进行转换 // 异步加载的时候需要处理parseData进行转换
if (!reload || (reload && parseData && !parseData.mod)) {
options.parseData = function () { options.parseData = function () {
var parseDataThat = this; var parseDataThat = this;
var args = arguments; var args = arguments;
@ -153,6 +146,8 @@ layui.define(['table'], function (exports) {
return retData; return retData;
} }
options.parseData.mod = true
}
} else { } else {
options.data = options.data || []; options.data = options.data || [];
// 处理 isSimpleData // 处理 isSimpleData
@ -165,6 +160,7 @@ layui.define(['table'], function (exports) {
that.initData(options.data); that.initData(options.data);
} }
if (!reload || (reload && done && !done.mod)) {
options.done = function () { options.done = function () {
var args = arguments; var args = arguments;
var doneThat = this; var doneThat = this;
@ -191,6 +187,25 @@ layui.define(['table'], function (exports) {
return done.apply(doneThat, args); return done.apply(doneThat, args);
} }
} }
options.done.mod = true;
}
}
Class.prototype.init = function () {
var that = this;
var options = that.config;
// 先初始一个空的表格以便拿到对应的表格实例信息
var tableIns = table.render($.extend({}, options, {
data: [],
url: '',
done: null
}))
var id = tableIns.config.id;
thisTreeTable.that[id] = that; // 记录当前实例对象
that.tableIns = tableIns;
updateOptions(id, options);
} }
// 初始默认配置 // 初始默认配置
@ -201,8 +216,7 @@ layui.define(['table'], function (exports) {
isParent: "isParent", // 节点数据保存节点是否为父节点的属性名称 isParent: "isParent", // 节点数据保存节点是否为父节点的属性名称
name: "name", // 节点数据保存节点名称的属性名称 name: "name", // 节点数据保存节点名称的属性名称
id: "id", // 唯一标识的属性名称 id: "id", // 唯一标识的属性名称
pid: "parentId", pid: "parentId", // 父节点唯一标识的属性名称
rootId: null
}, },
view: { view: {
indent: 14, // 层级缩进量 indent: 14, // 层级缩进量
@ -217,7 +231,8 @@ layui.define(['table'], function (exports) {
dblClickExpand: true, // 双击节点时,是否自动展开父节点的标识 dblClickExpand: true, // 双击节点时,是否自动展开父节点的标识
}, },
data: { data: {
isSimpleData: false // 是否简单数据模式 isSimpleData: false, // 是否简单数据模式
rootPId: null // 根节点的父 ID 值
}, },
async: { async: {
enable: false, // 是否开启异步加载模式,只有开启的时候其他参数才起作用 enable: false, // 是否开启异步加载模式,只有开启的时候其他参数才起作用
@ -276,7 +291,7 @@ layui.define(['table'], function (exports) {
tableData = tableData || table.cache[tableId]; tableData = tableData || table.cache[tableId];
return flatToTree(tableData, customName.id, customName.pid, customName.children, customName.rootId) return flatToTree(tableData, customName.id, customName.pid, customName.children, treeOptions.data.rootPId)
} }
Class.prototype.treeToFlat = function (tableData, parentId, parentIndex) { Class.prototype.treeToFlat = function (tableData, parentId, parentIndex) {
@ -309,6 +324,7 @@ layui.define(['table'], function (exports) {
var dataCache = table.cache[tableId][index]; var dataCache = table.cache[tableId][index];
if (newValue !== 'delete' && dataCache) { if (newValue !== 'delete' && dataCache) {
$.extend(dataCache, newValue);
return clone ? $.extend({}, dataCache) : dataCache; return clone ? $.extend({}, dataCache) : dataCache;
} }
@ -414,7 +430,7 @@ layui.define(['table'], function (exports) {
var trExpand = isToggle ? !trData[LAY_EXPAND] : expandFlag; var trExpand = isToggle ? !trData[LAY_EXPAND] : expandFlag;
var retValue = trData[isParentKey] ? trExpand : null; var retValue = trData[isParentKey] ? trExpand : null;
if (callbackFlag && trExpand != trData[LAY_EXPAND] && (!trData['LAY_ASYNC_STATUS'] || trData['LAY_ASYNC_STATUS'] === 'local')) { if (callbackFlag && trExpand != trData[LAY_EXPAND] && (!trData[LAY_ASYNC_STATUS] || trData[LAY_ASYNC_STATUS] === 'local')) {
var beforeExpand = treeOptions.callback.beforeExpand; var beforeExpand = treeOptions.callback.beforeExpand;
if (layui.type(beforeExpand) === 'function') { if (layui.type(beforeExpand) === 'function') {
if (beforeExpand(tableId, trData, expandFlag) === false) { if (beforeExpand(tableId, trData, expandFlag) === false) {
@ -445,22 +461,22 @@ layui.define(['table'], function (exports) {
trData[LAY_EXPAND] = trExpand; trData[LAY_EXPAND] = trExpand;
tableViewElem.find(childNodes.map(function (value, index, array) { tableViewElem.find(childNodes.map(function (value, index, array) {
return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]' return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]'
}).join(',')).removeClass('layui-hide'); }).join(',')).removeClass(HIDE);
layui.each(childNodes, function (i1, item1) { layui.each(childNodes, function (i1, item1) {
if (sonSign && !isToggle) { // 非状态切换的情况下 if (sonSign && !isToggle) { // 非状态切换的情况下
// 级联展开子节点 // 级联展开子节点
expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1.LAY_DATA_INDEX + '"]').first()}, expandFlag, sonSign, focus, callbackFlag); expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1[LAY_DATA_INDEX] + '"]').first()}, expandFlag, sonSign, focus, callbackFlag);
} else if (item1[LAY_EXPAND]) { } else if (item1[LAY_EXPAND]) {
// 级联展开 // 级联展开
expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1.LAY_DATA_INDEX + '"]').first()}, true); expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1[LAY_DATA_INDEX] + '"]').first()}, true);
} }
}) })
} else { } else {
var asyncSetting = treeOptions.async || {}; var asyncSetting = treeOptions.async || {};
var asyncUrl = asyncSetting.url || options.url; var asyncUrl = asyncSetting.url || options.url;
// 提供一个能支持用户在获取子数据转换调用的回调,这样让子节点数据获取更加灵活 todo // 提供一个能支持用户在获取子数据转换调用的回调,这样让子节点数据获取更加灵活 todo
if (asyncSetting.enable && asyncUrl && !trData['LAY_ASYNC_STATUS']) { if (asyncSetting.enable && trData[isParentKey] && asyncUrl && !trData[LAY_ASYNC_STATUS]) {
trData['LAY_ASYNC_STATUS'] = 'loading'; trData[LAY_ASYNC_STATUS] = 'loading';
var params = {}; var params = {};
// 参数 // 参数
var data = $.extend(params, asyncSetting.where || options.where); var data = $.extend(params, asyncSetting.where || options.where);
@ -485,22 +501,22 @@ layui.define(['table'], function (exports) {
// that.loading(); // that.loading();
flexIconElem.html('<i class="layui-icon layui-icon-loading layui-anim layui-anim-loop layui-anim-rotate"></i>') flexIconElem.html('<i class="layui-icon layui-icon-loading layui-anim layui-anim-loop layui-anim-rotate"></i>')
$.ajax({ $.ajax({
type: asyncType || 'get' type: asyncType || 'get',
, url: asyncUrl url: asyncUrl,
, contentType: asyncContentType contentType: asyncContentType,
, data: data data: data,
, dataType: asyncDataType || 'json' dataType: asyncDataType || 'json',
, jsonpCallback: asyncJsonpCallback jsonpCallback: asyncJsonpCallback,
, headers: asyncHeaders || {} headers: asyncHeaders || {},
, success: function (res) { success: function (res) {
trData['LAY_ASYNC_STATUS'] = 'success'; trData[LAY_ASYNC_STATUS] = 'success';
// 若有数据解析的回调,则获得其返回的数据 // 若有数据解析的回调,则获得其返回的数据
if (typeof asyncParseData === 'function') { if (typeof asyncParseData === 'function') {
res = asyncParseData.call(options, res) || res; res = asyncParseData.call(options, res) || res;
} }
// 检查数据格式是否符合规范 // 检查数据格式是否符合规范
if (res[asyncResponse.statusName] != asyncResponse.statusCode) { if (res[asyncResponse.statusName] != asyncResponse.statusCode) {
trData['LAY_ASYNC_STATUS'] = 'error'; trData[LAY_ASYNC_STATUS] = 'error';
// 异常处理 todo // 异常处理 todo
flexIconElem.html('<i class="layui-icon layui-icon-refresh"></i>'); flexIconElem.html('<i class="layui-icon layui-icon-refresh"></i>');
// 事件 // 事件
@ -510,9 +526,9 @@ layui.define(['table'], function (exports) {
// 正常返回 // 正常返回
expandNode(treeNode, true, isToggle ? false : sonSign, focus, callbackFlag); expandNode(treeNode, true, isToggle ? false : sonSign, focus, callbackFlag);
} }
} },
, error: function (e, msg) { error: function (e, msg) {
trData['LAY_ASYNC_STATUS'] = 'error'; trData[LAY_ASYNC_STATUS] = 'error';
// 异常处理 todo // 异常处理 todo
typeof options.error === 'function' && options.error(e, msg); typeof options.error === 'function' && options.error(e, msg);
} }
@ -571,7 +587,7 @@ layui.define(['table'], function (exports) {
if (sonSign && !isToggle) { // 非状态切换的情况下 if (sonSign && !isToggle) { // 非状态切换的情况下
// 级联展开/关闭子节点 // 级联展开/关闭子节点
layui.each(childNodes, function (i1, item1) { layui.each(childNodes, function (i1, item1) {
expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1.LAY_DATA_INDEX + '"]').first()}, expandFlag, sonSign, focus, callbackFlag); expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1[LAY_DATA_INDEX] + '"]').first()}, expandFlag, sonSign, focus, callbackFlag);
}) })
} }
} }
@ -581,22 +597,22 @@ layui.define(['table'], function (exports) {
// 折叠 // 折叠
if (sonSign && !isToggle) { // 非状态切换的情况下 if (sonSign && !isToggle) { // 非状态切换的情况下
layui.each(childNodes, function (i1, item1) { layui.each(childNodes, function (i1, item1) {
expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1.LAY_DATA_INDEX + '"]').first()}, expandFlag, sonSign, focus, callbackFlag); expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + item1[LAY_DATA_INDEX] + '"]').first()}, expandFlag, sonSign, focus, callbackFlag);
}); });
tableViewElem.find(childNodes.map(function (value, index, array) { // 只隐藏直接子节点,其他由递归的处理 tableViewElem.find(childNodes.map(function (value, index, array) { // 只隐藏直接子节点,其他由递归的处理
return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]' return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]'
}).join(',')).addClass('layui-hide'); }).join(',')).addClass(HIDE);
} else { } else {
var childNodesFlat = treeTableThat.treeToFlat(childNodes, trData[customName.id], trIndex); var childNodesFlat = treeTableThat.treeToFlat(childNodes, trData[customName.id], trIndex);
tableViewElem.find(childNodesFlat.map(function (value, index, array) { tableViewElem.find(childNodesFlat.map(function (value, index, array) {
return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]' return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]'
}).join(',')).addClass('layui-hide'); }).join(',')).addClass(HIDE);
} }
} }
table.resize(tableId); table.resize(tableId);
if (callbackFlag && trData['LAY_ASYNC_STATUS'] !== 'loading') { if (callbackFlag && trData[LAY_ASYNC_STATUS] !== 'loading') {
var onExpand = treeOptions.callback.onExpand; var onExpand = treeOptions.callback.onExpand;
layui.type(onExpand) === 'function' && onExpand(tableId, trData, expandFlag); layui.type(onExpand) === 'function' && onExpand(tableId, trData, expandFlag);
} }
@ -604,6 +620,16 @@ layui.define(['table'], function (exports) {
return retValue; return retValue;
} }
/**
* 展开或关闭一个节点
* @param {String} id 树表id
* @param {Object} opts
* @param {Number|String} opts.index 展开行的数据下标
* @param {Boolean} [opts.expandFlag] 展开关闭切换
* @param {Boolean} [opts.inherit] 是否级联子节点
* @param {Boolean} [opts.callbackFlag] 是否触发事件
* @return [{Boolean}] 状态结果
* */
treeTable.expandNode = function (id, opts) { treeTable.expandNode = function (id, opts) {
var that = getThisTable(id); var that = getThisTable(id);
if (!that) return; if (!that) return;
@ -615,13 +641,16 @@ layui.define(['table'], function (exports) {
var sonSign = opts.inherit; var sonSign = opts.inherit;
var callbackFlag = opts.callbackFlag; var callbackFlag = opts.callbackFlag;
var options = that.getOptions(); var options = that.getOptions();
var tableViewElem = options.elem.next(); var tableViewElem = options.elem.next();
return expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + index + '"]').first()}, expandFlag, sonSign, null, callbackFlag) return expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + index + '"]').first()}, expandFlag, sonSign, null, callbackFlag)
}; };
// 目前还有性能问题特别是在data模式需要优化暂时不能使用 todo /**
* 展开或关闭全部节点
* @param {String} id 树表id
* @param {Boolean} expandFlag 展开或关闭
* */
treeTable.expandAll = function (id, expandFlag) { treeTable.expandAll = function (id, expandFlag) {
if (layui.type(expandFlag) !== 'boolean') { if (layui.type(expandFlag) !== 'boolean') {
return hint.error('expandAll 的展开状态参数只接收true/false') return hint.error('expandAll 的展开状态参数只接收true/false')
@ -639,23 +668,41 @@ layui.define(['table'], function (exports) {
// 将所有已经打开的节点的状态设置为关闭, // 将所有已经打开的节点的状态设置为关闭,
that.updateStatus(null, {LAY_EXPAND: false}); // 只处理当前页如果需要处理全部表格需要用treeTable.updateStatus that.updateStatus(null, {LAY_EXPAND: false}); // 只处理当前页如果需要处理全部表格需要用treeTable.updateStatus
// 隐藏所有非顶层的节点 // 隐藏所有非顶层的节点
tableView.find('tbody tr[data-level!="0"]').addClass('layui-hide'); tableView.find('.layui-table-box tbody tr[data-level!="0"]').addClass(HIDE);
// 处理顶层节点的图标 // 处理顶层节点的图标
var trLevel0 = tableView.find('tbody tr[data-level="0"]'); var trLevel0 = tableView.find('tbody tr[data-level="0"]');
trLevel0.find('.layui-table-tree-flexIcon').html(treeOptions.view.flexIconClose); trLevel0.find('.layui-table-tree-flexIcon').html(treeOptions.view.flexIconClose);
trLevel0.find('.layui-table-tree-nodeIcon').html(treeOptions.view.iconClose); treeOptions.view.showIcon && trLevel0.find('.layui-table-tree-nodeIcon').html(treeOptions.view.iconClose);
treeTable.resize();
} else {
return hint.error('暂不支持展开全部');
// 展开所有
if (treeOptions.async.enable) {
// 存在异步加载
} else { } else {
// 先判断是否全部打开过了
var tableDataFlat = treeTable.getData(id, true); var tableDataFlat = treeTable.getData(id, true);
// 展开所有
// 存在异步加载
if (treeOptions.async.enable) {
// 判断是否有未加载过的节点
var isAllAsyncDone = true;
var isParentKey = treeOptions.customName.isParent;
layui.each(tableDataFlat, function (i1, item1) {
if (item1[isParentKey] && !item1[LAY_ASYNC_STATUS]) {
isAllAsyncDone = false;
return true;
}
})
// 有未加载过的节点
if (!isAllAsyncDone) {
// 逐个展开
layui.each(treeTable.getData(id), function (i1, item1) {
treeTable.expandNode(id, {
index: item1[LAY_DATA_INDEX],
expandFlag: true,
inherit: true
})
})
return;
}
}
// 先判断是否全部打开过了
var isAllExpanded = true; var isAllExpanded = true;
layui.each(tableDataFlat, function (i1, item1) { layui.each(tableDataFlat, function (i1, item1) {
if (!item1[LAY_HAS_EXPANDED]) { if (!item1[LAY_HAS_EXPANDED]) {
@ -665,36 +712,56 @@ layui.define(['table'], function (exports) {
}) })
// 如果全部节点已经都打开过,就可以简单处理跟隐藏所有节点反操作 // 如果全部节点已经都打开过,就可以简单处理跟隐藏所有节点反操作
if (isAllExpanded) { if (isAllExpanded) {
that.updateStatus(null, {LAY_EXPAND: true}); // 只处理当前页如果需要处理全部表格需要用treeTable.updateStatus that.updateStatus(null, {LAY_EXPAND: true});
// 隐藏所有非顶层的节点 // 隐藏所有非顶层的节点
tableView.find('tbody tr[data-level!="0"]').removeClass('layui-hide'); tableView.find('tbody tr[data-level!="0"]').removeClass(HIDE);
// 处理顶层节点的图标 // 处理顶层节点的图标
// var trLevel0 = tableView.find('tbody tr[data-level="0"]'); // var trLevel0 = tableView.find('tbody tr[data-level="0"]');
tableView.find('.layui-table-tree-flexIcon').html(treeOptions.view.flexIconOpen); tableView.find('.layui-table-tree-flexIcon').html(treeOptions.view.flexIconOpen);
tableView.find('.layui-table-tree-nodeIcon').html(treeOptions.view.iconOpen); tableView.find('.layui-table-tree-nodeIcon').html(treeOptions.view.iconOpen);
treeTable.resize();
} else { } else {
// 如果有未打开过的父节点,将内容全部生成 // 如果有未打开过的父节点,将内容全部生成
that.updateStatus(null, {LAY_EXPAND: true, LAY_HAS_EXPANDED: true}); that.updateStatus(null, {LAY_EXPAND: true, LAY_HAS_EXPANDED: true});
var trsAll = table.getTrHtml(id, tableDataFlat); var trAll = table.getTrHtml(id, tableDataFlat);
var trAllObj = {
trs: $(trAll.trs.join('')),
trs_fixed: $(trAll.trs_fixed.join('')),
trs_fixed_r: $(trAll.trs_fixed_r.join(''))
} }
layui.each(tableDataFlat, function (dataIndex, dataItem) {
// debugger;
var dataLevel = dataItem[LAY_DATA_INDEX].split('-').length - 1;
trAllObj.trs.eq(dataIndex).attr({
'data-index': dataItem[LAY_DATA_INDEX],
'lay-data-index': dataItem[LAY_DATA_INDEX],
'data-level': dataLevel
})
trAllObj.trs_fixed.eq(dataIndex).attr({
'data-index': dataItem[LAY_DATA_INDEX],
'lay-data-index': dataItem[LAY_DATA_INDEX],
'data-level': dataLevel
})
trAllObj.trs_fixed_r.eq(dataIndex).attr({
'data-index': dataItem[LAY_DATA_INDEX],
'lay-data-index': dataItem[LAY_DATA_INDEX],
'data-level': dataLevel
})
})
layui.each(['main', 'fixed-l', 'fixed-r'], function (i, item) {
tableView.find('.layui-table-' + item + ' tbody').html(trAllObj[['trs', 'trs_fixed', 'trs_fixed_r'][i]]);
});
that.renderTreeTable(tableView, 0, false);
} }
// 如果是异步加载子节点模式 如何处理
// 如果有部分节点未打开过,也需要重新
} }
treeTable.resize(id);
} }
Class.prototype.renderTreeTable = function (tableView, level, sonSign) { Class.prototype.renderTreeTable = function (tableView, level, sonSign) {
var that = this; var that = this;
var options = that.getOptions(); var options = that.getOptions();
var tableViewElem = options.elem.next(); var tableViewElem = options.elem.next();
tableViewElem.addClass('layui-table-tree'); tableViewElem.addClass(TABLE_TREE);
var tableId = options.id; var tableId = options.id;
var treeOptions = options.tree || {}; var treeOptions = options.tree || {};
var treeOptionsData = treeOptions.data || {}; var treeOptionsData = treeOptions.data || {};
@ -744,10 +811,10 @@ layui.define(['table'], function (exports) {
var flexIconElem = item.find('div.layui-table-cell') var flexIconElem = item.find('div.layui-table-cell')
.html(['<div class="layui-inline layui-table-tree-flexIcon" ', .html(['<div class="layui-inline layui-table-tree-flexIcon" ',
'style="', 'style="',
'margin-left: ' + (indent * level) + 'px;', 'margin-left: ' + (indent * trElem.attr('data-level')) + 'px;',
(trData[isParentKey] || treeOptionsView.showFlexIconIfNotParent) ? '' : ' visibility: hidden;', (trData[isParentKey] || treeOptionsView.showFlexIconIfNotParent) ? '' : ' visibility: hidden;',
'">', '">',
treeOptions.view.flexIconClose, // 折叠图标 trData[LAY_EXPAND] ? treeOptions.view.flexIconOpen : treeOptions.view.flexIconClose, // 折叠图标
'</div>', '</div>',
'<div class="layui-inline layui-table-tree-nodeIcon">', '<div class="layui-inline layui-table-tree-nodeIcon">',
treeOptions.view.showIcon ? (trData.icon || treeOptions.view.icon || (trData[isParentKey] ? treeOptions.view.iconClose : treeOptions.view.iconLeaf) || '') : '', treeOptions.view.showIcon ? (trData.icon || treeOptions.view.icon || (trData[isParentKey] ? treeOptions.view.iconClose : treeOptions.view.iconLeaf) || '') : '',
@ -771,33 +838,31 @@ layui.define(['table'], function (exports) {
expandNode({trElem: trDefaultExpand.first()}, true); expandNode({trElem: trDefaultExpand.first()}, true);
}); });
treeTable.formatNumber(tableId); options.hasNumberCol && that.formatNumber(tableId);
form.render(null, tableFilterId); form.render(null, tableFilterId);
} }
var formatNumber = function (that) {
/**
* 重新编号
* @param {String} id 表格id
* @return {Object} layui.treeTable
* */
treeTable.formatNumber = function (id) {
var that = getThisTable(id);
if(!that) return;
var options = that.getOptions(); var options = that.getOptions();
var tableViewElem = options.elem.next(); var tableViewElem = options.elem.next();
var num = 0; var num = 0;
layui.each(that.treeToFlat(table.cache[id]), function (i1, item1) { layui.each(that.treeToFlat(table.cache[options.id]), function (i1, item1) {
if (layui.isArray(item1)) { if (layui.isArray(item1)) {
return; return;
} }
var itemData = that.getNodeDataByIndex(item1.LAY_DATA_INDEX); var itemData = that.getNodeDataByIndex(item1[LAY_DATA_INDEX]);
itemData['LAY_NUM'] = ++num; itemData['LAY_NUM'] = ++num;
tableViewElem.find('tr[lay-data-index="' + item1.LAY_DATA_INDEX + '"] .laytable-cell-numbers').html(itemData['LAY_NUM']); tableViewElem.find('tr[lay-data-index="' + item1[LAY_DATA_INDEX] + '"] .laytable-cell-numbers').html(itemData['LAY_NUM']);
}) })
return treeTable; }
Class.prototype.formatNumber = function (id) {
var that = this;
clearTimeout(id);
timer[id] = setTimeout(function () {
formatNumber(that);
}, 10)
} }
// 树表渲染 // 树表渲染
@ -819,6 +884,9 @@ layui.define(['table'], function (exports) {
if (layui.type(item) === 'array') delete that.config[key]; if (layui.type(item) === 'array') delete that.config[key];
}); });
// 根据需要处理options中的一些参数
updateOptions(that.config.id, options, true);
// 对参数进行深度或浅扩展 // 对参数进行深度或浅扩展
that.config = $.extend(deep, {}, that.config, options); that.config = $.extend(deep, {}, that.config, options);
@ -919,6 +987,7 @@ layui.define(['table'], function (exports) {
var args = arguments; var args = arguments;
$.extend(tableThat.getNodeDataByIndex(trIndex), args[0]); $.extend(tableThat.getNodeDataByIndex(trIndex), args[0]);
var ret = updateFn.apply(updateThat, args); // 主要负责更新节点内容 var ret = updateFn.apply(updateThat, args); // 主要负责更新节点内容
obj.tr.find('td[data-field="' + obj.config.tree.customName.name + '"]').children('div.layui-table-cell').removeClass('layui-table-tree-item');
tableThat.renderTreeTable(obj.tr, obj.tr.attr('data-level'), false); tableThat.renderTreeTable(obj.tr, obj.tr.attr('data-level'), false);
return ret; return ret;
} }
@ -961,6 +1030,7 @@ layui.define(['table'], function (exports) {
tableView.find('.layui-table-' + item + ' tbody tr[lay-data-index="' + index + '"]').replaceWith($(trNew[['trs', 'trs_fixed', 'trs_fixed_r'][i]].join('')).attr({ tableView.find('.layui-table-' + item + ' tbody tr[lay-data-index="' + index + '"]').replaceWith($(trNew[['trs', 'trs_fixed', 'trs_fixed_r'][i]].join('')).attr({
'data-index': trIndex, 'data-index': trIndex,
'lay-data-index': index, 'lay-data-index': index,
'data-level': trLevel
})); }));
}); });
that.renderTreeTable(tableView.find('tr[lay-data-index="' + index + '"]'), trLevel); that.renderTreeTable(tableView.find('tr[lay-data-index="' + index + '"]'), trLevel);
@ -1001,16 +1071,17 @@ layui.define(['table'], function (exports) {
layui.each(table.cache[id], function (i4, item4) { layui.each(table.cache[id], function (i4, item4) {
tableView.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]').attr('data-index', i4); tableView.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]').attr('data-index', i4);
}) })
treeTable.formatNumber(id); options.hasNumberCol && that.formatNumber(id);
} }
/** /**
* 新增数据节点 * 新增数据节点
* @param {String} id 树表id * @param {String} id 树表id
* @param {String|Number} parentIndex 指定的父节点如果增加根节点请设置 parentIndex null 即可 * @param {Object} opts
* @param {Number} index:Number 新节点插入的位置 0 开始index = -1(默认) 插入到最后 * @param {String|Number} opts.parentIndex 指定的父节点如果增加根节点请设置 parentIndex null 即可
* @param {Object|Array} data 新增的节点单个或者多个 * @param {Number} opts.index 新节点插入的位置 0 开始index = -1(默认) 插入到最后
* @param {Boolean} focus 新增的节点单个或者多个 * @param {Object|Array} opts.data 新增的节点单个或者多个
* @param {Boolean} opts.focus 新增的节点单个或者多个
* @return {Array} 新增的节点 * @return {Array} 新增的节点
* */ * */
treeTable.addNodes = function (id, opts) { treeTable.addNodes = function (id, opts) {
@ -1134,7 +1205,7 @@ layui.define(['table'], function (exports) {
tableData = that.initData(); tableData = that.initData();
// 去掉父节点的已经展开过的状态,重新执行一次展开的方法 // 去掉父节点的已经展开过的状态,重新执行一次展开的方法
parentNode[LAY_HAS_EXPANDED] = false; parentNode[LAY_HAS_EXPANDED] = false;
parentNode['LAY_ASYNC_STATUS'] = 'local'; // 转为本地数据应该规定异步加载子节点的时候addNodes的规则 parentNode[LAY_ASYNC_STATUS] = 'local'; // 转为本地数据应该规定异步加载子节点的时候addNodes的规则
expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + parentIndex + '"]')}, true) expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + parentIndex + '"]')}, true)
} }
that.updateCheckStatus(parentNode, true); that.updateCheckStatus(parentNode, true);
@ -1177,7 +1248,7 @@ layui.define(['table'], function (exports) {
var tableView = options.elem.next(); var tableView = options.elem.next();
var tableId = options.id; var tableId = options.id;
if (tableView.hasClass('layui-table-tree')) { if (tableView.hasClass(TABLE_TREE)) {
treeTable.sort(tableId); treeTable.sort(tableId);
} }
}); });
@ -1187,7 +1258,7 @@ layui.define(['table'], function (exports) {
var options = obj.config; var options = obj.config;
var tableView = options.elem.next(); var tableView = options.elem.next();
if (tableView.hasClass('layui-table-tree')) { if (tableView.hasClass(TABLE_TREE)) {
updateObjParams(obj); updateObjParams(obj);
} }
}) })
@ -1198,7 +1269,7 @@ layui.define(['table'], function (exports) {
var tableView = options.elem.next(); var tableView = options.elem.next();
var tableId = options.id; var tableId = options.id;
if (tableView.hasClass('layui-table-tree')) { if (tableView.hasClass(TABLE_TREE)) {
updateObjParams(obj); updateObjParams(obj);
var treeOptions = options.tree || {}; var treeOptions = options.tree || {};
@ -1208,13 +1279,24 @@ layui.define(['table'], function (exports) {
} }
}) })
// 菜单
treeTable.on('rowContextmenu', function (obj) {
var options = obj.config;
var tableView = options.elem.next();
var tableId = options.id;
if (tableView.hasClass(TABLE_TREE)) {
updateObjParams(obj);
}
})
// tr中带lay-event节点点击 // tr中带lay-event节点点击
treeTable.on('tool', function (obj) { treeTable.on('tool', function (obj) {
var options = obj.config; var options = obj.config;
var tableView = options.elem.next(); var tableView = options.elem.next();
var tableId = options.id; var tableId = options.id;
if (tableView.hasClass('layui-table-tree')) { if (tableView.hasClass(TABLE_TREE)) {
updateObjParams(obj); updateObjParams(obj);
} }
}) })
@ -1226,10 +1308,9 @@ layui.define(['table'], function (exports) {
var tableView = options.elem.next(); var tableView = options.elem.next();
var tableId = options.id; var tableId = options.id;
if (tableView.hasClass('layui-table-tree')) { if (tableView.hasClass(TABLE_TREE)) {
updateObjParams(obj); updateObjParams(obj);
if (obj.field === options.tree.customName.name) { if (obj.field === options.tree.customName.name) {
obj.tr.find('td[data-field="' + obj.field + '"]').children('div.layui-table-cell').removeClass('layui-table-tree-item')
obj.update({}); // 通过update调用执行tr节点的更新 obj.update({}); // 通过update调用执行tr节点的更新
} }
} }
@ -1240,9 +1321,9 @@ layui.define(['table'], function (exports) {
var options = obj.config; var options = obj.config;
var tableView = options.elem.next(); var tableView = options.elem.next();
var tableId = options.id; var tableId = options.id;
var that = getThisTable(tableId);
if (tableView.hasClass('layui-table-tree')) { if (tableView.hasClass(TABLE_TREE)) {
var that = getThisTable(tableId);
updateObjParams(obj); updateObjParams(obj);
checkNode.call(that, obj.tr, obj.checked) checkNode.call(that, obj.tr, obj.checked)
} }
@ -1422,7 +1503,7 @@ layui.define(['table'], function (exports) {
var tableView = options.elem.next(); var tableView = options.elem.next();
var tableId = options.id; var tableId = options.id;
if (tableView.hasClass('layui-table-tree')) { if (tableView.hasClass(TABLE_TREE)) {
var that = getThisTable(tableId); var that = getThisTable(tableId);
var checked = obj.checked; var checked = obj.checked;
updateObjParams(obj) updateObjParams(obj)
@ -1484,7 +1565,7 @@ layui.define(['table'], function (exports) {
/** /**
* 获得数据 * 获得数据
* @param {String} id 表格id * @param {String} id 表格id
* @param {Boolean} isSimpleData 是否返回平铺结构的数据 * @param {Boolean} [isSimpleData] 是否返回平铺结构的数据
* @return {Array} 表格数据 * @return {Array} 表格数据
* */ * */
treeTable.getData = function (id, isSimpleData) { treeTable.getData = function (id, isSimpleData) {