简介
DataTables是一款比较好用的可以在bootstrap中使用的jquery表格插件。
它是一个高度灵活的工具,可以为任何HTML表格添加高级的交互功能。
DataTables特点
分页,即时搜索和排序
几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理
支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation
各式各样的扩展: Editor, TableTools, FixedColumns ……
丰富多样的option和强大的API
支持国际化
超过2900+个单元测试
免费开源 ( MIT license )! 商业支持
DataTables官网
https://datatables.net/
DataTables中文网
http://www.datatables.club/
DataTables官网实现例子
https://datatables.net/examples/index
DataTables中文网实现例子
http://datatables.club/example/#user_share
环境准备
我们在之前的文章中已经在SpringMVC基础框架的基础上应用了BootStrap的后台框架,在此基础上记录 dataTable列表示例。
应用bootstrap模板
基础项目源码下载地址为:
SpringMVC+Shiro+MongoDB+BootStrap基础框架
我们在基础项目中已经做好了首页index的访问。
现在就在index.jsp页面和index的路由Controller上做修改,实现 dataTable列表示例,提取数据库中的数据。
在使用DataTables之前需要先在官网下载DataTables的相关包放置到项目中,当然也可以使用CDN的方式直接引用外部资源。
资源下载链接:
https://datatables.net/download/index
在这个列表中可以定制需要的功能以及根据自己项目的具体情况进行选择功能插件。
如果不是很清楚的话 可以选择 最小的默认版本即可。
下载后解压zip压缩包得到文件如下:
如果需要用到很多其他交互功能,建议下载完整版,完整版DataTables插件下载路径
http://datatables.net/releases/DataTables-1.10.16.zip
完整版DataTables插件zip包解压如下:
放入到项目中路径如下:
需要引入的资源如下:
注意,项目需要支持jquery和bootstrap框架如下:
<!-- jQuery Js -->
<script src="/assets/js/jquery-1.10.2.js"></script>
```
```
<!-- Bootstrap Js -->
<script src="/assets/js/bootstrap.min.js"></script>
```
DataTables相关的资源引用:
```
<!-- jquery.dataTables.css -->
```
```
<link href="/plugins/DataTables-1.10.16/media/css/dataTables.bootstrap.css" rel="stylesheet"
type="text/css"></link>
```
```
<!-- DATA TABLE SCRIPTS -->
<script type="text/javascript" src="/plugins/DataTables-1.10.16/media/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="/plugins/DataTables-1.10.16/media/js/dataTables.bootstrap.min.js"></script>
<script type="text/javascript">
<script src="/plugins/DataTables-1.10.16/extensions/Responsive/js/dataTables.responsive.min.js"></script>
我们在列表展示时可能还需要通过时间段去查询,所以需要bootstrap-datetimepicker框架。
bootstrap-datetimepicker官网
http://www.bootcss.com/p/bootstrap-datetimepicker/
bootstrap-datepicker的github
https://github.com/uxsolutions/bootstrap-datepicker
在bootstrap-datetimepicker官网下载资源解压如图:
把bootstrap-datetimepicker-master放到项目中。
放入到项目中路径如下:
bootstrap-datetimepicker相关的资源引用:
<!-- DATE STYLES-->
<link rel="stylesheet" href="/plugins/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css"></link>
<script src="/plugins/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.min.js"></script>
<script src="/plugins/bootstrap-datetimepicker-master/js/locales/bootstrap-datetimepicker.zh-CN.js"></script>
注意事项
需要注意的是 js的引用有顺序,否则会报找不到方法的各种错误。
顺序是jQuery相关的js,bootstrap相关的js,datatables的js以及responsive的js,最后是datetimepicker的js。
JSP代码
<%@ include file="./include/header.jsp"%>
<!-- jquery.dataTables.css -->
<link href="/plugins/DataTables-1.10.16/media/css/dataTables.bootstrap.css" rel="stylesheet"
type="text/css"></link>
<link rel="stylesheet" href="/plugins/DataTables-1.10.16/extensions/Responsive/css/responsive.dataTables.css"></link>
<!-- DATE STYLES-->
<link rel="stylesheet" href="/plugins/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css"></link>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="cf" uri="com.data.web.view.function" %>
<div id="page-wrapper">
<div id="page-inner">
<div class="row">
<div class="col-md-12">
<h1 class="page-header">
DataTables<small>示例</small>
</h1>
</div>
</div>
<div class="row">
<form class="form-inline col-sm-11" id="search_form">
<div class="form-group ">
<input class="form-control" placeholder="名称或其他" name="name">
</div>
<div class="form-group">
<select class="form-control" id="gender" name="gender">
<option value="">--</option>
<option value=1>男</option>
<option value=0>女</option>
</select>
</div>
<div class="form-group">
<label for="beginTime">开始</label> <input type="text"
class="datepicker form-control"
data-date-format="yyyy-mm-dd 00:00:00" name="beginTime"
id="beginTime" />
</div>
<div class="form-group">
<label for="endTime">截止</label> <input type="text"
class="datepicker form-control"
data-date-format="yyyy-mm-dd 23:59:59" name="endTime" id="endTime" />
</div>
<button type="button" id="query" class="btn btn-success query mt-5">查询</button>
<button type="button" id="add" class="btn btn-info add mt-5">新建</button>
</form>
</div>
<!-- /. ROW -->
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">示例列表</div>
<div class="panel-body">
<div class="table-responsive">
<table class="table table-striped table-bordered responsive table-hover" id="table" cellspacing="0" width="100%">
<thead>
<tr>
<th width="8%" class="min-mobile-l">姓名</th>
<th width="10%" class="min-mobile-l">电话</th>
<th width="10%" class="min-mobile-l">性别</th>
<th width="10%" class="min-mobile-l">时间</th>
<th width="8%" class="min-mobile-l">操作</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- /. ROW -->
</div>
<!-- /. PAGE INNER -->
</div>
<!-- /. PAGE WRAPPER -->
<%@ include file="./include/footer.jsp"%>
<!-- DATA TABLE SCRIPTS -->
<script src="/plugins/DataTables-1.10.16/extensions/Responsive/js/dataTables.responsive.min.js"></script>
<script type="text/javascript" src="/plugins/DataTables-1.10.16/media/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="/plugins/DataTables-1.10.16/media/js/dataTables.bootstrap.min.js"></script>
<script src="/plugins/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.min.js"></script>
<script src="/plugins/bootstrap-datetimepicker-master/js/locales/bootstrap-datetimepicker.zh-CN.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.datepicker').datetimepicker({
language : 'zh-CN',
autoclose : true
});
refreshTable();//刷新列表数据内容
clickEvent();//绑定表格中的按钮事件
//点击查询
$('button.query').on("click", function() {
refreshTable();
clickEvent();
});
$('button.add').on('click',function(){
location.href = '/create';
});
});
function clickEvent(){
$('#table').on('click','.js-delete',function(){
if(confirm('确认删除该条数据?')){
var id = $(this).attr('data-id');
$.get('/delete?id='+id+'', function(result){
console.log(result);
if(result==0){
alert('删除成功');
window.location.reload();
}
})
}
}).on('click','.js-edit',function(){
var id = $(this).attr('data-id');
location.href = '/edit?id='+id+'';
})
}
function refreshTable(){
var $searchForm = $('#search_form').on('submit', function () {
$dt.DataTable().searchEx({}).draw();
return false;
});
var $dt = $('#table').on('preXhr.dt', function (e, settings, data) {
//data.search.value = $searchForm.formGet();
}).dataTable({
"columns" : [
{
"data" : "name",
"class" : "text-center"
},
{
"data" : "tel",
"class" : "text-center",
"render" : function(data, type, row) {
if(data){
var ms="00-";
ms=row.name+"的电话"+ms+data;
return ms;
}
return "";
}
},
{
"data" : "gender",
"class" : "text-center",
"render" : function(data, type, row) {
if(data==0){
return "女";
}else if(data==1){
return "男";
}
return "";
}
},
{
"data" : "creatTime",
"class" : "text-center",
"render" : function(data, type, row) {
return new Date(data).Format("yyyy-MM-dd hh:mm:ss");
}
},
{
"data" : "id",
"class" : "text-center",
"render" : function(data, type, row) {
return '<span class="btn btn-primary btn-xs ml-5 js-edit" data-id="'+data+'">编辑</span> <span class="btn btn-danger btn-xs ml-5 js-delete" data-id="'+data+'">删除</span>';
}
}
],
"ajax" : {//类似jquery的ajax参数,基本都可以用。
type : "post",//后台指定了方式,默认get,外加datatable默认构造的参数很长,有可能超过get的最大长度。
url : "/listData",
dataSrc : "data",//默认data,也可以写其他的,格式化table的时候取里面的数据
data : function(d) {//d 是原始的发送给服务器的数据,默认很长。
var param = {};//因为服务端排序,可以新建一个参数对象
param.start = d.start;//开始的序号
param.length = d.length;//要取的数据的
var formData = $(
"#search_form")
.serializeArray();//把form里面的数据序列化成数组
formData
.forEach(function(e) {
param[e.name] = e.value;
});
return param;//自定义需要传递的参数。
},
},
//"ajax": $.fn.dataTable.pagerAjax({url: "/listData"}),
"destroy":true,
lengthChange : false,
serverSide : true,//分页,取数据等等的都放到服务端去
searching : false,
processing : true,//载入数据的时候是否显示“载入中”
bDestroy : true,
pageLength : 20,//首次加载的数据条数
ordering : false,//排序操作在服务端进行,所以可以关了。
language : {
processing : "载入中",//处理页面数据的时候的显示
paginate : {//分页的样式文本内容。
previous : "上一页",
next : "下一页",
first : "第一页",
last : "最后一页"
},
zeroRecords : "没有内容",//table tbody内容为空时,tbody的内容。
//下面三者构成了总体的左下角的内容。
info : "第 _PAGE_/_PAGES_页 共 _TOTAL_条记录",//左下角的信息显示,大写的词为关键字。
infoEmpty : "第 _PAGE_/_PAGES_页 共 _TOTAL_条记录",//筛选为空时左下角的显示。
infoFiltered : ""//筛选之后的左下角筛选提示(另一个是分页信息显示,在上面的info中已经设置,所以可以不显示),
},
"columnDefs": [{
"defaultContent": "",
"targets": "_all"
}]
}).on('click', 'a[row-index]', function () {
});
}
//对Date的扩展,将 Date 转化为指定格式的String
//月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
//年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
//例子:
//(new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
//(new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
</script>
</body>
</html>
JAVA代码
联系人Contacts实体
package com.test.domain.entity;
import java.util.Date;
/**
* 联系人
*
*
*/
public class Contacts {
private String name;// 姓名
private String tel;// 电话
private Date creatTime;//创建时间
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public Date getCreatTime() {
return creatTime;
}
public void setCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
}
IndexController的代码如下:
package com.test.web.controller;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.test.domain.entity.Contacts;
import com.test.web.message.response.JSONResult;
/**
* IndexController
*
*
*/
@Controller
public class IndexController {
@Autowired
MongoTemplate mongoTemplate;
DateFormat fmt =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@RequestMapping("/")
public String index(Model model) throws IOException {
return "/index";
}
@SuppressWarnings("deprecation")
@RequestMapping("/listData")
@ResponseBody
public JSONObject listDatamale(@RequestParam Map<String, String> queryMap) throws ParseException {
Criteria criteria = new Criteria();
Query query =new Query();
Criteria criterianame=new Criteria();
if (StringUtils.isNoneBlank(queryMap.get("name"))) {
criterianame=new Criteria().orOperator(
Criteria.where("name").regex(
".*" + queryMap.get("name") + ".*", "i"),
Criteria.where("tel").regex(
".*" + queryMap.get("name") + ".*", "i"));
}
if (!StringUtils.isEmpty(queryMap.get("gender"))) {
criteria.and("gender").is((Integer.valueOf(queryMap.get("gender"))));
}
Criteria createTime = new Criteria();
if (!StringUtils.isEmpty(queryMap.get("beginTime"))
|| !StringUtils.isEmpty(queryMap.get("endTime"))) {
Criteria beginTime =new Criteria();
Criteria endTime =new Criteria();
if (!StringUtils.isEmpty(queryMap.get("beginTime"))) {
beginTime =Criteria.where("creatTime").gte(fmt.parse(String
.valueOf(queryMap.get("beginTime"))));
}
if (!StringUtils.isEmpty(queryMap.get("endTime"))) {
endTime =Criteria.where("creatTime").lte(fmt.parse(String
.valueOf(queryMap.get("endTime"))));
}
createTime.andOperator(beginTime,endTime);
}
criteria.andOperator(createTime,criterianame);
query.addCriteria(criteria);
if (queryMap.get("start") != null) {
query.skip(Integer.parseInt(queryMap.get("start")));
}
if (queryMap.get("length") != null) {
query.limit(Integer.parseInt(queryMap.get("length")));
}
long allCount = mongoTemplate.count(query, Contacts.class);
query.with(new Sort(Sort.Direction.DESC, "createTime"));
List<Contacts> list = mongoTemplate.find(query, Contacts.class);
JSONObject result = new JSONObject();
result.put("draw", UUID.randomUUID().toString());//给本次数据容器一个随机id
result.put("recordsTotal", allCount);// 设置总条数
result.put("recordsFiltered", allCount);// 设置过滤后的总条数
result.put("data", list);
return result;
}
@RequestMapping("/delete")
@ResponseBody
public JSONResult delete(@RequestParam String id) {
mongoTemplate.remove(new Query(Criteria.where("_id").is(id)), Contacts.class);
return JSONResult.success(1);
}
@RequestMapping("/create")
public String create(Model model) {
return "/edit";
}
@RequestMapping("/edit")
public String edit(Model model,@RequestParam String id) {
model.addAttribute("contact", mongoTemplate.find(new Query(Criteria.where("_id").is(id)), Contacts.class));
return "/edit";
}
@RequestMapping("/add")
@ResponseBody
public JSONResult save() {
List<Contacts> cs=new ArrayList<Contacts>();
for(int i=0;i<20;i++) {
Contacts c=new Contacts();
c.setName("joe"+i);
c.setTel("123"+i);
c.setGender(i%2);
c.setCreatTime(new Date());
cs.add(c);
}
mongoTemplate.insertAll(cs);
return JSONResult.success(1);
}
}
最终效果如图: