datatables后端分页
0x01 缘由
平时较少涉及前端,这次本以为模板中有表单,分页跳转搜索功能都比较齐全,可以高枕无忧,但是细看模板中的分页跳转是不需要与后台交互的,数据一次性写在前端,再有前端插件完成分页。
这种方式肯定是不可行的,这次要做的可以看做资产管理,服务器+主机量级很大,一个机器生成一条 <th>,第一次请求的前端代码怕是要崩掉。
所以合理采用的还是后端分页
0x02 分页方式
团队项目里看过的几种后端分页方式:
1. Paginator + render渲染整个页面,这种方式比较好理解,但是每一次跳转分页,都会替换掉整块main-content部分。
2. datatables 后端分页,这种方式按照datatables提供的API填写相关信息与逻辑,缺点是
1) 受限于这种插件的条条框框,要自定义一些内容有点麻烦。
比如原始datatables中search是实时的,即在search input框中输入 "123",会进行 "1"、"12"、"123"三次过滤,在后端分页中,就会发起三次查询。
所以要自定义搜索,但是form部分是由datatables初始化过程中生成的,找半天没有找到插入自定义<input>框的接口。所以用jquery遍历再添加 <input>。
2) 文档不太清晰
各种API、接口,在文档中找来找去挺麻烦的。等到整块写的差不多的时候,才意外看到官方后端分页的文档。
3. 自己编写form、跳转、查询、排序、每页数量等功能,就是稍显麻烦,但还是挺灵活的。
0x03 datatables后端分页流程
由于模板本身的表单是基于datatables的,所以最后还是修改了datatables。
datatables后端分页的流程大概可以分为四部分:
1. 修改datatables的初始化参数,改为后端分页,并修改其他设置
2. datatables传递数据给服务端
3. 接收服务端数据,比如说取到第10页的10条json数据
4. 数据渲染至datatables当前页面
0x04 修改datatables初始化参数
<script type="text/javascript">
$(function () {
//提示信息
var lang = {
"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": "末页",
"sJump": "跳转"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
}; //初始化表格
var table = $("#dynamic-table").dataTable({
language:lang, //提示信息
autoWidth: false, //禁用自动调整列宽
stripeClasses: ["odd", "even"], //为奇偶行加上样式,兼容不支持CSS伪类的场合
processing: true, //隐藏加载提示,自行处理
serverSide: true, //启用服务器端分页
searching: false, //禁用原生搜索
orderMulti: false, //启用多列排序
order: [], //取消默认排序查询,否则复选框一列会出现小箭头
renderer: "bootstrap", //渲染样式:Bootstrap和jquery-ui
pagingType: "simple_numbers", //分页样式:simple,simple_numbers,full,full_numbers
columnDefs: [{
"targets": 'nosort', //列的样式名
"orderable": false //包含上样式名‘nosort’的禁止排序
}]
}).api();//此处需调用api()方法,否则返回的是JQuery对象而不是DataTables的API对象
});
</script>
datatables初始化中,以字典的形式将初始化信息传递进去。
其中,language为表单的一些提示信息。这里比较简单,基本上看看就明白。
所以,现在表单已经初始化成了后端模式了。
接下来,怎么给后端传递数据
0x05 前后端数据交互
需要增加的两个值:ajax 与 column
<script type="text/javascript">
$(function () {
//提示信息
var lang = {
"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": "末页",
"sJump": "跳转"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
}; //初始化表格
var table = $("#dynamic-table").dataTable({
language:lang, //提示信息
autoWidth: false, //禁用自动调整列宽
stripeClasses: ["odd", "even"], //为奇偶行加上样式,兼容不支持CSS伪类的场合
processing: true, //隐藏加载提示,自行处理
serverSide: true, //启用服务器端分页
searching: false, //禁用原生搜索
orderMulti: false, //启用多列排序
order: [], //取消默认排序查询,否则复选框一列会出现小箭头
renderer: "bootstrap", //渲染样式:Bootstrap和jquery-ui
pagingType: "simple_numbers", //分页样式:simple,simple_numbers,full,full_numbers
columnDefs: [{
"targets": 'nosort', //列的样式名
"orderable": false //包含上样式名‘nosort’的禁止排序
}],
ajax: function (data, callback, settings) {
//封装请求参数
console.log(data);
var param = {};
param.limit = data.length;//页面显示记录条数,在页面显示每页显示多少项的时候
param.start = data.start;//开始的记录序号
param.page = (data.start / data.length)+1;//当前页码
param.order = data.order[0]
//console.log(param);
//ajax请求数据
$.ajax({
type: "GET",
url: "http://your_server",
cache: false, //禁用缓存
data: param, //传入组装的参数
dataType: "json",
success: function (result) {
console.log(result);
//setTimeout仅为测试延迟效果
setTimeout(function () {
//封装返回数据
var returnData = {};
returnData.draw = data.draw;//这里直接自行返回了draw计数器,应该由后台返回
returnData.recordsTotal = result.total;//返回数据全部记录
returnData.recordsFiltered = result.total;//后台不实现过滤功能,每次查询均视作全部结果
returnData.data = result.data;//返回的数据列表
//console.log(returnData);
//调用DataTables提供的callback方法,代表数据已封装完成并传回DataTables进行渲染
//此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕
callback(returnData);
}, 200);
}
});
},
//列表表头字段
columns: [
{ "data": "ip" },
{ "data": "online_state" },
{ "data": "machine_id" },
{ "data": "location" },
{ "data": "agent_state" },
{ "data": "system" }
]
}).api();//此处需调用api()方法,否则返回的是JQuery对象而不是DataTables的API对象
});
</script>
1. ajax: function(data,callback,settings){}——data
data为datatables本身会提供的数据集合,包含每一列的信息、一页的数据量(一页几行)、查找的值、当前页等,另外根据datatables的初始化选择还会包含其他内容,比如,当点击排序时,data中将包含排序的列、方式。
想要传递给服务端的数据,可以在这一处取。但是最好将数据重新封装一遍再发送给服务器,原因是:
1) 有的数据是不需要的,比如在原生搜索关闭的情况下,data中还是会以后search的信息
2) 有一些自定义的信息,比如自定义搜索框,可以封装入其中再传给服务器
3) 整理格式,比如 排序数据 order中, order[0] 包含排序的列和方式,其他没什么用,所以取出order[0] 封装再发送,简洁得多。
数据封装完毕,则采用ajax的方式将数据发送给服务端。
2. ajax: function(data,callback,settings){}——callback
callback为返回给datatables渲染当前表单的数据,以字典形式。
其中,draw与data中的draw相同。
recordsTotal、recordsFiltered填写为数据库总数据量即可,datatables从中获取数据总量、分页数量等。
渲染的核心数据 data,是给表单渲染内容用的。
3. columns字段
columns字段的作用是:
将回调函数中的data中的数据,按columns的排序渲染入表单列中,比如这里,第一列为ip,则将data['ip'] 放到第一列中,以此类推。
4. 后端返回什么数据
后端的数据可以根据传递给回调函数的数据进行猜测拼接,但是data也是字典格式的,返回的数据用Python可以写为:
data = [
{'ip':'192.168.1.91','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.92','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.93','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.94','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.95','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.96','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.97','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.98','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.99','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
{'ip':'192.168.1.100','online_state':'运行中','machine_id':'','location':'58security','agent_state':'OK','system':'windows'},
]
response = {'data':data,'limit':10,'page':10,'total':100}
return JsonResponse(response)
在 ajax success中接收这些数据,再进行封装、传入datatables回调函数,从而完成渲染。
其中,显而易见,data以 “字段”:"内容"的形式存在于字典中。
5. 自定义搜索(version2)
(上一次写的太丑了)
由此,基本已经完成。
但是原生的搜索是不能用了,所以要自定义搜索。
也找不到添加 <input>框的接口,所以,用jquery遍历搜索再添加<input>元素、绑定事件。
绑定的事件要做什么事呢?
最简单的就是让datatables执行一次提交ajax,这里使用 datatables对象的draw()函数。
JS代码:
function search(){
table.draw();
}
var search_input = $('#search_input_html').text();
$("#dynamic-table_wrapper").find(".row").first().find(".col-sm-6").last().append(search_input);
$('#searcy_type').html($('#search_type').text());
$("#search_button").click(function(){
search();
});
$("#search_key").keydown(function(e){
if(e.keyCode == 13){
search();
}
})
其中插入的代码用textarea包裹起来,再用val取代码
<!--ADDING HTML start-->
<textarea id="search_input_html" style="display:none">
<div class="my_dataTables_filter">
<div class="span6">
<select id="searcy_type" class="search_type">
<select>
<input id="search_key" class="search_space"></input>
<button type="button" id="search_button" class="search_button btn">搜索</button>
</div>
</div>
</textarea>
<textarea id="search_type" style="display:none">
<option value="ip">ip</option>
<option value="online_status">online_status</option>
<option value="machine_id">machine_id</option>
</textarea>
<!--ADDING HTML end-->
样式CSS:
.my_dataTables_filter {
float: right;
} .search_space{
height:34px;
position: relative;
top:2px;
left:4px;
} .search_button{
width: 50px;
height: 34px;
color: #fff;
/*font-size:20%;*/
letter-spacing: 1px;
background: #65CEA7;
border-bottom: 2px solid #65CEA7;
/*background: #3385ff;*/
/*border-bottom: 2px solid #2d78f4;*/
outline: medium;
-webkit-appearance: none;
-webkit-border-radius:;
} .search_type{
height:34px;
position: relative;
top:2px;
left:4px;
}
在初始化结束后,加入这段JS代码(HTML写在content部分;CSS放在.css中):遍历、添加元素、绑定事件、事件为datatables发出ajax。
draw()默认参数为true,表明刷新时会跳转到第一页重新刷新;draw(false) 则保持在原页。
同时,搜索的值也要传递给服务端:在封装数据时加入
param.search_key = $("#search_key").val()
参考——重要程度由高到低:
2. 引导我做demo的文章 jQuery Data Tables 插件自定义Ajax分页实现
一脸懵时可以做一个demo,后端数据返回,form完成,再一步步做转移。
datatables后端分页的更多相关文章
- datatables跳转自定义页面(后端分页)
在后端分页的情况下,怎么做到跳转自定义页面? 0x01 难点: 一. 怎么添加自定义代码? 前提:datatables在整个html加载完毕后,进行datatables数据的渲染,并且把右下角的 “上 ...
- jQuery--dataTable 前端分页与后端分页 及遇到的问题
(1)区别 前端分页:一次性把所有数据全都放在前端,由前端进行处理:适合请求的数据量不大的情况 后端分页:服务器模式,所有的分页,搜索,排序等操作在服务器端完成,然后前端去请求数据:适合量大的情况 ( ...
- bootstrap table 前后端分页(超级简单)
前端分页:数据库查询所有的数据,在前端进行分页 后端分页:每次只查询当前页面加载所需要的那几条数据 下载bootstrap 下载bootstrap table jquery谁都有,不说了 项目结构:T ...
- EasyUI表格DataGrid前端分页和后端分页的总结
Demo简介 Demo使用Java.Servlet为后台代码(数据库已添加数据),前端使用EasyUI框架,后台直接返回JSON数据给页面 1.配置Web.xml文件 <?xml version ...
- django项目一 分页器(前端分页和后端分页区别)
1. 客户信息展示 1. 母版和继承 {% extends 'layout'%} {% load static%} {% static '文件路径' %} block css js content 2 ...
- [转]Bootstrap table后端分页(ssm版)
原文地址:https://www.cnblogs.com/flyins/p/6752285.html 说明bootstrap table可以前端分页,也可以后端sql用limit分页.这里讲的是后端分 ...
- python 进行后端分页详细代码
后端分页 两个接口 思路: 1. 先得到最大页和最小页数(1, 20) --> 传递给前端, 这样前端就可以知道有多少个页数 2. 通过传递页数得到当前页对应数据库的最大值和最小值 3. 通过s ...
- Bootstrap table后端分页(ssm版)
说明bootstrap table可以前端分页,也可以后端sql用limit分页.这里讲的是后端分页,即实用limit.性能较好,一般均用这种源码下载地址:https://git.oschina.ne ...
- Bootstrap-table学习笔记(二)——前后端分页模糊查询
在使用过程中,一边看文档一边做,遇到了一些困难的地方,在此记录一下,顺便做个总结: 1,前端分页 2,后端分页 3,模糊查询 前端分页相当简单,在我添加了2w条测试数据的时候打开的很流畅,没有卡顿. ...
随机推荐
- Linux 上的 SQL Server 2017 的安装指南
一:介绍背景 微软在2016年 3 月首次对外宣布了 Linux 版的 SQL Server,并于2017年 7 月发布了首个公开 RC 版.前几日在美国奥兰多召开的微软 Ignite 2017 大会 ...
- 使用 Apache 来限制访问 Confluence 6 的管理员界面
限制特定的 IP 地址可以访问管理员后台 Confluence 的管理员控制台界面对整个应用来说是非常重要的,任何人访问 Confluence 的控制台不仅仅可以访问 Confluence 安装实例, ...
- 【CSS】Bootstrap中select2+popover冲突
网上搜索得到: It changes the position because the position is based on the popover's dimansions and select ...
- vue之$forceUpdate
由于一些嵌套特别深的数据,导致数据更新了.UI没有更新(连深度监听都没有监听到) this.$forceUpdate();
- 第一次Java测试及感触
周四进行了java测试,感触很深,测试的题目是用Java实现一个ATM机的管理系统.最后3个小时后,我没有完成这次测试,但是我找到了自己的很多不足,明确了自己的问题究竟在哪里. 关于这次测试我不会的最 ...
- React-Native到0.44版本后Navigator 不能用的问题
新升级 到0.46版本以后 Navigator 不能使用报错. 'Navigator is deprecated and has been removed from this package. It ...
- 第十六单元 yum管理RPM包
yum的功能 本地yum配置 光盘挂载和镜像挂载 本地yum配置 网络yum配置 网络yum配置 Yum命令的使用 使用yum安装软件 使用yum删除软件 安装组件 删除组件 清除缓存 查询 课后作业 ...
- HTML&javaSkcript&CSS&jQuery&ajax(八)
一. <!DOCTYPE html><html><head><meta charset="utf-8"><tiitle> ...
- 第七周学习总结-C#
2018年8月26日 这个周二突然得知另一位老师留的暑假作业,群文件里早就上传了,我居然一直没翻到那里,要不是同学问作业做完没,我可能开学就要“真●裸考”了
- 批量杀掉多个pid文件中记录的pid进程, 并集成到shell脚本中
head_files=`find ./fmsConf/ -name "*.pid"` for file in $head_files do cat $file | awk rm - ...