datatables使用教程
- 2019 年 10 月 5 日
- 筆記
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/qq_37933685/article/details/85144313
文章目錄
- bootstrap-datatables使用教程
- 介紹
- 安裝配置
- 簡單使用
- 設置language 選項
- 設置開發常用選項
- ajax非同步帶參數獲取數據源,結合Java服務端模式
- 搜索條件,整合服務端,利用mybatis動態sql
bootstrap-datatables使用教程
介紹
Datatables是一款jquery表格插件。它是一個高度靈活的工具,可以將任何HTML表格添加高級的交互功能。
- 分頁,即時搜索和排序
- 幾乎支援任何數據源:DOM, javascript, Ajax 和 伺服器處理
- 支援不同主題 DataTables, jQuery UI, Bootstrap, Foundation
- 各式各樣的擴展: Editor, TableTools, FixedColumns ……
- 豐富多樣的option和強大的API
- 支援國際化
- 超過2900+個單元測試
- 免費開源 ( MIT license )! 商業支援
- 更多特性請到官網查看
安裝配置
本文程式碼倉庫:https://gitee.com/suwenguang/demo/tree/datatables使用教程
步驟
- 引入文件 css,jq,datatables
- 拿到table對象,執行初始化
示例程式碼
<!--第一步:引入Javascript / CSS (CDN)--> <!-- DataTables CSS --> <link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.15/css/jquery.dataTables.css"> <!-- jQuery --> <script type="text/javascript" charset="utf8" src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <!-- DataTables --> <script type="text/javascript" charset="utf8" src="http://cdn.datatables.net/1.10.15/js/jquery.dataTables.js"></script> <!--或者下載到本地,下面有下載地址--> <!-- DataTables CSS --> <link rel="stylesheet" type="text/css" href="DataTables-1.10.15/media/css/jquery.dataTables.css"> <!-- jQuery --> <script type="text/javascript" charset="utf8" src="DataTables-1.10.15/media/js/jquery.js"></script> <!-- DataTables --> <script type="text/javascript" charset="utf8" src="DataTables-1.10.15/media/js/jquery.dataTables.js"></script> <!--第二步:添加如下 HTML 程式碼--> <table id="table_id_example" class="display"> <thead> <tr> <th>Column 1</th> <th>Column 2</th> </tr> </thead> <tbody> <tr> <td>Row 1 Data 1</td> <td>Row 1 Data 2</td> </tr> <tr> <td>Row 2 Data 1</td> <td>Row 2 Data 2</td> </tr> </tbody> </table> <!--第三步:初始化Datatables--> $(document).ready( function () { $('#table_id_example').DataTable(); } );
原理介紹
對table進行渲染,前提table的數據源得有,如上面的是HTML頁面本來就有一定的數據了,所以可以直接調用函數進行渲染;
但是在大多數情況下,項目開發並不會採用這種做法,而是要結合服務端,採用ajax方式獲取數據源。
做法有很多,可以ajax非同步拿到數據後,進行dom操作,把數據填入table中,在進行datatables.ajax.reload()
這樣當然可以,但是程式碼很亂,難看。
然而datatables支援我們開啟服務端模式,通過配置一些選項即可做到。那麼下面開始我們開發中比較好的用法。當然,你也可以通過自己去官網去了解更多的使用技巧。
上面的只是最簡單的入門,還有更多自定義參數,自定義選型。
下面我們來看一下,在開發中最常用的一些用法。
簡單使用
步驟
- 前端準備好靜態的表格數據
- 引入datatables
- 在js中調用函數渲染
示例程式碼
前端準備好靜態的表格數據
<html> <#include "common/head.ftl"> <body> <table id="t1"> <thead> <tr> <th>編號</th> <th>姓名</th> <th>性別</th> <th>年齡</th> <th>生日</th> <th>操作</th> </tr> </thead> <tbody> <tr> <td>Row 1 Data 1</td> <td>Row 1 Data 2</td> <td>Row 1 Data 1</td> <td>Row 1 Data 2</td> <td>Row 1 Data 1</td> <td>Row 1 Data 2</td> </tr> <tr> <td>Row 2 Data 1</td> <td>Row 2 Data 2</td> <td>Row 1 Data 1</td> <td>Row 1 Data 2</td> <td>Row 1 Data 1</td> <td>Row 1 Data 2</td> </tr> </tbody> </table> </body> </html> <script src="/js/index.js"></script>
引入datatables
我是在head.ftl 中公共部分引入的。並且是使用maven去管理webjars,具體程式碼請clone 我的GitHub上的程式碼查看,每一步都是有commit tag 可以查看的。
<head> <link rel="stylesheet" href="/webjars/bootstrap/3.3.6/css/bootstrap.min.css"/> <link rel="stylesheet" type="text/css" href="/webjars/datatables/1.10.16/css/jquery.dataTables.css"> <script src="/webjars/jquery/1.12.3/jquery.min.js"></script> <script src="/webjars/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script type="text/javascript" charset="utf8" src="/webjars/datatables/1.10.16/js/jquery.dataTables.js"></script> <#--設置request變數--> <script> var ctx = "${request.contextPath}"; </script> </head>
在js中調用函數渲染
$("#t1").dataTable({});
效果截圖

