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 += '&nbsp;|&nbsp;';
tempHtml += '<a title="添加下一级菜单" "openDialog2(\'添加菜单\',\'${ctx}//form?pid=' + item.id + '\',\'800px\',\'550px\',\'' + item.pid + '\')" style="color: #4a93ff">添加下一级菜单</a>';
tempHtml += '&nbsp;|&nbsp;';
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

bootstrap table 父子表实现【无限级】菜单管理功能的更多相关文章

  1. 我的第一个python web开发框架(36)——后台菜单管理功能

    对于后台管理系统来说,要做好权限管理离不开菜单项和页面按钮控件功能的管理.由于程序没法智能的知道有什么菜单和控件,哪些人拥有哪些操作权限,所以首先要做的是菜单管理功能,将需要管理的菜单项和各个功能项添 ...

  2. Swoole 中使用 Table 内存表实现进程间共享数据

    背景 在多进程模式下进程之间的内存是相互隔离的,在一个工作进程中的全局变量和超全局变量,在另一个工作进程中是无法读取和操作的. 如果只有一个工作进程,则不存在进程隔离问题,可以使用全局变量和超全局变量 ...

  3. ABP+AdminLTE+Bootstrap Table权限管理系统第十节--AdminLTE模板菜单处理

    上节我们把布局页,也有的临时的菜单,但是菜单不是应该动态加载的么?,所以我们这节来写菜单.首先我们看一下AdminLTE源码里面的菜单以及结构. <aside class="main- ...

  4. Bootstrap table 实现树形表格,实现联动选中,联动取消

    公司最近有需求要做树形式table.因为是前后端不分离项目,且之前已经引入了bootstrap table插件,现把实现方式分享一下: <!DOCTYPE HTML> <html l ...

  5. Xianfeng轻量级Java中间件平台:菜单管理

    通过菜单管理,可以实现系统菜单的权限控制.用户个性化菜单功能等,当然很多系统支持在线开发,不用专门的开发工具编写代码,通过一些简单的设置就能开发出新的功能,有新功能增加到系统中,菜单管理功能也是必不可 ...

  6. JS组件系列——Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案

    前言:最近项目里面需要用到表格的冻结列功能,所谓“冻结列”,就是某些情况下表格的列比较多,需要固定前面的几列,后面的列滚动.遗憾的是,bootstrap table里自带的fixed column功能 ...

  7. 开源 java CMS - FreeCMS2.2 菜单管理

    项目地址:http://www.freeteam.cn/ 菜单管理 FreeCMS在设计时定位于面向二次开发友好,所以FreeCMS提供了菜单管理功能.二次开发者能够自由添加新的功能菜单到FreeCM ...

  8. django项目后台权限管理功能。

    对后台管理员进行分角色,分类别管理,每个管理员登录账号后只显示自己负责的权限范围. 创建后台管理数据库 models.py文件内 # 管理员表 class Superuser(models.Model ...

  9. ABP+AdminLTE+Bootstrap Table权限管理系统第十一节--bootstrap table之用户管理列表

    这张开始bootstrap table,引入项目有两种方法,一种是直接去官网下载 地址:http://bootstrap-table.wenzhixin.net.cn/ 另一种是Nuget引入. 然后 ...

随机推荐

  1. 预编译加速编译(precompiled_header),指定临时文件生成目录,使项目文件夹更干净(MOC_DIR,RCC_DIR, UI_DIR, OBJECTS_DIR),#pragma execution_character_set("UTF-8")"这个命令是在编译时产生作用的,而不是运行时

    预编译加速编译 QT也可以像VS那样使用预编译头文件来加速编译器的编译速度.首先在.pro文件中加入: CONFIG += precompiled_header 然后定义需要预编译的头文件: PREC ...

  2. [2017.02.13] linux平台下统计C++项目文件个数和代码行数

    #输出排序后文件名 file='find . -name "*.[ch]" | sort' #统计文件个数 filecnt='find . -name "*.[ch]&q ...

  3. 【转载】Chrome使用自定义协议打开本地程序并运行IE打开网页

    部分内容转载自: http://blog.sina.com.cn/s/blog_e2b8213a0102wqby.html 项目中遇到某需求:chorme要运行IE并打开网页.解决方案之一就是通过自定 ...

  4. sql关联查询—将一个表的查询结果作为新表进行查询操作

    例题:#  各个部门中 最高工资中最低的那个部门的 最低工资是多少? 先考虑取得各个部门最高工资 SELECT MAX(salary) AS max_salary,e.`department_id` ...

  5. 深入理解计算机系统 BombLab 实验报告

    又快有一个月没写博客了,最近在看<深入理解计算机系统>这本书,目前看完了第三章,看完这章,对程序的机器级表示算是有了一个入门,也对 C 语言里函数栈帧有了一个初步的理解. 为了加深对书本内 ...

  6. 你一定能看懂的JDK动态代理

    前言:阅读这篇文章前,一定要知道什么是代理模式,具体可以参考这篇文章<设计模式(一):代理模式>. 在<设计模式(一):代理模式>一文中说了,程序员思思买书有两种选择:一种是选 ...

  7. Spark学习之路(四)—— RDD常用算子详解

    一.Transformation spark常用的Transformation算子如下表: Transformation算子 Meaning(含义) map(func) 对原RDD中每个元素运用 fu ...

  8. kubernetes实战篇之helm完整示例

    系列目录 构建一个 Helm Chart 下面我们通过一个完整的示例来学习如何使用 Helm 创建.打包.分发.安装.升级及回退Kubernetes应用. 创建一个名为 mychart 的 Chart ...

  9. java集合框架中的去重问题

    对于自定义的类来说,必须要重写hashcode和equals方法 hashcode方法的作用是确定元素在数据结构中的位置,当两个元素的hash值一样时,需要用equals方法判断两个元素是否是一样的, ...

  10. leetcode的Hot100系列--序

    小白程序猿,练练手,做做题目,分享下经验, 有不对的,还请大家能够指出,多多包涵!谢谢!! 先简单,后复杂,循序渐进,希望能够坚持下来, 大家一起进步~~