bootstrap table 父子表实现【无限级】菜单管理功能
实现效果
前端代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%@include file="/WEB-INF/include/tags.jsp" %>
<!DOCTYPE HTML>
<html>
<head>
<!-- 引入jquery插件 -->
<script src="/jquery/jquery-2.1.1.min.js" type="text/javascript"></script>
<!-- 引入bootstrap插件 -->
<script src="/bootstrap/3.3.4/js/bootstrap.min.js" type="text/javascript"></script>
<link href="/bootstrap/3.3.4/css_default/bootstrap.min.css" type="text/css" rel="stylesheet"/>
<!-- 引入bootstrap-table 语言包 -->
<script src="/bootstrap/table/bootstrap-table-zh-CN.min.js"></script>
<!-- 引入bootstrap-table插件 -->
<script src="/bootstrap/table/bootstrap-table.min.js"></script>
<link href="/bootstrap/table/bootstrap-table.min.css" rel="stylesheet">
<style>
.child-table thead {
//隐藏子表的表头
/*display: none !important;*/
}
</style>
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content">
<p class="tit">菜单列表</p>
<div class="ibox">
<div class="ibox-content">
<table id="mytab" class="table table-hover"></table>
</div>
</div>
</div>
<script type="text/javascript">
//菜单的根id
var mRootId = '0';
$(function () {
//初始化表格数据 传递menu的rootid
createTable(mRootId);
})
//详情递归使用初始化表格方法 pid 菜单的父级id tableObj 当前生成的table所绑定的对象
function createTable(pid, tableObj) {
var isSearch = false;
if (!tableObj) {
tableObj = "#mytab";
isSearch = true;
}
//根据窗口调整表格高度
$(window).resize(function () {
$(tableObj).bootstrapTable('resetView', {
height: tableHeight()
})
})
$(tableObj).bootstrapTable({
url: "${ctx}/",//数据源 后台Controller的数据
dataField: "dataList",//服务端返回数据键值 就是说记录放的键值是rows,分页时使用总记录数的键值为total
// height: tableHeight(),//高度调整
search: isSearch,//是否搜索
pagination: false,//是否分页
contentType: "application/x-www-form-urlencoded",//请求数据内容格式 默认是 application/json 自己根据格式自行服务端处理
dataType: "json",//返回数据类型
method: "post",//请求方式
searchAlign: "left",//查询框对齐方式
queryParamsType: "limit",//查询参数组织方式
queryParams: function getParams(params) {
//params obj 其他参数 除了自身传递的参数外,可以由开发者自身设置传递
params.other = "otherInfo";
params.author = 'upuptop';
params.pid = pid
return params;
},
searchOnEnterKey: false,//回车搜索
showRefresh: isSearch,//刷新按钮
showColumns: false,//列选择按钮
buttonsAlign: "right",//按钮对齐方式
toolbarAlign: "right",//工具栏对齐方式
columns: [
{
title: "菜单名称",//标题
field: "name",//键名 与上方dataList里面存放的键值相对应 dataList['name':"菜单名称"]
sortable: true,//是否可排序
align: "center",//水平
order: "desc"//默认排序方式
},
{
title: "链接",
align: "center",//水平
field: "href",
sortable: true,
},
// {
// title: "权限",
// field: "permission",
// sortable: true,
// align: "center",//水平
// width: "20%",
// },
{
title: "排序值",
field: "sort",
align: "center",//水平
sortable: true,
},
{
title: "是否显示",
field: "isShow",
align: "center",//水平
sortable: true,
},
{
title: "操作",
field: "operation",
align: "center",//水平
sortable: true,
},
],
locale: "zh-CN", //中文支持
detailView: true, //是否显示详情折叠
detailFormatter: function (index, row, element) {
// 详情折叠 内容
// return '<p>这里显示详情</p>'
},
responseHandler: function (res) {
//请求返回数据成功会调用该方法/填充表格数据之前会调用这个方法
$.each(res.menuList, function (index, item) {
if (item.isShow == 1) {
item.isShow = "显示";
} else {
item.isShow = "隐藏";
}
var tempHtml = '<a title="修改" "openDialog2(\'修改菜单\',\'${ctx}//form?id=' + item.id + '\',\'800px\',\'550px\',\'' + item.pid + '\')" style="color: #4a93ff">修改</a>';
tempHtml += ' | ';
tempHtml += '<a title="添加下一级菜单" "openDialog2(\'添加菜单\',\'${ctx}//form?pid=' + item.id + '\',\'800px\',\'550px\',\'' + item.pid + '\')" style="color: #4a93ff">添加下一级菜单</a>';
tempHtml += ' | ';
tempHtml += '<a title="删除" style="color: red" "delConfirmx(\'' + item.id + '\',\'' + item.pid + '\',\'' + item.name + '\')">删除</a>';
item.operation = tempHtml;
})
return res;
},
onClickRow: function (row, $element) {
//$element是当前tr的jquery对象
//单击row事件
},
onExpandRow: function (index, row, $detail) {
//点击左侧的加号 展开查看详情的时候调用 在这里做了递归调用自身再次构建一张表 这里的child-table-row.id是为了修改或者删除,刷新子表使用
createTable(row.id, $detail.html('<table class="child-table child-table-' + row.id + '" style=""></table>').find('table'));
},
onLoadSuccess: function (data) {
},
detailFilter: function (index, row) {
//是否展开详情的过滤方法 可以通过逻辑进行设置是否可以展开查看详情
if (!row.childCount) {
return false;
}
return true;
}
});
}
// 删除确认框
function delConfirmx(id, pid, name) {
top.layer.confirm('是否删除菜单【' + name + '】?', {
btn: ['确定', '取消'] //按钮 .bootstrapTable('refresh')
}, function (index) {
var tableObj;
if (pid != mRootId) {
tableObj = $(".child-table-" + pid);
} else {
tableObj = $("#mytab");
}
$.get("${ctx}/deleteData?id=" + id, function (res) {
top.layer.msg("删除成功");
tableObj.bootstrapTable("refresh");
})
}, function (index) {
top.layer.close(index);
});
}
//添加修改对话框
function openDialog2(title, url, width, height, pid) {
console.log(pid);
console.log($(".child-table-" + pid));
if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端,就使用自适应大小弹窗
width = 'auto';
height = 'auto';
} else {//如果是PC端,根据用户设置的width和height显示。
}
top.layer.open({
type: 2,
area: [width, height],
title: title,
maxmin: true, //开启最大化最小化按钮
content: url,
// btn: ['确定', '关闭'],
// yes: function (index, layero) {
// },
end: function (index) {
if (pid != mRootId) {
$(".child-table-" + pid).bootstrapTable('refresh');
} else {
$("#mytab").bootstrapTable('refresh');
// window.location.reload()
}
}
});
}
//设置表格的高度
function tableHeight() {
// return $(window).height() - 50;
var height = $(window).height() - 120;
//当表格内容的高度小于外面容器的高度,容器的高度设置为内容的高度,相反时容器设置为窗口的高度-160
if ($(".fixed-table-body table").height() < $(".fixed-table-container").height()) {
$(".fixed-table-container").css({"padding-bottom": "0px", height: $(".fixed-table-body table").height() + 20});
// 是当内容少时,使用搜索功能高度保持不变
height = "auto";
} else {
height = $(window).height() - 160;
}
return height;
}
</script>
</body>
</html>
上方代码需要修改的地方:
<head>
标签中所有的引用需要修改。 推荐cdn:https://www.bootcdn.cn/- 数据源 需要修改为自身服务端的请求地址
服务端代码:
@RequestMapping("/")
@ResponseBody
public Map<String, Object> menuData(String pid, String search, String order, Integer offset, Integer limit) {
logger.info(" menuData() pid " + pid);
logger.info(" menuData() search " + search);
logger.info(" menuData() order " + order);
logger.info(" menuData() offset " + offset);
logger.info(" menuData() limit " + limit);
Map<String, Object> resultMap = new HashMap<>();
List<Menu> menuList = menuService.selectAllMenuByPid(pid, null);
resultMap.put("menuList", menuList);
return resultMap;
}
参考地址:
官方示例程序:https://examples.bootstrap-table.com/#welcomes/sub-table.html
博客API翻译:https://blog.csdn.net/S_clifftop/article/details/77937356
博客API翻译:https://blog.csdn.net/rickiyeat/article/details/56483577