JQuery Datatables是一款JQuery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。功能包含:分页,即时搜索和排序、几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理、支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation、丰富多样的option和强大的API、支持国际化等。
1、JQuery DataTables示例代码
$(document).ready(function()
{
//DataTable对象
var tableModel = $("#table").DataTable({
"processing": true, //显示“处理中...”
"serverSide": true, //开启服务器模式
"paging": true, //是否允许翻页
"rowId": "userId", //指定用于行ID的属性名 默认是:DT_RowId
"lengthMenu": [5, 10, 25, 50, 75, 100], // 数量选择下拉框内容
"pageLength": 5, // 每页的初期件数
"searching" : false, //是否显示搜索框
"bSort": false, //禁止排序
"ajax": {
"url": "/user/searchUserPage",
"type": "GET",
"data": function (searchParams) {
searchParams.userName = $("#userName").val();
searchParams.sex = $("#sex").val();
searchParams.departmentName = $("#departmentName").val();
searchParams.orderBy = "user_id ASC";
return searchParams;
}
},
"columns": [
{
"data": "userId", "title":"<input type='checkbox' id='checkAll' />全选",
"render": function (data, type, row, meta)
{
return "<input type='checkbox' name='checkItem' value=" + data + " />";
}
},
{
"title":"序号",
"render" : function (data, type, row, meta)
{
return meta.row + 1 + meta.settings._iDisplayStart;
}
},
{ "data": "userName","title":"用户名称" },
{
"data": "sex","title":"性别",
"render" : function ( data, type, row, meta ) {
var conent = data == 1 ? "男" : "女";
return conent;
}
},
{ "data": "departmentName","title":"部门名称" },
{ "data": "blogRemark","title":"博客信息" },
{
"title":"操作",
"render" : function ( data, type, row, meta )
{
var conent = "<a href='javascript:updateData(" + row.userId + ")'>编辑</a>\n";
conent += "<a href='javascript:deleteData(" + row.userId + ")'>删除</a>";
return conent;
}
}
],
"language": {
"sProcessing": "处理中...",
"sLengthMenu": "显示 _MENU_ 项结果",
"sZeroRecords": "没有匹配结果",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sInfoPostFix": "",
"sSearch": "搜索:",
"sUrl": "",
"sEmptyTable": "表中数据为空",
"sLoadingRecords": "载入中...",
"sInfoThousands": ",",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "上页",
"sNext": "下页",
"sLast": "末页"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
}
});
});
2、创建项目
【实例】创建 SpringBoot、MyBatis 整合的项目,使用 JQuery DataTables 插件分页显示用户列表信息。执行结果如下图:
2.1 创建数据表
在MySQL数据库中创建用户信息表(tb_user),并添加数据。
-- 判断数据表是否存在,存在则删除
DROP TABLE IF EXISTS tb_user;
-- 创建“用户信息”数据表
CREATE TABLE IF NOT EXISTS tb_user
(
user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
user_name VARCHAR(50) NOT NULL COMMENT '用户名称',
sex CHAR(2) DEFAULT '1' COMMENT '性别(1:男;2:女;)',
department_name VARCHAR(50) NOT NULL COMMENT '部门名称',
blog_remark VARCHAR(50) COMMENT '博客信息'
) COMMENT = '用户信息表';
-- 创建数据
INSERT INTO tb_user(user_name,sex,department_name,blog_remark) VALUES
('pan_junbiao的博客',1,'研发部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',1,'财务部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',2,'人事部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',1,'研发部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',2,'财务部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',1,'人事部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',2,'人事部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',1,'研发部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',1,'研发部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',1,'财务部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',2,'研发部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',1,'财务部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',1,'研发部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',1,'财务部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',1,'研发部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',2,'财务部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',1,'人事部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',2,'财务部','https://blog.csdn.net/pan_junbiao'),
('pan_junbiao的博客',1,'研发部','您好,欢迎访问 pan_junbiao的博客'),('pan_junbiao的博客',2,'人事部','https://blog.csdn.net/pan_junbiao');
2.2 创建项目
(1)创建SpringBoot项目,项目结构如下图:
(2)创建实体类(Entity层)
在com.pjb.entity包中,创建UserInfo类(用户信息实体类)。
package com.pjb.entity;
/**
* 用户信息的持久化类
* @author pan_junbiao
**/
public class UserInfo
{
private int userId; //用户编号
private String userName; //用户名称
private int sex; //性别(1:男;2:女;)
private String departmentName; //部门名称
private String blogRemark; //博客信息
//省略getter与setter方法...
}
(3)数据库映射层(Mapper层)
在com.pjb.mapper包中,创建UserMapper接口(用户信息Mapper动态代理接口)。
package com.pjb.mapper;
import com.pjb.entity.UserInfo;
import com.pjb.model.UserParam;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.SelectProvider;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 用户信息Mapper动态代理接口
* @author pan_junbiao
**/
@Mapper
@Repository
public interface UserMapper
{
/**
* 分页查询员工列表
*/
@SelectProvider(type = UserSqlBuilder.class, method = "searchUserList")
public List<UserInfo> searchUserList(UserParam userParam);
/**
* 查询员工列表总数
*/
@SelectProvider(type = UserSqlBuilder.class, method = "searchUserCount")
public int searchUserCount(UserParam param);
//建议将SQL Builder以映射器接口内部类的形式进行定义
public class UserSqlBuilder
{
/**
* 分页查询员工列表
*/
public String searchUserList(UserParam param)
{
StringBuffer sql = new StringBuffer("SELECT * FROM tb_user WHERE 1=1");
//用户名称
if(param.getUserName()!=null && param.getUserName().length()>0)
{
sql.append(" AND user_name LIKE '%${userName}%'");
}
//性别(1:男;2:女;)
if(param.getSex()>0)
{
sql.append(" AND sex = #{sex}");
}
//部门名称
if(param.getDepartmentName()!=null && param.getDepartmentName().length()>0)
{
sql.append(" AND department_name = #{departmentName}");
}
//排序信息
if(param.getOrderBy()!=null && param.getOrderBy().length()>0)
{
sql.append(" ORDER BY #{orderBy}");
}
//分页信息
sql.append(" LIMIT #{start}, #{length}");
return sql.toString();
}
/**
* 查询员工列表总数
*/
public String searchUserCount(UserParam param)
{
StringBuffer sql = new StringBuffer("SELECT COUNT(1) FROM tb_user WHERE 1=1");
//用户名称
if(param.getUserName()!=null && param.getUserName().length()>0)
{
sql.append(" AND user_name LIKE '%${userName}%'");
}
//性别(1:男;2:女;)
if(param.getSex()>0)
{
sql.append(" AND sex = #{sex}");
}
//部门名称
if(param.getDepartmentName()!=null && param.getDepartmentName().length()>0)
{
sql.append(" AND department_name = #{departmentName}");
}
return sql.toString();
}
}
}
3、JQuery DataTables的使用
(1)模型类(Model层)
在com.pjb.model.DataTable包中,创建DtSentParam类(DataTables请求的参数类)。
package com.pjb.model.DataTable;
/**
* DataTables请求的参数类
* @author pan_junbiao
**/
public class DtSentParam
{
/**
* 绘制计数器。这个是用来确保Ajax从服务器返回的是对应的(Ajax是异步的,因此返回的顺序是不确定的)。
* 要求在服务器接收到此参数后再返回
*/
private int draw;
/**
* 第一条数据的起始位置,比如0代表第一条数据
*/
private int start;
/**
* 告诉服务器每页显示的条数,这个数字会等于返回的 data集合的记录数,可能会大于因为服务器可能没有那么多数据。
* 这个也可能是-1,代表需要返回全部数据(尽管这个和服务器处理的理念有点违背)
*/
private int length;
/**
* 搜索值
* key包含:value和regex
*/
private Map<String, String> search = new HashMap<String, String>();
//省略getter与setter方法...
}
在com.pjb.model.DataTable包中,创建DtReturnData类(DataTables接收服务器返回的数据类)。
package com.pjb.model.DataTable;
import java.util.List;
/**
* DataTables接收服务器返回的数据类
* @author pan_junbiao
**/
public class DtReturnData<T>
{
/**
* 必要。上面提到了,Datatables发送的draw是多少那么服务器就返回多少。
* 这里注意,出于安全的考虑,强烈要求把这个转换为整形,即数字后再返回,而不是纯粹的接受然后返回,
* 这是 为了防止跨站脚本(XSS)攻击。
*/
private int draw;
/**
* 必要。即没有过滤的记录数(数据库里总共记录数)
*/
private int recordsTotal;
/**
* 必要。过滤后的记录数(如果有接收到前台的过滤条件,则返回的是过滤后的记录数)
*/
private int recordsFiltered;
/**
* 必要。表中中需要显示的数据。
*/
private List<T> data;
//省略getter与setter方法...
}
在com.pjb.model包中,创建UserParam类(用户信息参数类),并继承DtSentParam类。
package com.pjb.model;
import com.pjb.model.DataTable.DtSentParam;
/**
* 用户信息参数类
* @author pan_junbiao
**/
public class UserParam extends DtSentParam
{
private String userName; //用户名称
private int sex; //性别(1:男;2:女;)
private String departmentName; //部门名称
private String orderBy; //排序
//省略getter与setter方法...
}
(2)控制器方法(Controller层)
在com.pjb.controller包中,创建UserController类(用户信息控制器)。
package com.pjb.controller;
import com.pjb.entity.UserInfo;
import com.pjb.mapper.UserMapper;
import com.pjb.model.DataTable.DtReturnData;
import com.pjb.model.UserParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* 用户信息控制器
* @author pan_junbiao
**/
@Controller
@RequestMapping("user")
public class UserController
{
@Autowired
private UserMapper userMapper;
/**
* 分页查询员工列表
*/
@ResponseBody
@RequestMapping("/searchUserPage")
public DtReturnData<UserInfo> searchUserPage(UserParam param)
{
DtReturnData<UserInfo> dtReturnData = new DtReturnData<UserInfo>();
//分页查询员工列表
List<UserInfo> userList = userMapper.searchUserList(param);
//查询员工列表总数
int total = userMapper.searchUserCount(param);
//封装成DataTable所需的数据类型
dtReturnData.setDraw(param.getDraw());
dtReturnData.setData(userList);
dtReturnData.setRecordsTotal(total);
dtReturnData.setRecordsFiltered(total);
//返回结果
return dtReturnData;
}
/**
* 用户列表页面
*/
@RequestMapping("/toUserList")
public String toUserList()
{
return "user-list.html";
}
}
(2)显示页面(View层)
在resources/templates目录下,创建 user-list.html 用户列表显示页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<meta name="author" content="pan_junbiao的博客">
<link rel="stylesheet" href="/css/base.css">
<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="/DataTables-1.10.21/css/jquery.dataTables.css">
<!-- jQuery -->
<script type="text/javascript" charset="utf8" src="/DataTables-1.10.21/js/jquery.js"></script>
<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="/DataTables-1.10.21/js/jquery.dataTables.js"></script>
</head>
<body>
<!--搜索框-->
<form class="searchBox">
用户名称:<input class="s_text" id="userName"/>
性别:
<select class="s_select" id="sex">
<option value="0">请选择</option>
<option value="1">男</option>
<option value="2">女</option>
</select>
部门:
<select class="s_select" id="departmentName">
<option value="">请选择</option>
<option value="研发部">研发部</option>
<option value="财务部">财务部</option>
<option value="人事部">人事部</option>
</select>
<input class="b_button" type="button" value="搜索" onclick="searchList()"/>
<input class="b_button" type="reset" value="重置" />
<input class="b_button" type="button" value="批量删除" onclick="batchDelete()" />
</form>
<!-- 数据表格 -->
<table id="table" class="cell-border" ></table>
</body>
<script>
$(document).ready(function()
{
//DataTable对象
var tableModel = $("#table").DataTable({
"processing": true, //显示“处理中...”
"serverSide": true, //开启服务器模式
"paging": true, //是否允许翻页
"rowId": "userId", //指定用于行ID的属性名 默认是:DT_RowId
"lengthMenu": [5, 10, 25, 50, 75, 100], // 数量选择下拉框内容
"pageLength": 5, // 每页的初期件数
"searching" : false, //是否显示搜索框
"bSort": false, //禁止排序
"ajax": {
"url": "/user/searchUserPage",
"type": "GET",
"data": function (searchParams) {
searchParams.userName = $("#userName").val();
searchParams.sex = $("#sex").val();
searchParams.departmentName = $("#departmentName").val();
searchParams.orderBy = "user_id ASC";
return searchParams;
}
},
"columns": [
{
"data": "userId", "title":"<input type='checkbox' id='checkAll' />全选",
"render": function (data, type, row, meta)
{
return "<input type='checkbox' name='checkItem' value=" + data + " />";
}
},
{
"title":"序号",
"render" : function (data, type, row, meta)
{
return meta.row + 1 + meta.settings._iDisplayStart;
}
},
{ "data": "userName","title":"用户名称" },
{
"data": "sex","title":"性别",
"render" : function ( data, type, row, meta ) {
var conent = data == 1 ? "男" : "女";
return conent;
}
},
{ "data": "departmentName","title":"部门名称" },
{ "data": "blogRemark","title":"博客信息" },
{
"title":"操作",
"render" : function ( data, type, row, meta )
{
var conent = "<a href='javascript:updateData(" + row.userId + ")'>编辑</a>\n";
conent += "<a href='javascript:deleteData(" + row.userId + ")'>删除</a>";
return conent;
}
}
],
"language": {
"sProcessing": "处理中...",
"sLengthMenu": "显示 _MENU_ 项结果",
"sZeroRecords": "没有匹配结果",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sInfoPostFix": "",
"sSearch": "搜索:",
"sUrl": "",
"sEmptyTable": "表中数据为空",
"sLoadingRecords": "载入中...",
"sInfoThousands": ",",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "上页",
"sNext": "下页",
"sLast": "末页"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
}
});
// init:初始化和数据都加载完成,和 initComplete配置等价
tableModel.on("draw", function ()
{
//全选
$("#checkAll").click(function(){
$("[name=checkItem]:checkbox").prop("checked",this.checked);
});
//复选框组的联动效果
$("[name=checkItem]:checkbox").click(function(){
var flag = true;
$("[name=checkItem]:checkbox").each(function(index){
if(!this.checked)
{
flag = false;
}
});
$("#checkAll").prop("checked",flag);
});
});
});
//查询列表
function searchList()
{
//重新加载DataTable列表
$("#table").DataTable().ajax.reload();
}
//编辑用户
function updateData(userId)
{
if (userId <= 0) {
alert("参数错误!");
return;
}
//执行您的编辑操作
alert("编辑用户的编号:" + userId);
//编辑操作完成后,重新加载DataTable列表
$("#table").DataTable().ajax.reload();
}
//删除用户
function deleteData(userId)
{
if (!confirm("确定删除该记录吗?")) {
return;
}
if (userId <= 0) {
alert("参数错误!");
return;
}
//执行您的删除操作
alert("删除用户的编号:" + userId);
//删除操作完成后,重新加载DataTable列表
$("#table").DataTable().ajax.reload();
}
//批量删除
function batchDelete()
{
var idArray = new Array(); //批量删除的用户ID数组
$("[name=checkItem]:checkbox:checked").each(function(index){
idArray.push($(this).val());
});
if(idArray.length==0)
{
alert("请选择要删除的员工!");
return;
}
if (!confirm("确定删除记录吗?")) {
return;
}
//执行您的删除操作
alert("删除用户的编号:" + idArray);
//删除操作完成后,重新加载DataTable列表
$("#table").DataTable().ajax.reload();
}
</script>
</html>
(3)运行测试
代码完成后,就可以运行测试了,启动项目,执行结果如下:
当在搜索框中输入相关参数,如用户名称:pan_junbiao的博客;性别:男;部门:研发部;点击“搜索”按钮,执行结果如下:
当点击“全选”复选框后,选中需要批量删除的用户信息,然后点击“批量删除”按钮,将输出被删除用户的编号列表,执行结果如下:
4、JQuery DataTables去掉搜索框和底部文字
$(function(){
$('#table').dataTable({
"searching" : false, //去掉搜索框方法一
"bFilter": false, //去掉搜索框方法二
"bSort": false, //禁止排序
"paging": false, //禁止分页
"info": false //去掉底部文字
});
});
5、JQuery DataTables设置服务器返回的数据
Datatables 额外提供了 dataSrc 属性来改变从服务器返回的数据给 Datatables,或者是操作数据从一种形式转换成另一种形式(比如xml、json、yaml等)。 这么做是因为 ajax 的 success 选项不能被改变 Datatables 内部自己加载数据完成时使用。
dataSrc属性的用法:
"ajax": {
"url": "/user/getUserList",
"type": "GET",
//设置服务器返回的数据
//"dataSrc":"userInfoList"
// 或者:
"dataSrc": function(result)
{
//设置服务器返回的数据
return result.userInfoList;
}
}
【实例】使用 dataSrc 属性绑定从服务器返回的数据给Datatables,并且隐藏分页信息、底部信息。
(1)模型类(Model层)
创建 UserModel类(用户信息模型类),在该类中包含一个用户列表属性。
package com.pjb.model;
import com.pjb.entity.UserInfo;
import java.util.List;
/**
* 用户信息模型类
* @author pan_junbiao
**/
public class UserModel
{
private int total; //数据总数
private List<UserInfo> userInfoList; //用户列表
public int getTotal()
{
return total;
}
public void setTotal(int total)
{
this.total = total;
}
public List<UserInfo> getUserInfoList()
{
return userInfoList;
}
public void setUserInfoList(List<UserInfo> userInfoList)
{
this.userInfoList = userInfoList;
}
}
(2)控制器方法(Controller层)
在控制器中,编写获取用户信息方法。
/**
* 获取用户列表
* @author pan_junbiao
*/
@ResponseBody
@RequestMapping("/getUserList")
public UserModel getUserList()
{
UserModel userModel = new UserModel();
//创建参数类
UserParam param = new UserParam();
param.setStart(1);
param.setLength(5);
//分页查询员工列表
List<UserInfo> userList = userMapper.searchUserList(param);
//查询员工列表总数
int total = userMapper.searchUserCount(param);
userModel.setUserInfoList(userList);
userModel.setTotal(total);
//返回结果
return userModel;
}
(3)显示页面(View层)
在resources/templates目录下,创建 user-dataSrc.html 用户列表显示页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<meta name="author" content="pan_junbiao的博客">
<link rel="stylesheet" href="/css/base.css">
<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="/DataTables-1.10.21/css/jquery.dataTables.css">
<!-- jQuery -->
<script type="text/javascript" charset="utf8" src="/DataTables-1.10.21/js/jquery.js"></script>
<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="/DataTables-1.10.21/js/jquery.dataTables.js"></script>
</head>
<body>
<!-- 数据表格 -->
<table id="table" class="cell-border"></table>
</body>
<script>
$(document).ready(function () {
//DataTable对象
var tableModel = $("#table").DataTable({
"processing": true, //显示“处理中...”
"serverSide": true, //开启服务器模式
"paging": false, //是否允许翻页
"searching": false, //是否显示搜索框
"bSort": false, //禁止排序
"info": false, //去掉底部文字
"rowId": "userId", //指定用于行ID的属性名 默认是:DT_RowId
"ajax": {
"url": "/user/getUserList",
"type": "GET",
//设置服务器返回的数据
//"dataSrc":"userInfoList"
// 或者:
"dataSrc": function(result)
{
//这里可以做些数据处理
if(result && result.userInfoList && result.userInfoList.length>0)
{
alert("数据总数:" + result.total);
}
else
{
alert("无数据");
}
//设置服务器返回的数据
return result.userInfoList;
}
},
"columns": [
{
"data": "userId", "title": "<input type='checkbox' id='checkAll' />全选",
"render": function (data, type, row, meta) {
return "<input type='checkbox' name='checkItem' value=" + data + " />";
}
},
{
"title": "序号",
"render": function (data, type, row, meta) {
return meta.row + 1 + meta.settings._iDisplayStart;
}
},
{"data": "userName", "title": "用户名称"},
{
"data": "sex", "title": "性别",
"render": function (data, type, row, meta) {
var conent = data == 1 ? "男" : "女";
return conent;
}
},
{"data": "departmentName", "title": "部门名称"},
{"data": "blogRemark", "title": "博客信息"},
{
"title": "操作",
"render": function (data, type, row, meta) {
var conent = "<a href='javascript:updateData(" + row.userId + ")'>编辑</a>\n";
conent += "<a href='javascript:deleteData(" + row.userId + ")'>删除</a>";
return conent;
}
}
]
});
// init:初始化和数据都加载完成,和 initComplete配置等价
tableModel.on("draw", function () {
//全选
$("#checkAll").click(function () {
$("[name=checkItem]:checkbox").prop("checked", this.checked);
});
//复选框组的联动效果
$("[name=checkItem]:checkbox").click(function () {
var flag = true;
$("[name=checkItem]:checkbox").each(function (index) {
if (!this.checked) {
flag = false;
}
});
$("#checkAll").prop("checked", flag);
});
});
});
</script>
</html>
(3)运行测试
启动项目,执行结果如下: