thinkphp5集成H-ui后台(三)集成datatables
在弄完ztree后,这⾥没有急着去做博客列表的相关功能,因为涉及要说的插件太多。这⾥单独的说明下如何集成datatables,并详细解释
在当前系统中⽤到的属性。这⾥使⽤⼀个⾮常简单的表作为例⼦(公告列表)。
1、数据库表的设计
CREATE TABLE `mq_notice` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '逻辑主键',
`title` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT '标题',
`content` text CHARACTER SET utf8 COMMENT '内容',
`delete_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0:未删除;1:已删除)',
`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
2、页⾯结构
这是⼀个完整的查询列表页⾯,使⽤datatables的时候,只要先在页⾯设计好表头等就可以了。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
{include file="../application/admin/view/header.html" /}
{include file="../application/admin/view/footer.html" /}
<title>公告管理</title>
</head>
<body>
<nav class="breadcrumb"><i class="Hui-iconfont"> </i> ⾸页 <span class="c-gray en">></span> 综合管理 <span class="c-gray en">></span> 公告管理 <a class="b <div class="page-container">
<div class="text-c">
标题:<input type="text" class="input-text" placeholder="输⼊标题" id="title" name="" />
精确查<input id="accurateFlg" name="accurateFlg" type="checkBox" value="1" />
<button type="button" class="btn btn-success radius" id="search" name="search"><i class="Hui-iconfont"> </i> 搜公告</button>
</div>
<div class="cl pd-5 bg-1 bk-gray mt-20">
<span class="l">
<a href="javascript:;" οnclick="delete_batch()" class="btn btn-danger radius"><i class="Hui-iconfont"> </i> 批量删除</a>
<a href="javascript:;" οnclick="notice_add('添加公告','__URL__/notice/toNoticeAdd','','')" class="btn btn-primary radius"><i class="Hui-iconfont"> </i> 添加公告</a </span>
</div>
<div class="mt-20">
<table class="table table-border table-bordered table-hover table-bg table-sort">
<thead>
<tr class="text-c">
<th width="25"><input type="checkbox" id="chkId" name="chkIdAll" value=""></th>
<th width="40">ID</th>
<th width="200">公告标题</th>
<th width="200">发布时间</th>
<th width="100">操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</body>
3、datatables的详细说明
datatables真⼼很好⽤,作为jquery的页⾯元组,个⼈觉得还是很专业的。这⾥说点题外话,⾃⼰在刚⼊⾏(javaweb)的那⼀两年,对
css+div有种爱恨交加的感受,爱是它们的语法很简单,恨的是⾃⼰实在没有UI设计的⽂艺细胞。⾯对⼀个⼩⼩的后台项⽬,想在已有的模
板上⾯加点⾃⼰的东西,都举步维艰。那时候就有⼀个想法,有没有⼀套完整的js系统,有⾃⼰的css和图⽚以及icon等,按照全局的样
式,封装成⼀个⼀个的表单组件(table、from等),使⽤的时候,只要拿对应的组件就可以了,并不需要考虑全局的布局和样式问题,⾃⼰安⼼的做接⼝就⾏。所以就主动的搜寻到了extjs、easyui等。⽆奈,要么收费,要么试⽤的组件不全,要么就是像extjs那样太⼤了......,最后就⼀直在jquery的组件中东拼西凑着,虽然没有所谓的统⼀,但还是⽤得舒⼼,也许只是习惯了吧。随着移动互联⽹的兴起,mvvm模式的成熟,尤其是web前端开发的独⽴,web⼯程师终于可以安静的去关⼼框架和数据库了。扯淡到此为⽌,这⾥还是上代码,具体解释在注释中:
<script type="text/javascript" src="__ADMIN__/lib/datatables/1.10.0/jquery.dataTables.min.js"></script>
<script type="text/javascript">
var table;
$(function(){
table = $('.table-sort').dataTable({
"bStateSave": false,//状态保存
"bServerSide" : true, //是否启动服务器端数据导⼊
"bFilter": false, //去掉默认⾃带的搜索框
"aLengthMenu" : [20, 40, 60],//每页显⽰⾏数
"sAjaxSource" : "__URL__/notice/noticeDatas",//请求后台的url
/**
* fnServerParams函数:
* 顾名思义,就是请求后台的参数设置
* ⼤家可以在开发的时候可以⽤console.log(JSON.stringify(aoData))
* 查看下参数结构,我们可以将⾃⼰页⾯的查询条件放⼊aoData中,如例⼦所⽰
*/
"fnServerParams" : function(aoData) {
aoData.push({
"name" : "criteria",
"value" : {
"title" : $("#title").val(),
"accurateFlg" : $("#accurateFlg").prop("checked") ? "1" : ""
thinkphp3}
});
},
/**
* aoColumns 对应于表头和属性赋值等
*
* "mData" : 对应的属性名
* "bSortable" : 是否需要排序,默认是true(就是每列表头上的的上、下两个箭头)
* "sTitle" : 列名
* "sDefaultContent" : 默认值
* "sClass" : 相当于css中的text-align,有text-l、text-c、text-r(左中右)这三个选择
*/
"aoColumns" : [{
"mData" : "id"
},{
"mData" : "id",
"sTitle" : "ID",
"sWidth": "40px",
"sDefaultContent" : "",
"sClass" : "text-c"
},{
"mData" : "title",
"sTitle" : "标题",
"sDefaultContent" : "",
"sClass" : "text-c"
},{
"mData" : "create_time",
"sTitle" : "发布时间",
"sDefaultContent" : "",
"sClass" : "text-c"
},{
"mData" : "",
"sTitle" : "操作",
"sDefaultContent" : "",
"sClass" : "text-c"
"sClass" : "text-c"
}],
//aoColumnDefs⽤来设置列的属性,可以指定任何列,我们这⾥⽤来设置第⼀列[0]的复选框
"aoColumnDefs":[{
"sClass": "text-c",
"mRender" : function(data,type,full) {
return '<input type="checkbox" id="chkId_' + data
+ '" name="chkId" value="' + data + '" />';
},
"bSortable": false,
"aTargets": [0]
}],
//columnDefs和oColumnDefs差不多,它们的区别问百度吧
"columnDefs": [{ "orderable": false, "targets": 1 }],
/**
* fnServerData函数
* 这个函数很重要,我们可以通过⾥⾯的参数类重构页⾯与服务器的交互⽅式
* 总之,⾥⾯的ajax由我们配置,⼤家可以打印参数和回调测试测试
*/
"fnServerData" : function(sSource, aoData, fnCallback) {
$.ajax({
type : 'POST',
url : sSource,
async : false,
data : {
"aoData" : JSON.stringify(aoData)
},
success : fnCallback,
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status + "," + textStatus);
}
});
},
/
**
* ⼤家试想⼀下这样⼀个业务场景,我们数据库中存放了性别这⼀列,数据库中的值
* 1代表男;0代表⼥;假设我们没有在php中处理,那么页⾯显⽰的时候就会显⽰1或者是0
* 这显然是不友好的。
* fnRowCallback就可以直接在页⾯完美的解决这场景
* 说⽩了,就是获取完⾏数据以后,我们在页⾯显⽰之前,对数据预处理下
* 例⼦中只是增加操作列的查看、修改和删除图标与事件
*/
"fnRowCallback" : function(nRow, aData, iDisplayIndex) {
var cstr = "<a title='查看' href='javascript:void(0);' οnclick='notice_edit("+aData.id+",0)' class='ml-5' style='text-decoration:none'><i class='Hui-iconfont'> </i></a>" "<a title='编辑' href='javascript:void(0);' οnclick='notice_edit("+aData.id+",1)' class='ml-5' style='text-decoration:none'
><i class='Hui-iconfont'> </i></a>" + "<a title='删除' href='javascript:void(0);' οnclick='notice_del(this,"+ aData.id +")' class='ml-5' style='text-decoration:none'><i class='Hui-iconfont'> </i></a>"
$('td:eq(4)', nRow).html(cstr);
return nRow;
}
});
//注册查询按钮事件
$("#search").bind("click", function () {
//这⾥可以做⼀些js的格式验证
table.fnDraw();//每次查询,调⽤fnDraw重绘
});
});
</script>
4、datatables分页说明
写到这⾥,⼤家可能会有疑问,分页、总记录数等这些页⾯信息怎么体现在页⾯,或者说后台查询出来的分页数据,怎么给datatables?这
个呢,就要从datatables的参数说起了。我们在浏览器后台打印下它的请求参数,如图:
上图中的数据就是:
[
{"name":"sEcho","value":1},
{"name":"iColumns","value":5},
{"name":"sColumns","value":",,,,"},
{"name":"iDisplayStart","value":0},
{"name":"iDisplayLength","value":20},
{"name":"mDataProp_0","value":"id"},
{"name":"bSortable_0","value":false},
{"name":"mDataProp_1","value":"id"},
{"name":"bSortable_1","value":true},
{"name":"mDataProp_2","value":"title"},
{"name":"bSortable_2","value":true},
{"name":"mDataProp_3","value":"create_time"},
{"name":"bSortable_3","value":true},
{"name":"mDataProp_4","value":""},
{"name":"bSortable_4","value":true},
{"name":"iSortCol_0","value":0},
{"name":"sSortDir_0","value":"asc"},
{"name":"iSortingCols","value":1},
{"name":"criteria","value":{"title":"","accurateFlg":""}}
]
我们可以很清楚的看到iDisplayStart、iDisplayLength这两个属性,⾥⾯的值就是mysql分页时候limit 0,20的值。所以后台可以获取aoData中的这两个值来进⾏翻页处理。
后台怎么获取datatables的翻页数据解决了。那么datatables需要的当前页,总数量等这些页⾯信息怎么从后台获取呢?它⼜怎么和数据内容区分呢?这个我们可以到datatables的学习论坛中去查就是了,这⾥不卖官⼦,直接告诉⼤家:
{
"sEcho":1,//这个参数有意思,下⼩节封装DataTablesUtil.php会详细说明
"iTotalRecords":100,//实际的总数量
"iTotalDisplayRecords":100,//过滤之后的数量,我们不⽤datatables的假翻页的话,它和iTotalRecords等价
"aaData":'.....',//当前页的所有结果集
...
}
值得说明的是,不同的datatables的版本,参数名是不⼀样的,我这边⽤的是H-ui⾃带的1.10.0,其他的版本,可以上官⽹或者百度询问,这⾥不⼀⼀列举。到了这⼀步,我们书写后台的查询语句就有思路了。
5、封装⼀个DataTablesUtil.php
如果只有⼀个系统只有这个页⾯⽤到datatables,那么我想谁都不会想着要封装⼀个⼯具类,这就是实际开发与普通练习的区别。我们通过第4⼩节的描述,有很清楚的查询思路。但是当⼤家仔细观察aoData参数结构的时候,我们可以发现,还可以抽取出⼀个排序的思路。这⾥还是说下细节:"mData
Prop_xx"封装了每列的名称;"bSortable_xx"封装了当前xx列是否需要排序;"sSortDir_xx"打家看到它的值就知道是存放asc和desc这两个排序⽅式的;"iSortingCols"就是当前查询具体是哪⼀列在排序(和数组下标⼀样从0开始)。所以,我们可以做⼀个⼤胆的逻辑,根据这些参数获取到客户在使⽤的时候点了那列,升序还是降序。下⾯先上DataTablesUtil.php的完整代码:
<?php
namespace app\common\utils;
/**
*
* @author tim
*
*/
class DataTablesUtil
{
//datatable参数下标常量定义
const ID_DISPLAY_START = 'iDisplayStart'; //开始⾏
const ID_DISPLAY_LENGTH = 'iDisplayLength'; //每页显⽰⾏数
const S_ECHO = 'sEcho'; //每页的唯⼀标识,必须在结果集中传回
const ORDER_PREFIX = 'mDataProp_'; //列名前缀
const ISORTCOL_0 = 'iSortCol_0'; //排列下标
const SSORTDIR_0 = 'sSortDir_0'; //排列⽅式
//⾃定义查询条件key
const CRITERIA = 'criteria';//和页⾯中aoData中的查询条件key要⼀致
//封装查询条件下标常量定义
const ORDER = 'order';
const LIMIT = 'limit';
/**
* 根据$aoData参数,封装查询条件(筛选_criteria、排序_order、分页_limit)
* */
public static function getQueryPageProperty($aoData){
//json参数转化为数组
$arr = json_decode($aoData,true);
//将数据整理为key=>value的关联模式数组
$dataArr = array();
for ($i=0;$i<count($arr);$i++){
$dataArr[$arr[$i]['name']] = $arr[$i]['value'];
}
//设置返回的数据
$iSortCol_0 = $dataArr[DataTablesUtil::ISORTCOL_0];
$sSortDir_0 = $dataArr[DataTablesUtil::SSORTDIR_0];
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论