2.8.6
请问下treeTable
能否对现有的树形表数据进行搜索并显示搜索结果在树形表中(非异步搜索服务端数据,仅对已加载的树形表中的数据进行搜索显示。应用场景:几百上千个菜单一次加载形成树形表进行搜索显示)
看了文档,可以通过 treeTable.getNodesByFilter
方法来获得想要的返回数据集,但这里获得了返回的搜索结果数据集后,不知道怎么显示到树形表中。
var data = treeTable.getNodesByFilter('menus', function(item){
return item.menu_name.indexOf(keywords) > -1;
});
我承诺将本着相互尊重、理解和友善的态度进行交流,共同维护 Layui 良好的社区氛围。
本地搜索的话有两种思路你试试看:
1、先把行记录全部隐藏,然后遍历数据找到符合的条件的行记录然后将他们显示回来,如果是树表,还要注意把他们的父行和祖辈给显示回来。这样做基本上就是一些隐藏和显示。
2、2.8.6 新增了一个方法,table.renderData, treeTable 也同样有这个方法,它的作用就是将表格的 cache 信息重新渲染,我觉得可以利用这个方法来实现你目前的需求,实际就是将 cache 过滤一下,然后重新 renderData 即可,但是也要注意如何恢复,目前没有对数据是否 hide 进行解析如果有的话就更方便只要处理 hide 信息即可。我本地写的了一个数移动的,你可以试试看有没有可以参考的
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>测试 table.renderData </title>
<!-- <link href="src/css/layui.css" rel="stylesheet">-->
<link href="//unpkg.com/layui@2.8.6/dist/css/layui.css" rel="stylesheet">
<style>
html body {
padding: 10px;
}
.layui-table-click {
background-color: #ffb800;
}
</style>
</head>
<body>
<table id="table1"></table>
<hr>
<table id="table2"></table>
<script type="text/html" id="barDemo">
<a class="layui-icon layui-icon-up" lay-event="move" data-direction="up"></a>
<a class="layui-icon layui-icon-down" lay-event="move" data-direction="down"></a>
</script>
<!--<script src="src/layui.js"></script>-->
<script src="//unpkg.com/layui@2.8.6/dist/layui.js"></script>
<script>
layui.use(['table'], function (table) {
var $ = layui.jquery;
table.render({
elem: "#table1",
toolbar: '<div><b>表格1,data模式</b></div>',
data: [
{
"id": "10001",
"username": "杜甫123",
"email": "test1@email.com",
"sex": "<strong style=\"color: red\">男</strong>",
"city": "浙江杭州",
"sign": "舍南舍北皆春水,但见群鸥日日来。花径不曾缘客扫,蓬门今始为君开。盘飧市远无兼味,樽酒家贫只旧醅。肯与邻翁相对饮,隔篱呼取尽余杯。",
"experience": 7,
"ip": "192.168.0.8",
"checkin": 0,
"joinTime": "2016-10-14",
"LAY_DISABLED": true
},
{
"id": "10002",
"username": "李白",
"email": "test2@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "君不见,黄河之水天上来,奔流到海不复回。 君不见,高堂明镜悲白发,朝如青丝暮成雪。 人生得意须尽欢,莫使金樽空对月。 天生我材必有用,千金散尽还复来。 烹羊宰牛且为乐,会须一饮三百杯。 岑夫子,丹丘生,将进酒,杯莫停。 与君歌一曲,请君为我倾耳听。(倾耳听 一作:侧耳听) 钟鼓馔玉不足贵,但愿长醉不复醒。(不足贵 一作:何足贵;不复醒 一作:不愿醒/不用醒) 古来圣贤皆寂寞,惟有饮者留其名。(古来 一作:自古;惟 通:唯) 陈王昔时宴平乐,斗酒十千恣欢谑。 主人何为言少钱,径须沽取对君酌。 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。",
"experience": 9,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14",
"LAY_CHECKED": true
},
{
"id": "10003",
"username": "苏轼",
"email": "test3@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。人生如梦,一尊还酹江月。",
"experience": 8,
"ip": "192.168.0.8",
"checkin": null,
"joinTime": "2016-10-14"
},
{
"id": "10004",
"username": "李清照",
"email": "test4@email.com",
"sex": "女",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 6,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
},
{
"id": "10005",
"username": "冰心",
"email": "test5@email.com",
"sex": "女",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 64,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
},
{
"id": "10006",
"username": "张三",
"email": "test6@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 65,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
},
{
"id": "10007",
"username": "张三7",
"email": "test7@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 49,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
},
{
"id": "10008",
"username": "张三8",
"email": "test8@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 5,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
},
{
"id": "10009",
"username": "张三9",
"email": "test9@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 5,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
},
{
"id": "10010",
"username": "张三10",
"email": "test10@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 5,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
},
{
"id": "10011",
"username": "张三11",
"email": "test11@email.com",
"sex": "男",
"city": "浙江杭州",
"sign": "人生恰似一场修行",
"experience": 5,
"ip": "192.168.0.8",
"checkin": "106",
"joinTime": "2016-10-14"
}
],
cols: [[
{field: 'id', hide: true}
, {type: 'numbers'}
, {field: 'username', title: '用户名'}
, {field: 'email', title: '邮箱'}
, {field: 'joinTime', title: '日期'}
, {field: 'experience', title: '积分', totalRow: true}
, {field: 'checkin', title: '迁入', totalRow: true}
, {title: '操作', align: 'center', toolbar: '#barDemo'}
]],
page: true,
totalRow: true,
done: function (res, curr, count) {
var tableView = this.elem.next();
tableView.find('tr[data-index="0"] .layui-icon[lay-event="move"][data-direction="up"]').addClass('layui-disabled');
tableView.find('tr[data-index="' + (res.data.length - 1) + '"] .layui-icon[lay-event="move"][data-direction="down"]').addClass('layui-disabled');
}
});
table.render({
elem: '#table2'
, url: 'examples/json/table/demo1.json'
, toolbar: '<div><b>表格2,url模式</b></div>'
, page: {
limit: 10
}
, scrollPos: 'fixed'
, totalRow: true
, maxHeight: 480
, cellMinWidth: 80
, cols: [[
{field: 'id', hide: true}
, {type: 'numbers'}
, {field: 'username', title: '用户名'}
, {field: 'email', title: '邮箱'}
, {field: 'joinTime', title: '日期'}
, {field: 'experience', title: '积分', totalRow: true}
, {field: 'checkin', title: '迁入', totalRow: true}
, {title: '操作', align: 'center', toolbar: '#barDemo'}
]]
, done: function (res, curr, count) {
var tableView = this.elem.next();
tableView.find('tr[data-index="0"] .layui-icon[lay-event="move"][data-direction="up"]').addClass('layui-disabled');
tableView.find('tr[data-index="' + (res.data.length - 1) + '"] .layui-icon[lay-event="move"][data-direction="down"]').addClass('layui-disabled');
}
});
table.on('tool', function (obj) {
var btnElem = $(this);
var tableId = obj.config.id;
var dataCache = table.cache[tableId];
var dataIndex = obj.index;
var btnEvent = obj.event;
switch (btnEvent) {
case 'move':
if (btnElem.hasClass('layui-disabled')) {
return;
}
var direction = btnElem.data('direction');
var dataMove = dataCache.splice(dataIndex, 1);
var indexNew = dataIndex + (direction === 'up' ? -1 : 1);
dataCache.splice(indexNew, 0, dataMove[0]);
table.renderData(tableId);
setTimeout(function () {
table.setRowChecked(tableId, {
index: indexNew,
selectedStyle: true
})
}, 0);
break;
default:
break;
}
})
});
</script>
</body>
</html>
好的,多谢指教,我试下
这边尝试了下改缓存再渲染的形式,有点不大好去过滤树形数组。
采用隐藏行的形式,基本能实现,代码如下:
$('#btnSearch').click(function(){
var keywords = $('#keywords').val(), tableId = 'menus';
if(keywords){
treeTable.expandAll(tableId,true);
var $trList = menusTree.config.elem.next().find('.layui-table-main table tbody').children('tr');
$trList.addClass('layui-hide');
var soList = [];
$trList.each(function(){
var $this = $(this), index = $this.data('index'), flag = false;
$this.children('td').each(function(){
if($(this).text().indexOf(keywords) !== -1){
soList.push(index);
return flag = true;
}
});
if (flag) $this.removeClass('layui-hide');
});
for (var j = 0; j < soList.length; j++) {
var $tr = $trList.filter('[data-index="' + soList[j] + '"]');
$tr.removeClass('layui-hide');
var level = parseInt($tr.data('level'));
// 联动子级
$tr.nextAll('tr').each(function () {
if (parseInt($(this).data('level')) <= level) return false;
$(this).removeClass('layui-hide');
});
var $icon = $tr.find('.layui-table-tree-flexIcon i.layui-icon');
if ($icon.hasClass('layui-icon-triangle-d')) treeTable.expandNode(tableId,{index:soList[j],expandFlag:false});
// 联动父级
$tr.prevAll('tr').each(function () {
var num = parseInt($(this).data('level'));
if (num < level) {
$(this).removeClass('layui-hide');
var $icon = $(this).find('.layui-table-tree-flexIcon i.layui-icon');
if ($icon.hasClass('layui-icon-triangle-r')) $icon.removeClass('layui-icon-triangle-r').addClass('layui-icon-triangle-d');
level = num;
}
});
}
}else{
treeTable.renderData(tableId);
}
});
但是这里有个问题,搜索后显示的结果,再调用展开方法时,隐藏的无需行也显示了出来。
期待官方在后期版本中能有更好的搜索解决方案!
有一个思路你试试看:将根据关键字搜索表格的处理提取出来封装成一个方法,在input修改的时候调用,在table的done中也要去调用一下,根据已有的关键词去做一下处理,然后展开的回调也要去处理一下,这样应该就可以做到想要“过滤”的效果
嗯嗯。我这边刚仔细参照了下,对上面代码作了调整,基本上是可以的了。
layui-hide
来控制以区分expandAll
方法引起的隐藏或显示<style>.treeTable-filter-hide{display:none !important;}</style>
$('#btnSearch').click(function(){
var keywords = $('#keywords').val(), tableId = 'menus';
if(keywords){
// 这里全部展开是为了将所有的子类行 html 化,便于下面遍历搜索
treeTable.expandAll(tableId,true);
// 再全部收起,防止在搜索的子类过多情况下,全展开不便查看
treeTable.expandAll(tableId,false);
var $trList = menusTree.config.elem.next().find('.layui-table-main table tbody').children('tr');
$trList.addClass('treeTable-filter-hide');
var soList = [];
$trList.each(function(){
var $this = $(this), index = $this.data('index');
$this.children('td').each(function(){
if($(this).text().indexOf(keywords) !== -1){
soList.push(index);
return false;
}
});
});
for (var j = 0; j < soList.length; j++) {
var $tr = $trList.filter('[data-index="' + soList[j] + '"]');
$tr.removeClass('treeTable-filter-hide');
var level = parseInt($tr.data('level'));
// 联动子级
$tr.nextAll('tr').each(function () {
if (parseInt($(this).data('level')) <= level) return false;
$(this).removeClass('treeTable-filter-hide');
});
var $icon = $tr.find('.layui-table-tree-flexIcon i.layui-icon');
if ($icon.hasClass('layui-icon-triangle-d')) treeTable.expandNode(tableId,{index:soList[j],expandFlag:false});
// 联动父级
$tr.prevAll('tr').each(function () {
var num = parseInt($(this).data('level'));
if (num < level) {
$(this).removeClass('treeTable-filter-hide');
var index = $(this).data('index');
var $icon = $(this).find('.layui-table-tree-flexIcon i.layui-icon');
if ($icon.hasClass('layui-icon-triangle-r')) treeTable.expandNode(tableId,{index:index,expandFlag:true});
level = num;
}
});
}/**/
}else{
treeTable.renderData(tableId);
}
});
以上基本能实现了,还是希望官方能整理下把搜索的方法封装进去。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
登录 后才可以发表评论