datatable.js 服务端分页+fixColumns列固定
前言
記得還是15年的時候,工作需要,獨自寫后臺管理系統。。記得那時候,最讓我頭疼的不是后臺邏輯,而是數據的列表展示。?列很多的時候,頁面顯示問題;分頁樣式問題;表格樣式問題;數據加載...很多細節的問題,費時,而且總是達不到我想要的效果...也是那個時候,第一次接觸了datatable.js插件,只需要簡單的修改配置值,就可以改變表格的方方面面,真的是非常好的體驗。。。
不過,因為一些歷史原因,和時間問題,那時候對 ajax加載+服務端分頁+頁面刷新,仍然是一直很迷迷糊糊...剛好最近工作中需要做一個列表管理頁,所以就很自然的選擇了datatable.js,并且總算把 ?ajax加載數據+服務端分頁+reload這套流程弄通。也許還有很多種方案可以達到效果,但至少這個是肯定可行的.
樣式是基于bootstrap風格.
正文
一.前端
需要引的js文件
<!-- datatables樣式和bootstrap支持樣式 --> <link rel="stylesheet" type="text/css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/plug-ins/28e7751dbec/integration/bootstrap/3/dataTables.bootstrap.css"><script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-1.10.2.min.js"></script> <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script> <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/plug-ins/28e7751dbec/integration/bootstrap/3/dataTables.bootstrap.js"></script> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script><!--form ajax提交--> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.form/4.2.1/jquery.form.js"></script>?
html部分
<!-- search 框start --> <div class="container"><nav class="navbar navbar-default"><div class="container-fluid"><!-- Collect the nav links, forms, and other content for toggling --><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><form class="navbar-form navbar-left"><div class="form-group"><input type="text" class="form-control" placeholder="用戶姓名" name="userName" id="searchUserName"></div>&<div class="form-group"><input type="text" class="form-control" placeholder="律所名" name="officeName" id="searchOfficeName"></div>&<div class="form-group"><input type="number" class="form-control" placeholder="狀態" name="be_valid" id="searchValid"></div><button type="button" class="btn btn-success" onclick="searchData()">搜索</button></form><form class="navbar-form navbar-right"><button type="button" class="btn btn-primary btn-sm btn-warning" data-toggle="modal" data-target="#addModal">新增律所</button></form></div><!-- /.navbar-collapse --></div><!-- /.container-fluid --></nav> </div> <!-- search 框end --> <div class="container"><table id="mytable" class="table table-striped table-bordered table-hover" cellspacing="0" width="100%" style="white-space: nowrap;"><thead><tr><th>用戶名</th><th>用戶ID</th><th>郵箱</th><th>身份</th><th>律所</th><th>律所id</th><th>律所簡報</th><th>律所創建時間</th><th>限制人數</th><th>驗證碼</th><th>狀態</th><th>備注信息</th><th>操作</th></tr></thead><tbody></tbody><tfoot><tr><th>用戶名</th><th>用戶ID</th><th>郵箱</th><th>身份</th><th>律所</th><th>律所id</th><th>律所簡報</th><th>律所創建時間</th><th>限制人數</th><th>驗證碼</th><th>狀態</th><th>備注信息</th><th>操作</th></tr></tfoot></table> </div>因為是服務端分頁,所以我頁面做了搜索框,進行自定義的參數搜索.
?
js部分?
<script type="text/javascript">var oTable;$(function(){LoadData();});function searchData(){oTable.draw(true); // oTable.ajax.reload(null,true); }function LoadData() {oTable = $('#mytable').DataTable({//sDom: 'T<"clear">lfrtip', oLanguage: {sZeroRecords: "對不起,查詢不到任何相關數據",sInfoEmpty: "記錄數為0"},sScrollX: "100%",sScrollXInner: "110%",bScrollCollapse: false, //可滾動bDestory: true, //數據允許清空bServerSide: true, //服務端處理分頁bLengthChange: false, //是否允許自定義每頁顯示條數.iDisplayLength: 20, //每頁顯示10條記錄bPaginate: true, //是否分頁//sPaginationType: "amaze", //分頁樣式 "full_numbers"//bJQueryUI: true,//是否將分頁樣式應用到表格bProcessing: true, //當datatable獲取數據時候是否顯示正在處理提示信息。bFilter: false, //是否啟用條件查詢bSearchable: false,//bStorable: false,//是否啟用列排序//bInfo: true, //是否顯示分頁信息(頁腳信息)order: [[7, "desc"]], //默認按照第幾列排序,從1開始bAutoWidth: false, //自動寬度bStateSave: true, //狀態保存,使用了翻頁或者改變了每頁顯示數據數量,會保存在cookie中,下回訪問時會顯示上一次關閉頁面時的內容 ajax:{dataType:'json',type:'POST',url: '/adminUserList',headers: {'token': window.localStorage.token //取localStorage中的token,用來做安全校驗},dataSrc: "aaData",data:function(d){//取搜索的參數值,在請求服務端時,附加到請求參數中var userName=$('#searchUserName').val();var officeName=$('#searchOfficeName').val();var be_valid=$('#searchValid').val();d.userName=userName;d.officeName=officeName;d.be_valid=be_valid;}},columns: [{data: "name",bSortable: false},{data: "user_id",bSortable: false},{data: "email",bSortable: false},{data: "level_name",bSortable: false},{data: "office_name",bSortable: false},{data: "office_id",bSortable: false},{data: "officeBriefing",bSortable: false},{ data: "office_create_time"},{data: "limited_num",bSortable: false},{data: "verify_code",bSortable: false},{data: "be_valid",bSortable: false},{data: "remark",bSortable: false},{data: null,render: function (data, type, row) {return '<button type="button" class="btn btn-primary btn-sm" οnclick="editShow(\''+data.user_id+'\')">編輯</button>';},bSortable: false}]});} </script>
二.后端
java服務端代碼
@ResponseBody@RequestMapping(value = "/adminUserList",method = RequestMethod.POST)public AjaxListResponseDTO<AppUserShowDTO> getAdminUserList(@ApiParam(required = true, name = "start", value = "開始條數") @RequestParam Integer start,@ApiParam(required = true, name = "length", value = "取多少條") @RequestParam Integer length,@ApiParam(required = true, name = "userName", value = "用戶名") @RequestParam String userName,@ApiParam(required = true, name = "officeName", value = "律所名") @RequestParam String officeName,@ApiParam(required = true, name = "be_valid", value = "狀態") @RequestParam Integer be_valid,HttpServletRequest request) throws Exception{// Map<String,String[]> paramMap=request.getParameterMap(); String[] orderTypeArr=request.getParameterValues("order[0][dir]");String lawOfficeOrderType="";if(null!=orderTypeArr){lawOfficeOrderType=orderTypeArr[0];}AjaxListResponseDTO<AppUserShowDTO> responseDTO=new AjaxListResponseDTO<>();//datatable.js 相關參數String[] drawStrArr=request.getParameterValues("draw");if(null!=drawStrArr){responseDTO.setSEcho(Integer.parseInt(drawStrArr[0]));}Page<AppUserShowDTO> appUserShowDTOPage = authUserService.findAllUserAndLawOffice(userName,officeName,be_valid,null!=start?start:0,null!=length?length:20,lawOfficeOrderType,"超級管理員");responseDTO.setITotalRecords((int) Math.ceil(appUserShowDTOPage.getTotal()));//實際需要傳數據總數,此處值不對responseDTO.setITotalDisplayRecords((int) Math.ceil(appUserShowDTOPage.getTotal()));responseDTO.setAaData(appUserShowDTOPage.getResult());return responseDTO;}start(起始條數,注意,是條數而不是頁數 )和length(取多少條數據)為datatable默認會傳到服務端的2個參數, userName/officeName/be_valid則為我前端自定義的附加參數。
Page是List<T>泛型集合,是開源項目PageHelper-mybatis中的類。
服務端返回給前端的json數據也有格式要求,具體見AjaxListResponseDTO類定義.
/*** Created by xinhuiyang on 2017/6/9.*/ @Data public class AjaxListResponseDTO<T>{private Integer sEcho;private Integer iTotalRecords;private Integer iTotalDisplayRecords;private List<T> aaData; }?
自此,就實現了帶搜索功能的服務端分頁效果.
三. FixColumn(固定第一列和最后一列效果)
首先,在之前的基礎上,需要添加一個js文件引用
<!-- 固定列 插件js --><script src="https://cdn.datatables.net/fixedcolumns/3.2.2/js/dataTables.fixedColumns.min.js"></script>
其次,在配置項中添加一項:
oTable = $('#mytable').DataTable({//sDom: 'T<"clear">lfrtip', oLanguage: {sZeroRecords: "對不起,查詢不到任何相關數據",sInfoEmpty: "記錄數為0"},sScrollX: "100%",sScrollXInner: "110%",bScrollCollapse: false, fixedColumns: { //固定列的配置項leftColumns: 1, //固定左邊第一列rightColumns:1 //固定右邊第一列 },bDestory: true, bServerSide: true, .....省略......然后,刷新頁面...至此,固定列效果就ok了。
?
后言
現在的頁面效果,還有2個瑕疵:
其一是后臺返回"總條數"不對,我是時間趕,來不及寫查詢了..大家實際使用時,自己查詢一下就行,這個好解決;
其二是前端頁面,下角顯示頁碼總數和頁腳信息顯示有問題(見下圖),不知道當后臺"總條數"準確時,會不會就ok了。我后面還會找個時間,去修復一下的...當我有解決方案時,會補充在下面的,大家有知道原因和解決方案的,也歡迎評論在下方。
頁腳圖
1.左邊數字沒顯示出來. ?
2.實際83條數據,每頁20條,應該最多到5頁的,但實際上,可以點任意頁,只不過從第6頁開始,數據都為空.
?
補充
頁面顯示不對的問題已經找到原因并且解決.
原因是:后端分頁時,需要返回給前端更多的信息,如總數多少,過濾后多少等,所以我代碼中的AjaxListResponseDTO類就不符合后端分頁時的需求了,需要改動.
修改后的類定義為:
/*** Created by xinhuiyang on 2017/6/9.*/ @Data @ApiModel public class AjaxListResponseDTO<T>{@ApiModelProperty("必要。上面提到了,Datatables發送的draw是多少那么服務器就返回多少。 這里注" +"意,作者出于安全的考慮,強烈要求把這個轉換為整形,即數字后再" +"返回,而不是純粹的接受然后返回,這是 為了防止跨站腳本(XSS)攻擊。")private Integer draw;@ApiModelProperty("必要。即沒有過濾的記錄數(數據庫里總共記錄數)")private Integer recordsTotal;@ApiModelProperty("必要。過濾后的記錄數(如果有接收到前臺的過濾條件,則返回的是過濾后的記錄數)")private Integer recordsFiltered;@ApiModelProperty("必要。表中中需要顯示的數據。這是一個對象數組,也可以只是" +"數組,區別在于 純數組前臺就不需要用 columns綁定數據,會自動按照順序" +"去顯示 ,而對象數組則需要使用 columns綁定數據才能正常顯示。")private List<T> aaData;@ApiModelProperty("可選。你可以定義一個錯誤來描述服務器出了問題后的友好提示")private String error; }相應的,controller部分代碼,也要給對應的屬性附上正確的值,改動后代碼如下:
@ResponseBody@RequestMapping(value = "/adminUserList",method = RequestMethod.POST)public AjaxListResponseDTO<AppUserShowDTO> getAdminUserList(@ApiParam(required = true, name = "start", value = "開始條數") @RequestParam Integer start,@ApiParam(required = true, name = "length", value = "取多少條") @RequestParam Integer length,@ApiParam(required = true, name = "userName", value = "用戶名") @RequestParam String userName,@ApiParam(required = true, name = "officeName", value = "律所名") @RequestParam String officeName,@ApiParam(required = true, name = "be_valid", value = "狀態") @RequestParam Integer be_valid,HttpServletRequest request) throws Exception{// Map<String,String[]> paramMap=request.getParameterMap(); String[] orderTypeArr=request.getParameterValues("order[0][dir]");String lawOfficeOrderType="";if(null!=orderTypeArr){lawOfficeOrderType=orderTypeArr[0];}AjaxListResponseDTO<AppUserShowDTO> responseDTO=new AjaxListResponseDTO<>();//datatable.js 相關參數String[] drawStrArr=request.getParameterValues("draw");if(null!=drawStrArr){responseDTO.setDraw(Integer.parseInt(drawStrArr[0]));}int totalCountBeforeFilter=authUserService.countUserByLevel("超級管理員");Page<AppUserShowDTO> appUserShowDTOPage = authUserService.findAllUserAndLawOffice(userName,officeName,be_valid,null!=start?start:0,null!=length?length:20,lawOfficeOrderType,"超級管理員");responseDTO.setAaData(appUserShowDTOPage.getResult());responseDTO.setRecordsTotal(totalCountBeforeFilter);responseDTO.setRecordsFiltered((int) appUserShowDTOPage.getTotal());return responseDTO;}然后,頁面的頁碼顯示就正確了(如圖):
?
?
?
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利;
本文出自:博客園--別問是誰
?
轉載于:https://www.cnblogs.com/Andrew-XinFei/p/7020055.html
總結
以上是生活随笔為你收集整理的datatable.js 服务端分页+fixColumns列固定的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冷知识 —— 地理
- 下一篇: 前后端开发是怎么合作分工的