由于公司的项目需要用到表格,所以我在网上找了许多的表格插件,对比之下,还是觉得dataTables这个插件比较好用。dataTables有很多的功能,具体可以查看官网 | 中文官网。
在这里我讲一下我在项目中使用到的功能。
dataTables 入门教程笔记
autoWidth
- 自动计算列宽这个值默认是true
的,所以我们不用去设置它
serverSide
- 开启服务器模式ajax.data
- 请求参数ajax.dataSrc
- 相当于jQuery的ajax的successajax
- 请求urldata
- 直接指定数据destroy
- 销毁表格对象retrieve
- 检索实例,检索当前存在的dt实例,继续使用它columns.data
- 指定数据源属性columns.render
- 渲染函数data:当前数据, type:。。。, row:当前行,整行数据,可以使用点语法来获取数据 meta
columns.visible
- 设置列显示或隐藏columnsDefs
- 设置列的属性dom
- 表格定位initComplete
- 初始化完毕footerCallback
- tfoot回调函数dt.ajax.reload()
- 重新加载数据dt指的是用datatables实例化后返回的对象,如果是用dataTables实例化,调用时应该带上api(),如table.api().ajax.reload(),如果是用DataTable实例化,则不用带上api(),如table.ajax.reload()
dt.ajax.url().load()
- 更换url并加载数据url中可以带参数,即数据源链接
当url不带参数时,dt.ajax.url().load() == dt.ajax.reload()
dt.ajax.url()
- 更换urldt.draw()
- 重绘$.fn.dataTable.util.throttle()
- 减少方法执行次数,比如我在搜索的时候,我不想每次键入一个单词就搜索一次,我可以用这个函数来控制搜索延迟,可以是3s后搜索一次等请求参数
draw
- 请求次数,即表示的是第几次请求start
- 起始位置,即分页起始位置length
- 长度,即分页长度search[value]
- 搜索框里的值order[i][column]
- 那一列排序order[i][dir]
- 排序方式columns[i][data]
- 列的属性名columns[i][name]
- 列的名字 需要配置 columns.namecolumns[i][searchable]
- 是否能被搜索columns[i][orderable]
- 是否排序columns[i][search][value]
返回参数
draw
- 请求次数recordsTotal
- 总条数recordsFiltered
data
- 返回的数据error
参考:DOM定位 基本初始化 示例 Datatables中文网 | option dom 自定义布局表格
datatables默认会打开部分特性,比如搜索框,分页显示等等,或许你不喜欢datatables这样去布局,可能你想把分页按钮放在底部的中间,搜索框放在顶部的左上角,不用担心datatables考虑到这个问题,使用dom选项就可以灵活配置各个特性的位置。
datatables定义了10个字符表示不同的组件
我可以先放置一个占位的class,然后在表格实例化完成之后,再去动态添加元素,以此来实现高度可定制的dom。如:
dom: '<"dataTable-top table-toolBar"><"table-body"rt><"dataTable-bottom"lip><"clear">',
// 添加自定义dom
$('div.dataTable-top').html(searchBox + '' + dataTableSearch + dataTableToolBar + '');
参考:自行封装请求和返回数据的零耦合服务端分页 网友共享 示例 Datatables中文网
Datatables有许多方法来获取你的数据,如果你的数据量比较大,这个时候你需要使用服务器模式来处理你的数据。 在服务器模式下,所有的分页,搜索,排序等操作,Datatables都会交给服务器去处理。所以每次绘制Datatables, 都会请求一次服务器获取需要的数据。
通过配置serverSide这个属性来打开Datatables的服务器模式
serverSide: true,
processing: true, // 服务器加载数据等待提示
此时使用ajax来获取数据
"ajax": "../resources/server_processing_custom.php"
当然你也可以自定义ajax,比如我的项目中
ajax : function(data, callback, settings) {//ajax配置为function,手动调用异步查询
console.log(data, callback, settings);
//手动控制遮罩
// $wrapper.spinModal();
//封装请求参数
var param = _this.getQueryCondition(data);
$.ajax({
type: "GET",
url: "/api/employee",
cache : false, //禁用缓存
data: param, //传入已封装的参数
dataType: "json",
success: function(result) {
//异常判断与处理
if (result.errorCode) {
// $.dialog.alert("查询失败。错误码:"+result.errorCode);
return;
}
//封装返回数据,这里仅演示了修改属性名
var returnData = {};
returnData.draw = data.draw;//这里直接自行返回了draw计数器,应该由后台返回
returnData.recordsTotal = result.total;
returnData.recordsFiltered = result.total;//后台不实现过滤功能,每次查询均视作全部结果
returnData.data = result.pageData;
//关闭遮罩
// $wrapper.spinModal(false);
//调用DataTables提供的callback方法,代表数据已封装完成并传回DataTables进行渲染
//此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕
console.log('success', returnData);
callback(returnData);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$.dialog.alert("查询失败");
$wrapper.spinModal(false);
}
});
},
参考:给表格添加索引(Type selector-modifier 应用) | option columns.render 渲染列(1) 添加checkbox
首先必须定义好相关的列,添加复选框,使用render来渲染单元格dom元素
columns: [
{ //复选框单元格
className: "td-checkbox",
"searchable": false,
"orderable": false,
// width: "30px",
data: null,
render: function (data, type, row, meta) {
return '';
}
},
{
data: null
},
{data: 'firstName'},
{data: 'lastName'},
{data: 'position'},
{data: 'office'},
{data: 'age'},
{data: 'startDate'},
{data: 'salary'},
{data: 'extn'},
{data: 'email'}
]
添加序号不能像复选框那样,而应该在表格生成完之后,再去渲染
'fnDrawCallback': function () {
_this.table.column(1, {
search: 'applied',
order: 'applied'
}).nodes().each(function(cell, i) {
//i 从0开始,所以这里先加1
i = i+1;
//服务器模式下获取分页信息,使用 DT 提供的 API 直接获取分页信息
var page = _this.table.page.info();
//当前第几页,从0开始
var pageno = page.page;
//每页数据
var length = page.length;
//行号等于 页数*每页数据长度+行号
var columnIndex = (i+pageno*length);
cell.innerHTML = columnIndex;
});
},
参考:自行封装请求和返回数据的零耦合服务端分页 网友共享 示例 Datatables中文网
在服务器模式下,通过改变传递到服务器的参数,来实现自定义搜索,排序和分页
getQueryCondition : function(data) {
var param = {};
//组装排序参数
if (data.order&&data.order.length&&data.order[0]) {
switch (data.order[0].column) {
case 2:
param.orderColumn = "firstName";
break;
case 3:
param.orderColumn = "lastName";
break;
case 4:
param.orderColumn = "position";
break;
case 5:
param.orderColumn = "office";
break;
case 6:
param.orderColumn = "age";
break;
case 7:
param.orderColumn = "startDate";
break;
case 8:
param.orderColumn = "salary";
break;
case 9:
param.orderColumn = "extn";
break;
case 10:
param.orderColumn = "email";
break;
default:
param.orderColumn = "firstName";
break;
}
param.orderDir = data.order[0].dir;
}
//组装查询参数
param.fuzzySearch = this.fuzzySearch;
if (param.fuzzySearch) {
param.fuzzy = (!this.searching && this.localState !== null) ? this.localState.search.search : $("#tableSearch").val();
}else{
param.firstName = (!this.searching && this.localState !== null) ? this.localState.search.field.firstName : $("#firstName-search").val();
param.lastName = (!this.searching && this.localState !== null) ? this.localState.search.field.lastName : $("#lastName-search").val();
param.position = (!this.searching && this.localState !== null) ? this.localState.search.field.position : $("#position-search").val();
param.office = (!this.searching && this.localState !== null) ? this.localState.search.field.office : $("#office-search").val();
param.age = (!this.searching && this.localState !== null) ? this.localState.search.field.age : $("#age-search").val();
param.startDate = (!this.searching && this.localState !== null) ? this.localState.search.field.startDate : $("#startDate-search").val();
param.salary = (!this.searching && this.localState !== null) ? this.localState.search.field.salary : $("#salary-search").val();
param.extn = (!this.searching && this.localState !== null) ? this.localState.search.field.extn : $("#extn-search").val();
param.email = (!this.searching && this.localState !== null) ? this.localState.search.field.email : $("#email-search").val();
}
//组装分页参数
param.startIndex = data.start;
param.pageSize = data.length;
param.draw = data.draw;
console.log(param);
return param;
}
参考:关于 DataTables 本地储存那点事,又爱又恨 (stateSave参数应用)
//开启本地保存功能
stateSave: true,
//保存状态操作
"stateSaveParams": function (settings, data) {
console.log("stateSaveParams", data, JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance)));
//这里可以操作保存的数据,写上自己特定的逻辑
data.search.search = $("#tableSearch").val();
data.search.fuzzySearch = _this.fuzzySearch;
data.search.field = {
firstName: $("#firstName-search").val(),
lastName: $("#lastName-search").val(),
position: $("#position-search").val(),
office: $("#office-search").val(),
age: $("#age-search").val(),
startDate: $("#startDate-search").val(),
salary: $("#salary-search").val(),
extn: $("#extn-search").val(),
email: $("#email-search").val()
}
},
"stateSaveCallback": function (settings, data) {
console.log("stateSaveCallback", data);
//DT默认保存的key值为DataTables_+表格id+页面名称
localStorage.setItem('DataTables_' + settings.sInstance, JSON.stringify(data));
},
//读取状态操作
"stateLoadParams": function (settings, data) {
console.log("stateLoadParams", data);
//在读取数据的时候可以改变数据,根据自己逻辑来处理
//data.search.search = "";
//或者你可以直接禁用从缓存里读取数据,只要直接返回false即可
//return false;
},
"stateLoadCallback": function (settings) {
console.log("stateLoadCallback", JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance)));
return JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance));
},
//状态加载完后执行的回调函数
"stateLoaded": function (settings, data) {
console.log("stateLoaded", data);
//在这里你可以打印出保存的缓存数据
//alert( 'Saved filter was: '+data.search.search );
},
rowId: '_id', // 为每一行数据添加上id,此处的_id是从服务器获取的
// 多语言
language: {
"lengthMenu": "每页 _MENU_ 条记录",
"zeroRecords": "没有找到记录",
"info": "第 _PAGE_ 页 ( 总共 _PAGES_ 页 )",
"infoEmpty": "无记录",
"infoFiltered": "(从 _MAX_ 条记录过滤)",
"paginate": {
"first": "<<",
"previous": "<",
"next": ">",
"last": ">>"
},
"search": "模糊查询:"
},
paginationType: 'full_numbers', // 分页功能
"order": [[2, 'asc']], // 默认排序
initComplete: ... // 初始化完成
fnDrawCallback: ... // 渲染表格完成回调
参考:JQuery Datatable Ajax请求两次问题的解决
table = $('#aaa').DataTable({...});
// 初始化完成,添加行号
table.on('order.dt search.dt',function() {
table.column(1, {
search: 'applied',
order: 'applied'
}).nodes().each(function(cell, i) {
cell.innerHTML = i + 1;
});
}).draw();