Bootstrap框架是近几年比较流行的后台前端开源框架,对于很多小公司,没有前端的开发团队来说,这是一个难得的前端框架,用到后台管理上,样式杠杠的没的说,而且是扁平化的设计,使用起来不仅流畅,体验也比较友好。
Bootstrap Table作为Bootstrap中的一款插件,把列表查询页面的功能包了个全,甚至对列的权限控制也可以做的很到位,下面进入使用正题。
本demo搭建环境:
springboot 2.1.4
thymeleaf
Bootstrap、jquery、bootstrap-table
首先,使用spring starter project创建一个项目,并引入thymeleaf模板,然后一个创建一个controller,用于返回前端需要的数据。一个html文件,展示一个列表。这样,就可以演示demo了,为了很好地说明这个bootstrap-table的各个属性的用法,js配置中加了尽可能多的列属性、行属性及注释,每个方法也足一尝试,各位看官看看够不够全,还有哪些奇葩要求不能满足呢?
Controller层代码,模拟返回的数据:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.example.demo.entity.Pager;
/**
* bootstrap-table练习demo
* @author 程就人生
* @date 2019年9月6日
*/
@RestController
public class IndexController {
/**
* 列表页初始化
* @return
*
*/
@GetMapping("/index")
public ModelAndView index(){
return new ModelAndView("/index");
}
/**
* 列表页查询结果模拟
* @return
*
*/
@GetMapping("/searchByCriteria")
public Object searchByCriteria(Pager pager){
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
Map<String,Object> dataMap = null;
//模拟分页查询的结果
for(int i=((pager.getCurrentPage()-1) * pager.getPageSize()); i<pager.getCurrentPage() * pager.getPageSize();i++){
dataMap = new HashMap<String,Object>();
dataMap.put("userName", "程就人生" + i);
dataMap.put("sex", i%2==0?"1":"0");
dataMap.put("desc", "描述描述描述" + i);
dataMap.put("money", "100.00");
dataMap.put("userUid", "N"+i);
list.add(dataMap);
}
Map<String,Object> map = new HashMap<String,Object>();
map.put("total", 100);
map.put("code", 200);
map.put("rows", list);
return map;
}
}
前台代码,分页,查询条件,列样式,列控制:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>列表页</title>
<meta name="keywords" content="">
<meta name="description" content="">
<!--[if lt IE 9]>
<meta http-equiv="refresh" content="0;ie.html" />
<![endif]-->
<link rel="stylesheet" th:href="@{/css/bootstrap.min14ed.css?v=3.3.6}">
<link rel="stylesheet" th:href="@{/css/bootstrap-table.min.css}">
</head>
<body >
<div class="wrapper wrapper-content animated fadeIn">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>查询条件</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form role="form" class="form-inline" id="searchForm" >
<div class="form-group">
<input type="text" placeholder="姓名" name="userName" id="userName" class="form-control">
</div>
<div class="form-group">
<input type="text" placeholder="描述" name="desc" id="desc" class="form-control">
</div>
<button id="dictkey_search_btn" class="btn btn-primary" type="button" onclick="searchByCriteria()" >查询</button>
<button id="dictkey_reset_btn" class="btn btn-info" type="button">重置</button>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>结果列表</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
</div>
</div>
<div class="ibox-content">
<button id="addButton" class="btn btn-info " type="button"><i class="fa fa-plus"></i> 新增</button>
<button id="editButton" class="btn btn-info " type="button"><i class="fa fa-edit"></i> 编辑</button>
<button id="deleteButton" class="btn btn-danger " type="button"><i class="fa fa-trash"></i> 删除</button>
<div class="table-responsive" >
<!-- bootstrap Table 使用 -->
<table id="table"></table>
</div>
</div>
</div>
</div>
</div>
</div>
<script th:src="@{/js/jquery.min.js?v=2.1.4}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/js/bootstrap-table.min.js}"></script>
<script th:src="@{/js/bootstrap-table-zh-CN.min.js}"></script>
<script th:inline="javascript" >
//获取查询参数,对表单中查询参数的封装
$.fn.serializeObject = function(){
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
$('#table').bootstrapTable({
url: "/searchByCriteria", //请求后台的URL(*)
method: 'GET', //请求方式(*)
toolbar: '.searchArea',
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
sortable: false, //是否启用排序
sortOrder: "asc", //排序方式
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
queryParamsType:"limit",
contentType:"application/x-www-form-urlencoded; charset=UTF-8",
pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
queryParams:queryParams, //查询参数
search: false, //是否显示表格搜索
strictSearch: true,
showColumns: true, //是否显示所有的列(选择显示的列),使用权限控制每一列时,可把该按钮设置为false
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
//height: 500, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
uniqueId: "ID", //每一行的唯一标识,一般为主键列
showToggle: true, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: false, //是否显示父子表
//singleSelect: true, //禁止选,默认多选,放开时单选
columns: [{
checkbox: true,
width:50
},{
title: '序号',
halign: 'center',//表头居中
align: 'center',//内容居中
width: '5%', //宽度5%
formatter:function (value, row, index) {
return index+1;
}
},{
field: 'userUid',
title: '用户ID',
visible: false //隐藏该列,不展示,也可以用权限控制这一行
}, {
field: 'userName',
halign: 'center',//表头居中
title: '姓名'
}, {
field: 'money',
halign: 'center',//表头居中
align: 'right',//居右
title: '余额'
}, {
field: 'sex',
halign: 'center',
title: '性别',
align: 'center',//内容居中
formatter:function (value, row, index) {
return value==1?"男":"女";
}
}, {
field: 'desc',
halign: 'center',
title: '个人描述'
}],
onLoadSuccess: function () {
//alert("页面加载后的处理。。。");
},
formatLoadingMessage: function(){
return "请稍等,正在加载中。。。";
},
onLoadError: function () {
//showTips("数据加载失败!");
},
onDblClickRow: function (row, $element) {
var id = row.ID;
},
//分页改变时触发
onPageChange:function(number, size){
queryParams.search=number;
}
});
//查询触发的事件
function searchByCriteria() {
$('#table').bootstrapTable('refresh');
};
// 查询条件,分页,检索条件等等
function queryParams(params) {
//此方法和后台的分页类Pager在接收参数上保持一致
var temp = {
pageSize: params.limit,
currentPage: params.offset/params.limit+1,
condition: $("#searchForm").serializeObject() //对查询条件的封装,可以尽可能地少写代码
};
return temp;
};
//获取选中的数据
var info = {};
//新增初始化
$("#addButton").click(function(){
alert("新增事件");
//TODO 新增处理事件
});
//修改初始化
$("#editButton").click(function(){
var a= $("#table").bootstrapTable('getSelections');
if(a.length<=0){
alert("请选择需要修改的数据!")
}else{
info = a[0];
alert("编辑事件,你选择了:" + info.userName);
//TODO 编辑处理事件
}
});
//删除处理
$("#deleteButton").click(function(){
var a= $("#table").bootstrapTable('getSelections');
if(a.length<=0){
alert("请选择需要删除的数据!")
}else{
confirm("确定要删除该数据吗?", function(index){
info = a[0];
//TODO 删除事件的处理
});
}
});
</script>
</body>
</html>
只引入了一个样式文件和必要的几个js文件,页面就相当规整了,看起来还不错。
以上功能,足以应对开发中的常见使用场景,特别是对列权限的控制,这个插件真的是特别好用,不知还有没有其他奇葩的需求呢。
参考资料:
bootstrap-table官网
https://bootstrap-table.com/
中文文档
https://www.runoob.com/bootstrap/bootstrap-tables.html
bootstrap table表格属性、列属性、事件、方法大全
https://blog.csdn.net/ryuenkyo/article/details/94554871
一个功能比较完善的已经搭好的付费后台管理界面,值得学习
http://www.zi-han.net/theme/hplus/
网友评论