DataTables ajax bootstrap 分页/搜索/排序/常见问题
最近学校的网站建设需要,尝试使用了下Jquery dataTables控件,我使用的是官网最新的DataTables-1.10.15版本,个人在使用的过程中遇到了相当多的问题,有的是数据显示问题,还有的是request unknown parameter xxx for row..,还有搜索带来的刷新之后无法还原问题,这些问题我下面会逐一解释
个人感觉dataTables对于第一次接触的人来说,属性超多,让人看的眼花缭乱.我在网上搜到的大部分资料感觉对于新手来说有些复杂,特别是ajax请求那块,由于dataTables提供的ajax请求方式非常多,加上各个版本的函数和属性名等的差异,让人看的很是头疼,不多说进入正题
1.使用步骤
1.1引入必须的js,css文件等我就不在重复了,这里需要注意的是如果你是在使用了网上的模板从而需要对模板中的dataTable进行拓展的话,请你一定搞清楚你使用的版本,否则你在写代码时可能会遇到属性名和官方给出的不一致的问题,其次你的html部分至少要有<table>标签和<thead>
1.2初始化与常见属性介绍
先说一个看上去复杂实则很简单的属性------------国际化(语言配置):其他的一些未标注的属性与之相类似
其他零散属性:
还有一个重要属性columnsDefs,这个属性用来设置列的属性,他不一定要和你的表格的列的数目完全一样,
targets属性指定列,orderable属性表示此列是否参与排序,name是对这一列的描述,title当然是列名了,最重要的有两个
data和render,其中data负责指定数据源,他指定的是你从服务器返回的json数据中的实体对象的属性(事实上你也可以直接写数组),这个属性下面分页时还会具体讲,
render英文意为渲染,可以看到render中带有data参数,可以把他理解为对数据的进一步处理,可以看到我的第一列使用了render,他构造了一个checkbox填充到了第一列中,并没有
使用从服务器返回的data
"columnDefs": [
{
"targets":[0],
"render": function(data, type, row, meta) {
return '<label><input type="checkbox" class="ace" /><span class="lbl"></span></label>';
},
"orderable":false,
"width":"50px"
},
{
"title":"序号",
"name":"1_id",
"data":"id",
"targets":[1],
"width":"50px",
"orderable":false,
},
{
"title":"新闻标题",
"name":"2_title",
"data":"title",
"targets":[2],
"render":function(data) {
if(data.length > 25) {
data = data.substring(0,25) + "...";
}
return data;
},
"orderable":false,
"width":"400px"
},
{
"data":null,
"targets":[3],
"visible": false,
"searchable": false,
"orderable":false
},
{
"title":"发布时间",
"name":"4_releaseTime",
"data":"releaseTime",
"targets":[4],
"width":"300px",
"orderable":true,
"orderData":[4],
},
{
"title":"所在板块",
"name":"5_smallId",
"data":"menu.name",
"targets":[5],
"width":"300px",
"orderable":true,
"orderData":[5],
},
{
"title":"操作",
"targets":[6],
"render":function(data,type,row,meta) {
var newsId = row.id;
//<a class="green" data-toggle="tooltip" data-placement="top" title="查看详细" href="#"><i class="icon-pencil bigger-130"></i></a>
return '<div class="visible-md visible-lg hidden-sm hidden-xs action-buttons"><a class="blue" data-toggle="tooltip" data-placement="top" title="查看详细" href="#"><i class="icon-zoom-in bigger-130"></i></a> <a class="red" data-toggle="tooltip" data-placement="top" title="删除" href="#"><i class="icon-trash bigger-130"></i></a></div><div class="visible-xs visible-sm hidden-md hidden-lg">';
},
"orderable":false,
"width":"200px"
}
],
infoCallBack,这是一个回调函数(属性),在表格状态信息改变后进行调用,所谓状态信息个人认为指的是表格的分页参数(长度,页码),和排序,绘制等一列信息,
"infoCallback": function(settings,start,end,max,total,pre) {
//激活工具提示
$("[data-toggle='tooltip']").tooltip();
//图标功能
$("#sample-table-2 tbody").on( 'click', 'tr', function () {
var id = $(this).find("td").eq(1).text();
if(id) {
$(".blue").attr("href","${pageContext.request.contextPath}/newsController/edit.action?id="+id);
}
});
$(".red").click(function() {
$(this).parents("tr").find("td").eq(0).find(":checkbox").attr("checked",true);
var ids = new Array();
//添加id到数组
$(":checkbox:checked").each(function(i) {
if($(this).parents("tr").find("td").eq(1).text()) {
ids[i] =$(this).parents("tr").find("td").eq(1).text();
}
})
if(window.confirm("确定要删除吗?")) {
if(ids.length>0) {
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/newsController/hide.action",
data:{"ids":ids},
traditional :true,
success:function(){
window.location.reload();
}
})
}
}
});
var api = this.api();
var pageInfo = api.page.info();
// alert(JSON.stringify(pageInfo));
return "共"+pageInfo.pages +"页,当前显示"+ start + "到" + end + "条记录" + ",共有"+ total + "条记录";
},
上面讲到的属性及函数只是我用到的,有些属性下面会具体的讲有不清楚的可以到官网去查,这里只做一个简略介绍
1.3分页
建议刚开始使用的时候不要想着什么排序,搜索之类的,你先把你的数据显示出来再说
1.3.1环境:springmvc+hibernate+spring+mysql
分页的话先要开启服务器模式,把分页交给服务器来处理,之后调用ajax,请求成功后数据渲染,ok了
说起来很容易,但要讲起来很多,在你开启服务器模式 "serverSide": true并且进行ajax请求时发生了这些事情
首先你的dataTables向服务器端发生了很多参数,比如draw(表格绘制次数).length(每页显示的数据量),start,page等参数
那么你的服务器接收到请求后又发生了什么?draw,data(返回的数据),recordsTotal(总记录数),好了现在可以讲ajax如何
发生请求,官网上有很多种ajax的写法,我挑了种我自己比较能接受的一种,你自己做的时候可以试下alert(JSON.stringify(data))看看
dataTables发送的data到底有哪些参数(以下部分代码来自官网的demo)
1 "ajax":function(data,callback,settings) {
2 //参数封装
3 var param = {};
4 param.draw = data.draw;
5 param.limit = data.length;//页面显示记录条数,在页面显示每页显示多少项的时候
6 param.start = data.start;//开始的记录序号
7 param.page = (data.start / data.length)+1;
8 param.filter = data.search.value;//过滤条件
9 // alert(JSON.stringify(data));
10 alert(JSON.stringify(data.order))
11 //单排序条件
12 /* if(data.order) {
13 if(data.order[0].dir) {
14 param.order = "releaseTime" + " " + data.order[0].dir;
15 }
16 } */
17 //多排序条件
18 param.order = " ";
19 if(data.order) {
20 $.each(data.order,function(index,value){
21 var col = data.order[index].column;
22 $.each(data.columns,function(i,v) {
23 var name = data.columns[i].name;
24 if(name) {
25 if(col == window.parseInt(name)) {
26 var arr = name.split("_");
27 param.order += arr[1] + " " + data.order[index].dir + ",";
28 }
29 }
30 })
31 })
32 }
33 param.order= param.order.substring(0,param.order.length-1);
34 $.ajax({
35 type:"POST",
36 url:"${pageContext.request.contextPath}/newsController/getAllNews.action",
37 data:param,
38 cache:false,
39 dataType:"json",
40 success:function(result) {
41 var returnData = {};
42 returnData.draw = result.draw;//个人感觉这里直接写data.draw也可以
43 returnData.recordsTotal = result.recordsTotal;//返回数据全部记录
44 returnData.recordsFiltered = result.recordsFiltered;//后台不实现过滤功能,每次查询均视作全部结果
45 returnData.data = result.data;//返回的数据列表
46 //更改时间格式
47 for(var i=0;i<result.data.length; i++) {
48 result.data[i].releaseTime = new Date(result.data[i].releaseTime).toLocaleDateString();
49 }
50 //回调函数(数据渲染)
51 callback(returnData);
52 },
53 error:function(ajax,textStatus) {
54 /* alert(JSON.stringify(ajax));
55 alert(textStatus); */
56 alert("未找到数据");
57 }
58 })
59 },
既然ajax发送了请求,服务器该如何应答?
好了应答完毕,轮到客户端渲染了,还记得上面讲属性时的columnDefs中的data属性吗?上面说了他用来指定数据源,请结合我的实体类对象News
你会发现我上面columnDefs中的data的值对应着我的实体类,因为我在服务器端的map中返回了一个List<News>,这可以理解为一种映射
好了,既然数据源指定完毕,处理下result,如果你对传回的result不需要特殊处理(如调整时间格式等直接把result传到callback中也是可以的,),直接渲染就好了
至此,分页解决,总结如下
1.开启serverside,调用ajax
2.封装分页参数发送给服务端,同时指定好数据源
3.服务器段返回规定的必要参数
4.渲染
常见分页问题:
1.request unknown parameter xxx for row..,
检查的你的列的设置,我之前设置了一个列隐藏,但是忘记指定隐藏列的数据源,导致此错误
2.分页数据显示不全,明明有20条数据,下拉菜单选择每页显示10条数据时只有一页
检查你返回的recordsTotal与recordsFiltered参数是否符合你期望的数据总量
1.4搜索
我这里做的搜索极其简单,仅仅是新闻的标题检索,本来老师说可以用luence,然而没接触过,先用like凑合吧
1.4.1自定义搜索框
官网给出的搜索框连个搜索图标都没得,所以只能是key up事件触发搜索,遂改之,加了个bootstrap官网的搜索图标
1 var search = "<div class='input-group'><input type='search' class='form-control input-sm' placeholder='标题检索' aria-controls='sample-table-2'><div class='input-group-addon'><span class='glyphicon glyphicon-search' id='search'></span></div></div>";
2 $("#sample-table-2_filter label").html(search);
3 $(".glyphicon-search").css("cursor","pointer");
1.4.2搜索请求的发送
思路:获取搜索框的值,然后发送,返回数据后重新绘制表格即可(draw)
当你为搜索图标绑定点击事件调用search方法后你会发现后台接收到了一次ajax请求,而且这个这个请求中包含的参数很熟悉,你上面分页时的draw,start等参数
居然都包含在这次ajax请求中,so你的search方法调用的是你上面分页时的ajax请求,所以我们考虑如何在我们上面写的ajax请求中加入过滤条件,把filter传入search方法
中,之后在你的ajax请求中的data的json结构里会发现data.search.value出现了filter的值(上面说过,在发送请求前打印下data的值你会有很多发现),于是参数的封装与接收就
顺理成章了,返回数据渲染什么的都不用动了注意变下你的sql语句就可以了
常见搜索问题:
到这儿搜索似乎结束了,然而还有一个问题,但你输入了一个条件进行搜索后,你会发现即使你刷新页面,所呈现的仍然是你上次
搜索时输入的条件过滤后的结果,查看后台发现此时的filter仍然还有值,不要慌张,也不要尝试什么param.filter = null,able.state.clear()之类的清除,没有用,
只需要在你初始化表格时加入"stateSave":false,即可,因为dataTable会把这些状态信息储存到cookie中,把状态保存设置为false即可,当然你也可以再加一个显示全部的按钮之类的........
总结:
1.属性中的搜索开关要开启,参数封装
2.可以设置某列searchable为false
3.状态保存
1.5排序
讲完了分页与搜索,接下来说说排序吧
我在网上找到的全是"单列排序",为什么这么说呢,很多例子是初始化的时候是多列排序
然而你点击某一列的排序后,其他列的排序就失效了,即不同列的排序似乎会相互影响这里给出的是一个
"单列排序",还有我做两列排序时目前仍然没有解决的问题,希望有前辈可以解答
1.5.1单列排序
初始化时加入以下属性
1 "ordering":true,//排序总开关
2 "order":[[4,"desc"],[5,"desc"]],
3 "orderFixed":{
4 "post": [[ 4, "desc" ],[5,"desc"]]
5 }, //固定排序,下面讲
先忽略orderfixed(注释掉),下面多列排序时会讲,
此处order属性指定第5,6列均降序排列,当然你也可以使用table.order([4,"desc"],[5,"desc"]).draw();方法进行设置,
下面讲如何封装参数,还记得上面讲搜索的时候参数如何封装的吗?对的,线索还在data里面,但是你会发现data.order
中有列的索引(column)和升降序(dir),但我们排序需要的是字段名啊,只有索引怎么办?贴下data里的数据吧
data.columns.name属性会帮助我们的.
再次回到上面讲columnDefs属性时讲到列有一个name属性用来描述列,于是我上面的列写成了这样
name中既有索引,又有我们需要的字段名,所以遍历data.columns找到和data.order中重叠的列,拼装排序参数
最后一步是为了去除多余的","
接下来又是发送请求,接收参数,返回数据渲染了,当然你要变的还是你的sql如果你感觉遍历太麻烦,直接指定param.order也可以
页面渲染完成后大概就是这样,可以看到是降序,so问题来了,当你点击某个排序列时,比如点击发布时间这一列,你会变为升序,但问题也来了,他的邻居发布板块列的排序参数会变成
对的,这个列退出排序了,如果你的后台打印了order的话,你会看到此时的order参数只有releaseTime asc,这也是我为什么说都是单列排序的原因
(今天问了老师,得到的答案是对啊就是这样的点击排序列其他列退出排序...和我预期的不太一样)
补充一点columnDefs属性中还有有一个orderSequence和orderData属性,用来设置排序的方向和排序的数据
1.5.2多列排序(建议跳过)
这个例子是我目前正在做的,相信上面的例子已经能够满足一个新手的需要,有点绕,可pass
我正在做的是一个多列排序:要实现这么一个功能,即点击排序列A时,排序列B不受影响,也就是保持之前的状态参与排序
用到了orderFixed属性,orderFixed属性用来设置排序始终作用于表格,始终作用代表着当你点击某个排序列时其余的列仍然参与排序
但也带来了新的问题(目前还未解决),这个待会再说.
orderFixed内部有两个属性,pre和post,前者代表orderFixed的设置在排序前起作用,后者代表在排序发生后起作用,
什么意思呢?假设你的order和orderFixed分别设置成如图:
页面渲染后如图:
可见orderFixed设置的降序起了作用(虽然是升序的三角),但是当你点击排序列的时候他不会显示成升序,这是因为你的
orderFixed属性内部设置成了pre,在排序前生效,贴下此时的data.order,显然orderFixed的设置在前,
所以是orderFixed的排序方式生效
post与pre相反,代表之后
所以页面是order设置的升序(在前面)起了效果:
好了,现在我们使用orderFixed实现了这种支持点击的多列排序,现在说说问题吧,我们想要的多列排序是这样一种:即点击排序列A时排序列B的排序条件保持不变且仍然参与排序
初始化时的data.order,均为降序
这样设置带来的问题如下:先点击下第5列发布时间,可以看到第5列变成了升序,第6列依然保持降序
然而当你点击第6列所在板块时,第5列被改成了降序!
似乎二者总是会相互影响...暂时未解决
补充一下单独使用orderFixed也会遇到这种问题
总结:
1.排序总开关要打开
2.设置order对排序进行指定
3.可以在列中使用orderable指定本列是否参与排序,orderSequence指定点击时的排序方向
1.6用到的代码
js
1 jQuery(function($) { 2 var oTable1 = $("#sample-table-2").DataTable({ 3 "language":{ 4 "sProcessing": "处理中...", 5 "sLengthMenu": "显示 _MENU_ 项结果", 6 "sZeroRecords": "没有匹配结果", 7 "sInfo":"显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项", 8 "sInfoEmpty": "显示第 0 至 0 项结果,共 0 项", 9 "sInfoFiltered": "(由 _MAX_ 项结果过滤)", 10 "sInfoPostFix": "", 11 "sSearch": "搜索:", 12 "sUrl": "", 13 "sEmptyTable":"表中数据为空", 14 "sLoadingRecords": "载入中...", 15 "sInfoThousands": ",", 16 "oPaginate": { 17 "sFirst": "首页", 18 "sPrevious": "上页", 19 "sNext": "下页", 20 "sLast": "末页" 21 }, 22 "oAria": { 23 "sSortAscending": ": 以升序排列此列", 24 "sSortDescending": ": 以降序排列此列" 25 } 26 }, 27 "sPaginationType":"ellipses",//页数过多时显示..,需引入对应文件 28 "stateSave":false,//状态保存(cookie里),开启会导致刷新后显示上一次的内容 29 "autoWidth":false,//自动宽度 30 "aLengthMenu":[10,15,20,30,50], 31 "serverSide": true,//服务器模式,使用ajax必须开启 32 "bPaginate": true,//分页总开关 33 "pagingType":"full_numbers",//分页样式 34 "searchable":true,//搜索总开关 35 "ordering":true,//排序总开关 36 // "order":[[4,"desc"],[5,"desc"]], 37 "orderFixed":{ 38 "post": [[ 4, "desc" ],[5,"desc"]] 39 }, //固定排序,下面讲 40 "bDestroy" : true, 41 "ajax":function(data,callback,settings) { 42 //参数封装 43 var param = {}; 44 param.draw = data.draw; 45 param.limit = data.length;//页面显示记录条数,在页面显示每页显示多少项的时候 46 param.start = data.start;//开始的记录序号 47 param.page = (data.start / data.length)+1; 48 param.filter = data.search.value;//过滤条件 49 // alert(JSON.stringify(data)); 50 alert(JSON.stringify(data.order)) 51 //单排序条件 52 /* if(data.order) { 53 if(data.order[0].dir) { 54 param.order = "releaseTime" + " " + data.order[0].dir; 55 } 56 } */ 57 //多排序条件 58 param.order = " "; 59 if(data.order) { 60 $.each(data.order,function(index,value){ 61 var col = data.order[index].column; 62 $.each(data.columns,function(i,v) { 63 var name = data.columns[i].name; 64 if(name) { 65 if(col == window.parseInt(name)) { 66 var arr = name.split("_"); 67 param.order += arr[1] + " " + data.order[index].dir + ","; 68 } 69 } 70 }) 71 }) 72 } 73 param.order= param.order.substring(0,param.order.length-1); 74 $.ajax({ 75 type:"POST", 76 url:"${pageContext.request.contextPath}/newsController/getAllNews.action", 77 data:param, 78 cache:false, 79 dataType:"json", 80 success:function(result) { 81 var returnData = {}; 82 returnData.draw = result.draw;//这里直接自行返回了draw计数器,应该由后台返回 83 returnData.recordsTotal = result.recordsTotal;//返回数据全部记录 84 returnData.recordsFiltered = result.recordsFiltered;//后台不实现过滤功能,每次查询均视作全部结果 85 //更改时间格式 86 for(var i=0;i<result.data.length; i++) { 87 result.data[i].releaseTime = new Date(result.data[i].releaseTime).toLocaleDateString(); 88 } 89 returnData.data = result.data;//返回的数据列表 90 //回调函数(数据渲染) 91 callback(returnData); 92 }, 93 error:function(ajax,textStatus) { 94 /* alert(JSON.stringify(ajax)); 95 alert(textStatus); */ 96 alert("未找到数据"); 97 } 98 }) 99 }, 100 "columnDefs": [ 101 { 102 "targets":[0], 103 "render": function(data, type, row, meta) { 104 return '<label><input type="checkbox" class="ace" /><span class="lbl"></span></label>'; 105 }, 106 "orderable":false, 107 "width":"50px" 108 }, 109 { 110 "title":"序号", 111 "name":"1_id", 112 "data":"id", 113 "targets":[1], 114 "width":"50px", 115 "orderable":false, 116 117 }, 118 { 119 "title":"新闻标题", 120 "name":"2_title", 121 "data":"title", 122 "targets":[2], 123 "render":function(data) { 124 if(data.length > 25) { 125 data = data.substring(0,25) + "..."; 126 } 127 return data; 128 }, 129 "orderable":false, 130 "width":"400px" 131 }, 132 133 { 134 "data":null, 135 "targets":[3], 136 "visible": false, 137 "searchable": false, 138 "orderable":false 139 }, 140 141 { 142 "title":"发布时间", 143 "name":"4_releaseTime", 144 "data":"releaseTime", 145 "targets":[4], 146 "width":"300px", 147 "orderable":true, 148 // "orderSequence":["asc","desc"],//排序方向,第一次点击升序,第二次点击降序 149 // "orderData":[4,5],//第5列数据相同时安按照第6列数据进行排序 150 }, 151 { 152 "title":"所在板块", 153 "name":"5_smallId", 154 "data":"menu.name", 155 "targets":[5], 156 "width":"300px", 157 "orderable":true, 158 "orderData":[5], 159 }, 160 { 161 "title":"操作", 162 "targets":[6], 163 "render":function(data,type,row,meta) { 164 var newsId = row.id; 165 //<a class="green" data-toggle="tooltip" data-placement="top" title="查看详细" href="#"><i class="icon-pencil bigger-130"></i></a> 166 return '<div class="visible-md visible-lg hidden-sm hidden-xs action-buttons"><a class="blue" data-toggle="tooltip" data-placement="top" title="查看详细" href="#"><i class="icon-zoom-in bigger-130"></i></a> <a class="red" data-toggle="tooltip" data-placement="top" title="删除" href="#"><i class="icon-trash bigger-130"></i></a></div><div class="visible-xs visible-sm hidden-md hidden-lg">'; 167 }, 168 "orderable":false, 169 "width":"200px" 170 } 171 ], 172 "infoCallback": function(settings,start,end,max,total,pre) { 173 //激活工具提示 174 $("[data-toggle='tooltip']").tooltip(); 175 //图标功能 176 $("#sample-table-2 tbody").on( 'click', 'tr', function () { 177 var id = $(this).find("td").eq(1).text(); 178 if(id) { 179 $(".blue").attr("href","${pageContext.request.contextPath}/newsController/edit.action?id="+id); 180 } 181 }); 182 183 $(".red").click(function() { 184 $(this).parents("tr").find("td").eq(0).find(":checkbox").attr("checked",true); 185 var ids = new Array(); 186 //添加id到数组 187 $(":checkbox:checked").each(function(i) { 188 if($(this).parents("tr").find("td").eq(1).text()) { 189 ids[i] =$(this).parents("tr").find("td").eq(1).text(); 190 } 191 }) 192 if(window.confirm("确定要删除吗?")) { 193 if(ids.length>0) { 194 $.ajax({ 195 type:"POST", 196 url:"${pageContext.request.contextPath}/newsController/hide.action", 197 data:{"ids":ids}, 198 traditional :true, 199 success:function(){ 200 window.location.reload(); 201 } 202 }) 203 } 204 205 } 206 }); 207 var api = this.api(); 208 var pageInfo = api.page.info(); 209 // alert(JSON.stringify(pageInfo)); 210 return "共"+pageInfo.pages +"页,当前显示"+ start + "到" + end + "条记录" + ",共有"+ total + "条记录"; 211 }, 212 "drawCallback": function(settings) { 213 //去除第一列排序图标 214 // $("#th1").removeClass("sorting_asc"); 215 /* var th4 = $("#th4").attr("aria-sort"); 216 var th5 = $("#th5").attr("aria-sort"); 217 if(th4){ 218 if(th4 == "ascending") { 219 if($("#th4").hasClass("sorting_desc")){ 220 $("#th4").removeClass("sorting_desc"); 221 $("#th4").addClass("sorting_asc"); 222 } 223 }else { 224 if($("#th4").hasClass("sorting_asc")){ 225 $("#th4").removeClass("sorting_asc"); 226 $("#th4").addClass("sorting_desc"); 227 } 228 } 229 } 230 if(th5){ 231 if(th5 == "ascending") { 232 if($("#th5").hasClass("sorting_desc")){ 233 $("#th5").removeClass("sorting_desc"); 234 $("#th5").addClass("sorting_asc"); 235 } 236 }else { 237 if($("#th5").hasClass("sorting_asc")){ 238 $("#th5").removeClass("sorting_asc"); 239 $("#th5").addClass("sorting_desc"); 240 } 241 } 242 } */ 243 244 }, 245 }); 246 247 248 //搜索框样式 249 //$("#sample-table-2_filter input[type='search']").val(""); 250 var search = "<div class='input-group'><input type='search' class='form-control input-sm' placeholder='标题检索' aria-controls='sample-table-2'><div class='input-group-addon'><span class='glyphicon glyphicon-search' id='search'></span></div></div>"; 251 $("#sample-table-2_filter label").html(search); 252 $(".glyphicon-search").css("cursor","pointer"); 253 254 var table = $("#sample-table-2").DataTable(); 255 //table.columns.adjust(); 256 //table.order([4,"desc"],[5,"desc"]).draw(); 257 258 //过滤条件 259 $("#sample-table-2_filter #search").on("click", function () { 260 var filter = $(this).parents("div").find("input[type='search']").val(); 261 table.search(filter).draw(); 262 } ); 263 264 265 266 //监听页码 267 /* $("#sample-table-2").on("page.dt",function() { 268 var tableSetings=$("#sample-table-2").dataTable().fnSettings(); 269 var length=tableSetings._iDisplayLength;//当前每页显示多少 270 var start=tableSetings._iDisplayStart;//当前页开始 271 } ); */
controller
1 @RequestMapping("getAllNews") 2 public @ResponseBody Map<String,Object> getAllNews(int draw,int limit,int start,int page,String filter,String order) { 3 String hql = "select count(id)"; 4 String hql2 ="from News where status=1"; 5 if(filter != null && filter.trim().length() > 0) { 6 hql2 += "and title like '%" + filter+ "%'"; 7 } 8 hql += hql2; 9 if(order != null && order.trim().length() > 0) { 10 hql2 += "order by " + order; 11 } 12 int newsCount = newsService.getSize(hql,null); 13 //查询 14 List<News> list = newsService.findByPages(limit,page,hql2); 15 print("filter-------" + filter); 16 print("order-----"+ order); 17 if(list != null && list.size() > 0) { 18 Map<String,Object> map = new HashMap<String,Object>(); 19 //总记录数,必须 20 map.put("recordsTotal",newsCount); 21 //过滤后记录数 22 map.put("recordsFiltered",newsCount); 23 map.put("data",list);//必须 24 map.put("draw",draw);//必须 25 return map; 26 }else { 27 return null; 28 } 29 }
bean
1 public class News { 2 private Integer id; 3 private String title; 4 private String content; 5 private Integer bigId; 6 private Integer smallId; 7 private Date releaseTime; 8 private Menu menu; 9 private Integer status = 1; 10 public Integer getId() { 11 return id; 12 } 13 public void setId(Integer id) { 14 this.id = id; 15 } 16 public String getTitle() { 17 return title; 18 } 19 public void setTitle(String title) { 20 this.title = title; 21 } 22 public String getContent() { 23 return content; 24 } 25 public void setContent(String content) { 26 this.content = content; 27 } 28 public Integer getBigId() { 29 return bigId; 30 } 31 public void setBigId(Integer bigId) { 32 this.bigId = bigId; 33 } 34 public Integer getSmallId() { 35 return smallId; 36 } 37 public void setSmallId(Integer smallId) { 38 this.smallId = smallId; 39 } 40 public Date getReleaseTime() { 41 return releaseTime; 42 } 43 public void setReleaseTime(Date releaseTime) { 44 this.releaseTime = releaseTime; 45 } 46 public Menu getMenu() { 47 return menu; 48 } 49 public void setMenu(Menu menu) { 50 this.menu = menu; 51 } 52 public Integer getStatus() { 53 return status; 54 } 55 public void setStatus(Integer status) { 56 this.status = status; 57 } 58 /*@Override 59 public String toString() { 60 return "News [id=" + id + ", title=" + title + ", content=" + content 61 + ", bigId=" + bigId + ", smallId=" + smallId 62 + ", releaseTime=" + releaseTime + ", menu=" + menu 63 + ", status=" + status + "]"; 64 }*/ 65 }
1.7参考文章