可以看到,這些默認都是英文的,那怎麼辦呢?其實我們可以自己訂製這個語言選項。
設置language 選項
下面給出詳細點的解釋,這些是通常能用到的。但是很多時候,項目開發是不需要這麼多的。
關鍵程式碼
對應倉庫的
datatables使用教程
分支的language選項詳解
$("#t1").dataTable({ language: { "decimal": "",//小數的小數位符號 比如「,」作為數字的小數位符號 "emptyTable": "沒有數據喲~~",//沒有數據時要顯示的字元串 "info": "當前 _START_ 條到 _END_ 條 共 _TOTAL_ 條",//左下角的資訊,變數可以自定義,到官網詳細查看 "infoEmpty": "無記錄",//當沒有數據時,左下角的資訊 "infoFiltered": "(從 _MAX_ 條記錄過濾)",//當表格過濾的時候,將此字元串附加到主要資訊 "infoPostFix": "",//在摘要資訊後繼續追加的字元串 "thousands": ",",//千分位分隔符 "lengthMenu": "每頁 _MENU_ 條記錄",//用來描述分頁長度選項的字元串 "loadingRecords": "載入中...",//用來描述數據在載入中等待的提示字元串 - 當非同步讀取數據的時候顯示 "processing": "處理中...",//用來描述載入進度的字元串 "search": "搜索",//用來描述搜索輸入框的字元串 "zeroRecords": "沒有找到",//當沒有搜索到結果時,顯示 "paginate": { "first": "首頁", "previous": "上一頁", "next": "下一頁", "last": "尾頁" } } });
效果截圖

可以看到,datatables是提供介面讓我們自定義的,當然,相對應的官網也會提供介面文檔。具體可以看這裡
設置開發常用選項
那麼我們開發也只是用到其中的一些。比較常用的,適應大部分普通後台管理的需求。
示例程式碼
具體查看程式碼倉庫:
datatables使用教程
分支的常用選項
index.js
$("#t1").dataTable({ language: { "decimal": "",//小數的小數位符號 比如「,」作為數字的小數位符號 "emptyTable": "沒有數據喲~~",//沒有數據時要顯示的字元串 "info": "當前 _START_ 條到 _END_ 條 共 _TOTAL_ 條",//左下角的資訊,變數可以自定義,到官網詳細查看 "infoEmpty": "無記錄",//當沒有數據時,左下角的資訊 "infoFiltered": "(從 _MAX_ 條記錄過濾)",//當表格過濾的時候,將此字元串附加到主要資訊 "infoPostFix": "",//在摘要資訊後繼續追加的字元串 "thousands": ",",//千分位分隔符 "lengthMenu": "每頁 _MENU_ 條記錄",//用來描述分頁長度選項的字元串 "loadingRecords": "載入中...",//用來描述數據在載入中等待的提示字元串 - 當非同步讀取數據的時候顯示 "processing": "處理中...",//用來描述載入進度的字元串 "search": "搜索",//用來描述搜索輸入框的字元串 "zeroRecords": "沒有找到",//當沒有搜索到結果時,顯示 "paginate": { "first": "首頁", "previous": "上一頁", "next": "下一頁", "last": "尾頁" } }, processing: true,//是否顯示處理狀態(排序的時候,數據很多耗費時間長的話,也會顯示這個) lengthChange: true,//是否允許用戶改變表格每頁顯示的記錄數 orderMulti: true, //啟用多列排序 ordering: true,//使用排序 bStateSave: true,//記錄cookie paging: true,//是否分頁 pagingType: "full_numbers",//除首頁、上一頁、下一頁、末頁四個按鈕還有頁數按鈕 searching: false,//是否開始本地搜索 stateSave: false,//刷新時是否保存狀態 autoWidth: true,//自動計算寬度 deferRender: true,//延遲渲染 });
扯了那麼多,只是定義一個大概雛形,接下來才是重頭戲
ajax非同步帶參數獲取數據源,結合Java服務端模式
服務端採用springboot 的 ssm框架 + freemarkder視圖(新手提示:類似jsp的東東)+pagehelper分頁
步驟
前端的步驟
- 開啟datatables的一些參數,serverSide: true
- 配置ajax源,即後端介面url
- 渲染,調用函數
datatables.ajax.reload()
後端介面的步驟
- 編寫介面
- 編寫mapper
- 返回json數據
注意:前後端一定要定義好數據格式,還有傳輸模式 這裡我統一使用 JSON
示例程式碼
前端
freemarker
<html> <#include "common/head.ftl"> <body> <table id="t1"> <thead> <tr> <th>編號</th> <th>姓名</th> <th>性別</th> <th>年齡</th> <th>生日</th> </tr> </thead> <tbody> </tbody> </table> </body> </html> <#include "common/footer.ftl"> <script src="/js/index.js"></script>
這裡我使用的靜態模板引擎 freemarker
html只要表頭,其他樣式都不要了,懶!
js
$("#t1").dataTable({ language: { "decimal": "",//小數的小數位符號 比如「,」作為數字的小數位符號 "emptyTable": "沒有數據喲~~",//沒有數據時要顯示的字元串 "info": "當前 _START_ 條到 _END_ 條 共 _TOTAL_ 條",//左下角的資訊,變數可以自定義,到官網詳細查看 "infoEmpty": "無記錄",//當沒有數據時,左下角的資訊 "infoFiltered": "(從 _MAX_ 條記錄過濾)",//當表格過濾的時候,將此字元串附加到主要資訊 "infoPostFix": "",//在摘要資訊後繼續追加的字元串 "thousands": ",",//千分位分隔符 "lengthMenu": "每頁 _MENU_ 條記錄",//用來描述分頁長度選項的字元串 "loadingRecords": "載入中...",//用來描述數據在載入中等待的提示字元串 - 當非同步讀取數據的時候顯示 "processing": "處理中...",//用來描述載入進度的字元串 "search": "搜索",//用來描述搜索輸入框的字元串 "zeroRecords": "沒有找到",//當沒有搜索到結果時,顯示 "paginate": { "first": "首頁", "previous": "上一頁", "next": "下一頁", "last": "尾頁" } }, processing: true,//是否顯示處理狀態(排序的時候,數據很多耗費時間長的話,也會顯示這個) lengthChange: true,//是否允許用戶改變表格每頁顯示的記錄數 orderMulti: true, //啟用多列排序 ordering: true,//使用排序 bStateSave: true,//記錄cookie paging: true,//是否分頁 pagingType: "full_numbers",//除首頁、上一·頁、下一頁、末頁四個按鈕還有頁數按鈕 searching: false,//是否開始本地搜索 stateSave: false,//刷新時是否保存狀態 autoWidth: true,//自動計算寬度 deferRender: true,//延遲渲染 serverSide: true,//開啟伺服器模式 //獲取數據 ajax: { "url": ctx + "/getList", "type": 'POST', //綁定額外參數 "data": function (d) { return $.extend({}, d, { "id":$("#user_id").val() }); } }, //設置數據 columns: [ {data: "userId", defaltContent:"空"}, {data: "name", defaultContent:"空"}, {data: "sex", defaultContent: "未知性別"}, {data: "age", defaultContent: 0}, {data: "birth", defaultContent: "未知",render:function (date) { return moment(date).format("yyyy-mm-dd hh:mm:ss") }} ] });
主要:開啟伺服器模式;開啟ajax獲取數據;設置數據;
這裡還用到了render函數,做數據處理,如果會js的同學應該一下就懂了,不懂就把它當成回調函數。
springboot服務端
controller層
DatatableController.java
@Controller public class DatatablesController { private final UserService userService; @Autowired public DatatablesController(UserService userService) { this.userService = userService; } /** * 返回視圖 * @return view */ @RequestMapping("/index") public String index(){ return "index"; } /** * 獲取全部數據 * @return list */ @RequestMapping("/getList") @ResponseBody public DataTable getList(User user,Order order, Integer start,Integer length, Integer draw){ PageInfo pageInfo = userService.selectByPageNumSize(user, start, length); List<User> users = pageInfo.getList(); long total = pageInfo.getTotal(); return DataTableBulid.build(draw, (int) total,users); } /** * 手動插入1000 * @return string */ @RequestMapping("/insert") @ResponseBody public String insert(){ for (int i = 0; i < 1000; i++) { String s = RandomStringUtils.randomAscii(8); User user = new User(); user.setName(s); user.setAge(RandomUtils.nextInt(1, 1000)); user.setBirth(new Date()); user.setSex(RandomStringUtils.randomAscii(1)); userService.save(user); } return "success"; } }
當你開啟伺服器模式serverside,datatables會主動提交一些參數過來,具體查看官網http://datatables.club/manual/server-side.html,下面貼出一些官網的內容.
返回給datatables的數據也有點講究,這裡我是按照官網的說明,封裝一個datatable的類。詳細說明看官網http://datatables.club/manual/server-side.html
DT自動請求的參數(Sent parameters) 當開啟了 伺服器模式時,DataTables 會發送如下參數到伺服器
名稱 |
類型 |
描述 |
---|---|---|
draw |
integerJS |
繪製計數器。這個是用來確保Ajax從伺服器返回的是對應的(Ajax是非同步的,因此返回的順序是不確定的)。 要求在伺服器接收到此參數後再返回(具體看 下面) |
start |
integerJS |
第一條數據的起始位置,比如0代表第一條數據 |
length |
integerJS |
告訴伺服器每頁顯示的條數,這個數字會等於返回的 data集合的記錄數,可能會大於因為伺服器可能沒有那麼多數據。這個也可能是-1,代表需要返回全部數據(儘管這個和伺服器處理的理念有點違背) |
伺服器需要返回的數據(Returned data) 一旦 DataTables 發送了請求,上面的參數就會傳送給伺服器,那麼你需要接受到這些參數並做相應的邏輯處理然後按照下面的格式講組裝好的JSON數據返回 (不是每個參數都需要接受處理,根據自己的業務需要)
名稱 |
類型 |
描述 |
---|---|---|
draw |
integerJS |
必要。上面提到了,Datatables發送的draw是多少那麼伺服器就返回多少。 這裡注意,作者出於安全的考慮,強烈要求把這個轉換為整形,即數字後再返回,而不是純粹的接受然後返回,這是 為了防止跨站腳本(XSS)攻擊。 |
recordsTotal |
integerJS |
必要。即沒有過濾的記錄數(資料庫里總共記錄數) |
recordsFiltered |
integerJS |
必要。過濾後的記錄數(如果有接收到前台的過濾條件,則返回的是過濾後的記錄數) |
data |
arrayType |
必要。表中中需要顯示的數據。這是一個對象數組,也可以只是數組,區別在於 純數組前台就不需要用 columns綁定數據,會自動按照順序去顯示 ,而對象數組則需要使用 columns綁定數據才能正常顯示。 注意這個 data的名稱可以由 ajaxOptionajax不定時一講 的 ajax.dataSrcOption ajax.dataSrc 1不定時一講ajax.dataSrc 2不定時一講 控制 |
error |
stringJS |
可選。你可以定義一個錯誤來描述伺服器出了問題後的友好提示 |
service層
UserServiceImpl.java
這裡我使用的tk.mybatis做通用service和通用mapper。 把datatables傳過來的參數start 和 length 作為pagehelper的offset 和 pageSize.
@Service public class UserServiceImpl extends BaseService<User> implements UserService { @Resource UserMapper userMapper; @Override public PageInfo selectByPageNumSize(User user, int pageNum, int pageSize) { PageHelper.offsetPage(pageNum, pageSize); List<User> users = userMapper.selectByPageNumSize(user); return new PageInfo<>(users); } }
dao層
UserMapper.java
public interface UserMapper extends MyMapper<User> { /** * @param user * @return */ List<User> selectByPageNumSize( @Param("user") User user); }
UserMapper.xml
<select id="selectByPageNumSize" resultType="my.suveng.demo.model.domain.User"> select * from sys_user </select>
資料庫文件
DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `user_id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `age` int(11) NULL DEFAULT NULL, `birth` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0), PRIMARY KEY (`user_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 11001 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; SET FOREIGN_KEY_CHECKS = 1;
測試數據的話,我已經寫了一個介面放在controller那裡了。 具體查看程式碼倉庫:
datatables使用教程
分支的ajax非同步帶參數獲取數據源
效果截圖

分頁和數據展示都做好了,那麼現在就來做一個搜索條件吧,項目來講,搜索這個功能是必不可少的。
搜索條件,整合服務端,利用mybatis動態sql
步驟
前端步驟:
- 添加搜索條件輸入框和搜索框
- 獲取搜索條件輸入
- 添加datatables的額外參數,傳給服務端介面
服務端步驟:
- 編寫controller介面,接收搜索參數,處理完,返回datatables對象(自己封裝的)
- 編寫service業務邏輯,處理數據,返回給controller
- 編寫dao,自定義sql 篩選數據,返回給service
示例程式碼
前端
index.ftl
添加搜索條件輸入框和搜索框
<html> <#include "common/head.ftl"> <body> <form> <input type="text" id="sch_userId" placeholder="請輸入userID..."> <input type="button" id="doQuery" value="搜索"> <input type="reset" value="重置"> </form> <table id="t1"> <thead> <tr> <th>編號</th> <th>姓名</th> <th>性別</th> <th>年齡</th> <th>生日</th> </tr> </thead> <tbody> </tbody> </table> </body> </html> <#include "common/footer.ftl"> <script src="/js/index.js"></script>
添加datatables的額外參數,傳給服務端介面
index.js
$(function () { $("#doQuery").click(doQuery); }); var doQuery=function (){ datatables.api().ajax.reload(); }; var datatables = $("#t1").dataTable({ language: { "decimal": "",//小數的小數位符號 比如「,」作為數字的小數位符號 "emptyTable": "沒有數據喲~~",//沒有數據時要顯示的字元串 "info": "當前 _START_ 條到 _END_ 條 共 _TOTAL_ 條",//左下角的資訊,變數可以自定義,到官網詳細查看 "infoEmpty": "無記錄",//當沒有數據時,左下角的資訊 "infoFiltered": "(從 _MAX_ 條記錄過濾)",//當表格過濾的時候,將此字元串附加到主要資訊 "infoPostFix": "",//在摘要資訊後繼續追加的字元串 "thousands": ",",//千分位分隔符 "lengthMenu": "每頁 _MENU_ 條記錄",//用來描述分頁長度選項的字元串 "loadingRecords": "載入中...",//用來描述數據在載入中等待的提示字元串 - 當非同步讀取數據的時候顯示 "processing": "處理中...",//用來描述載入進度的字元串 "search": "搜索",//用來描述搜索輸入框的字元串 "zeroRecords": "沒有找到",//當沒有搜索到結果時,顯示 "paginate": { "first": "首頁", "previous": "上一頁", "next": "下一頁", "last": "尾頁" } }, processing: true,//是否顯示處理狀態(排序的時候,數據很多耗費時間長的話,也會顯示這個) lengthChange: true,//是否允許用戶改變表格每頁顯示的記錄數 orderMulti: true, //啟用多列排序 ordering: true,//使用排序 bStateSave: true,//記錄cookie paging: true,//是否分頁 pagingType: "full_numbers",//除首頁、上一·頁、下一頁、末頁四個按鈕還有頁數按鈕 searching: false,//是否開始本地搜索 stateSave: false,//刷新時是否保存狀態 autoWidth: true,//自動計算寬度 deferRender: true,//延遲渲染 serverSide: true,//開啟伺服器模式 //獲取數據 ajax: { "url": ctx + "/getList", "type": 'POST', //綁定額外參數 "data": function (d) { return $.extend({}, d, { "userId":$("#sch_userId").val() }); } }, //設置數據 columns: [ {data: "userId", defaltContent:"空"}, {data: "name", defaultContent:"空"}, {data: "sex", defaultContent: "未知性別"}, {data: "age", defaultContent: 0}, {data: "birth", defaultContent: "未知",render:function (date) { return moment(date).format("yyyy-mm-dd hh:mm:ss") }} ] });
服務端
controller層接收參數
還是原來的程式碼,只不過這次前端是會有值傳過來了。這個值我一般會封裝到vo對象裡面,這裡我封裝到user裡面
@RequestMapping("/getList") @ResponseBody public DataTable getList(User user, Order order, Integer start, Integer length, Integer draw) { PageInfo pageInfo = userService.selectByPageNumSize(user, start, length); List<User> users = pageInfo.getList(); long total = pageInfo.getTotal(); return DataTableBulid.build(draw, (int) total, users); }
dao層:編寫篩選條件的動態sql
UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="my.suveng.demo.dao.mysql.UserMapper"> <resultMap id="BaseResultMap" type="my.suveng.demo.model.domain.User"> <!-- WARNING - @mbg.generated --> <id column="user_id" jdbcType="BIGINT" property="userId" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="sex" jdbcType="VARCHAR" property="sex" /> <result column="age" jdbcType="INTEGER" property="age" /> <result column="birth" jdbcType="TIMESTAMP" property="birth" /> </resultMap> <sql id="search_condition"> where 1=1 <if test="record.userId !=null"> and u.user_id = #{record.userId,jdbcType=BIGINT} </if> </sql> <select id="selectByPageNumSize" resultMap="BaseResultMap"> select * from sys_user u <include refid="search_condition"/> </select> </mapper>
具體查看程式碼倉庫:
datatables使用教程
分支的搜索條件
效果截圖

參考文章