并不是所有的后台开发都有美工和前端工程师来配合做页面,为了显示数据并有一定的美感,jQuery的DataTables插件对于像我这样的前端菜鸟来说真是雪中送炭,当然对于专业的前端开发者来说它更是锦上添花!DataTables提供了针对表格的排序、浏览器分页、服务器分页、筛选、格式化、统计等强大功能。
工作中对程序员的学习模式才深有体会,不是从入门到精通,而是从会用到了解。对于我来说,基本都是拿到一个知识先做个东西出来,再来细细品味个中的细节,然后再慢慢理解。从粗到细,从大到小,呵呵,这种”逆向学习”的模式估计也只在互联网常见了。
使用前要引入datatables的相关包:
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js"></script>
datatables表格展示以及数据源方式都有很多,这里用的是最常见的后端返回给前端的json格式的数据源,并且前端html里指定列的title。
后端的数据可以如下:
app.get('/test/index', function(req, res) {
var data = [{name:'xiaojie',age:24,job:'developer',description:'humours'},{},{},{}]; //格式像这样,数据省略
res.json({data:data});
});
html里仅仅声明一个table的框架:
<table class="table b-t b-light" id="datatables">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>JOB</th>
<th>描述</th>
<th>操作</th> <!--自定义列-->
</tr>
</thead>
<tbody>
</tbody>
</table>
重头戏是js,这里有功能强大的字段,待我慢慢道来。
首先初始化一个datatables,最基本的就这样:
$(document).ready(function() {
$('#datatables').dataTable( {
} );
} );
datatables太强大,记录起来真是无处下手。 先来看个例子,然后再做详细介绍:
<script type="text/javascript">
$(document).ready(function() {
var table = $('#datatables').DataTable({
"autoWidth": false,
"paging": true,
//"dom": 'T<"clear"><"toolbar">Clfrtip',
"dom": 'iCflrtp',
"iDisplayLength": 100,
"lengthMenu": [[100, 500, 1000, -1], [100, 500, 1000, "所有"]],
"tableTools": {
"sSwfPath": "/js/datatables/tabletools/swf/copy_csv_xls_pdf.swf",
"aButtons": [
{sExtends: "csv", oSelectorOpts: {page: "current" }},
"print"],
"sRowSelect": "os",
},
"stateSave": false,
"processing": true,
"ajax": {
'url': "/test/index",
},
"order": [
[0, "asc"],
[1, "asc"],
[2, "desc"],
],
"columnDefs": [
{width: '25%', targets: 3},
],
"columns": [{
"data": "name",
}, {
"data": "age",
}, {
"data": "job",
}, {
"data": "description",
"visible":false
}],
"sPaginationType": "full_numbers",
"oLanguage": {
"sProcessing": "<img src='/images/datatable_loading.gif'> 努力加载数据中.",
"sLengthMenu": "每页显示 _MENU_ 条记录",
"sZeroRecords": "抱歉, 没有找到",
"sInfo": "从 _START_ 到 _END_ /共 _TOTAL_ 条数据",
"sInfoEmpty": "没有数据",
"sInfoFiltered": "(从 _MAX_ 条数据中检索)",
"sZeroRecords": "没有检索到数据",
"sSearch": "模糊查询: ",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "前一页",
"sNext": "后一页",
"sLast": "尾页"
}
},
});
这里面每个字段都可以说上一番,有些简单很容易理解,像dom这种就很复杂。
展示的效果表格前面:
表格底部是分页:
然后说明一下每个字段的效果都体现在哪里
autoWidth
用来启用或禁用自动列的宽度计算。通常被禁用作为优化(它需要一个有限的时间量来计算的宽度),默认值是true,所以通常将它设为false
分页paging
指定它才能显示表格底部的分页按钮,如果数据量大的话,这个通常需要设置为true,当然它也与dom的值息息相关,如果dom中没有指定p这个字符,它即使为true也是无效的。
dom
这个是我认为最复杂也是功能最强大的字段,当然目前我也只用到了它的冰山一角。
当自定义数据表时,可以根据自身喜好来设置功能元素的默认位置等,可以指定容器,由数据表给出每个HTML控制元件被表示为在domDT选项的单个字符。
dom常用的初始化字符如下:
l - Length changing 选择每页显示行数下拉框的控件
f - Filtering input 搜索过滤控件
t - The Tabletools 导出excel,csv的按钮
i - Information 显示汇总信息(从 1 到 100 /共 1,288 条数据)
p - Pagination 分页控件
r - pRocessing 显示加载时的进度条
C - copy 显示复制,excel的控件
下面四种是在dom中在自定义的位置植入自定义元素和class
< and > - DIV元素
<"class" and > - DIV和Class
<"#id" and > - DIV和ID
<"#id.class" and > - DIV 和ID 和Class
这些元素的先后顺序也决定了对应的控件在表格中显示的位置。举个例子:
“dom”: ‘i<”toolbar”>TCflrtp’, 则在汇总信息(i)左边定义了一个div:toolbar
js如下:
$("div.toolbar").html("<button class='btn btn-primary add_server' ><span>自定义按钮</span></button>");
$(".add_server").click(function(){
location.href ="/server/import"
})
即这是在汇总信息左边会出现一个按钮,点击跳转到另一个页面。这种方式可以在一个集成的表格里植入自定义的东西,非常赞!
对于改变页面上元素的位置,我还愿意多举几个例子:
example 1: 简单的DIV和样式元素设置
/* Results in:
<div class="wrapper">
{filter}
{length}
{information}
{pagination}
{table}
</div>
*/
$('#example').dataTable( {
"dom": '<"wrapper"flipt>'
} );
example 2: 每页行数p,检索条件f,分页p在表格上面,表信息i在表格下面
/* Results in:
<div>
{length}
{filter}
<div>
{table}
</div>
{information}
{pagination}
</div>
*/
$('#example').dataTable( {
"dom": '<lf<t>ip>'
} );
example 3: 表信息i在表上面,检索条件f,每页行数p,处理中r在表下面,并且有清除元素
/* Results in:
<div class="top">
{information}
</div>
{processing}
{table}
<div class="bottom">
{filter}
{length}
{pagination}
</div>
<div class="clear"></div>
*/
$('#example').dataTable( {
"dom": '<"top"i>rt<"bottom"flp><"clear">'
} );
iDisplayLength和lengthMenu
这两个元素是和dom的l字符对应的,
“iDisplayLength”: 100, ——表示默认1页是100行数据
“lengthMenu”: [[100, 500, 1000, -1], [100, 500, 1000, “所有”]], ——-自定义每页显示的行数,
iDisplayLength默认是10行,lengthMenu默认是[[10 25 50 100], [10 25 50 100]]
tableTools
这个也有很多参数,这里只写了常见的。swf可以导出为csv,pdf,xls三种文件,若需要一种,可以在aButtons中指定
"tableTools": {
"sSwfPath": "/js/datatables/tabletools/swf/copy_csv_xls_pdf.swf",
"aButtons": [
{sExtends: "csv", oSelectorOpts: {page: "current" },sFileName: "test.csv", //导出为csv文件,并且指定了文件的名称
},
"print", //打印控件
"sRowSelect": "os",
},
对应的表格控件为:
stateSave
如果设置为true这个是保存当前用户的状态的,比如用户选择当前每页显示500行,那么他重新刷页面这个不是默认的100行,而是记录了用户的行为显示500行。
processing
这个对应dom中的r,即加载数据时显示的进度,这个一般都设置为true,不然数据量大的话用户可能等上几秒却不知怎么回事,显示的控件如下:
ajax
即后端传来的数据,如果按照上述传来的数据格式的话,则下面的url就是后端指定的url:
"ajax": {
'url': "/test/index",
},
order
排序,这个可以对单列排序,可以按照指定的顺序,先按哪列排序再按哪列排序
"order": [
[0, "asc"],
[1, "asc"],
[2, "desc"],
],
//表示先对第1列进行升序排序,再按照第二列升序排序,最后按照第三列降序排序
columnDefs
这个字段可以对列进行很多操作,这个字段也很复杂,功能强大
"columnDefs": [
{width: '25%', targets: 3},
],
上面举的例子的意思是对第四列的宽度设置占所有列宽度的25%,它还有很强大的功能,如改变某列元素的属性,增加列等,如下:
"columnDefs": [
// 将name列变为红色
{
"targets": [0], // 目标列位置,下标从0开始
"data": "name", // 数据列名
"render": function(data, type, full) { // 返回自定义内容
return "<span style='color:red;'>" + data + "</span>";
}
},
// 增加一列,包括删除和修改,同时将需要传递的数据传递到链接中
{
"targets": [4], // 目标列位置,下标从0开始
"data": "name", // 数据列名
"render": function(data, type, full) { // 返回自定义内容
return "<a href='/delete?name=" + data + "'>删除</a> <a href='/update?name=" + data + "'>更新</a>";
}
}
]
columns
这个指定了传过来的数据的字段,visible字段默认是true,如果设置false的话,显示的时候是隐藏的,当然也可以通过空间取消其隐藏。
sPaginationType (pagingType)
sPaginationType: 分页样式,支持四种内置方式,simple、simple_numbers、full和 full_numbers, 默认使用 simple_numbers。即下面四种方式:
simple: ‘Previous’ and ‘Next’ buttons only
simple_numbers: ‘Previous’ and ‘Next’ buttons, plus page numbers
full: ‘First’, ‘Previous’, ‘Next’ and ‘Last’ buttons
full_numbers: ‘First’, ‘Previous’, ‘Next’ and ‘Last’ buttons, plus page numbers
oLanguage
数据表的语言设置,默认都是英文的,可以通过修改下面源码的字段来修改成中文,更可以改为喜欢的展现方式。
另外有点想说明下,开始对于这些个字段的命名不太理解,原来第一个小写字母表示它接受参数的类型。
a: array s:string o:object
"oLanguage": {
"sProcessing": "<img src='/images/datatable_loading.gif'> 努力加载数据中.",
"sLengthMenu": "每页显示 _MENU_ 条记录",
"sZeroRecords": "抱歉, 没有找到",
"sInfo": "从 _START_ 到 _END_ /共 _TOTAL_ 条数据",
"sInfoEmpty": "没有数据",
"sInfoFiltered": "(从 _MAX_ 条数据中检索)",
"sZeroRecords": "没有检索到数据",
"sSearch": "模糊查询: ",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "前一页",
"sNext": "后一页",
"sLast": "尾页"
}
},
rowCallback
还有一个常用的是rowCallback,当创建了行,但还未绘制到屏幕上的时候调用,通常用于改变行的class风格。比如为列为IP的这一行加个超链接,代码接着上面的:
"rowCallback": function(row, data) { //data是后端返回的数据
if(data.ip) {
$('td:eq(3)', row).html('<a target="_blank" href=http://' + data.ip + '>' + data.ip + '</a>');
}
},
//$('td:eq(3)', row)表示选中第四列的元素
则这样的话第四列的IP只要不为空值则都链接到自己的页面。
datatables实在太强大,太方便,我这里说的仍然是冰山一角,下面附录是摘自网上,常用的属性和方法
要注意的是,要被dataTable处理的table对象,必须有thead与tbody,而且,结构要规整(数据不一定要完整),这样才能正确处理。
以下是在进行dataTable绑定处理时候可以附加的参数:
DataTable支持如下回调函数