首页 > 技术文章 > 聊聊前段插件之Datatables

wonder4 2016-07-17 14:39 原文

在web开发过程中表格数据展示是一个很常见的功能,而且用户对其要求也比较高,性能、易用性等。今天我推荐一款利器给大家——Datatables;Datatables中文网

  一、介绍


 

Datatables是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。(摘抄自Datatables中文网)

  二、优势


 

  • 分页,即时搜索和排序
  • 几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理
  • 支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation
  • 各式各样的扩展: Editor, TableTools, FixedColumns ……
  • 丰富多样的option和强大的API
  • 支持国际化
  • 超过2900+个单元测试
  • 免费开源 ( MIT license )! 商业支持
  • 摘抄自Datatables中文网

  三、Demo(ajax数据源)


 

  1. 先上效果图

Alt text

  1. 上代码
首先需要在html页面定义带有表头的table
 1 <table class="table table-bordered table-hover" id="example">
 2             <thead>
 3                 <tr>
 4                     <th style="width: 85px">任务编号</th>
 5                     <th style="width: 20px">PRI</th>
 6                     <th style="width: 45px">状态</th>
 7                     <th >任务标题</th>
 8                     <th style="width: 60px">客户</th>
 9                     <th style="width: 40px">PM</th>
10                     <th style="width: 60px">开发</th>
11                     <th style="width: 60px">测试</th>
12                     <th style="width: 60px">完成时间</th>
13                     <th style="width: 300px">备注</th>
14                 </tr>
15             </thead>
16         </table>

 

我这里采用ajax数据源 

  1 var tt = $('#example').DataTable({
  2         ajax:'/task/get_todoList',
  3         columns:[
  4             {'data':"task_no"},
  5             {'data':"PRI"},
  6             {'data':"status"},
  7             {'data':"task_title"},
  8             {'data':"customer_name"},
  9             {'data':"abu_pm"},
 10             {'data':"dev_name"},
 11             {'data':"tester_name"},
 12             {'data':"ekp_expect"},
 13             {'data':"comment"},
 14         ],
 15         "columnDefs": [
 16             {
 17 //                "visible": false,
 18 //                "targets": [10]
 19             },
 20             {
 21                 "render": function(data, type, row, meta) {
 22                     return '<a name="view_on_erp" rel="' + row.ekp_oid + '" target="_blank">' + data + '</a>';
 23                 },
 24                 "targets": 0
 25             },
 26             {
 27                 "render": function(data, type, row, meta) {
 28                     return task_status[data];
 29                 },
 30                 "targets": 2
 31             },
 32             {
 33                 "render": function(data, type, row, meta) {
 34                     switch (row.ekp_task_type){
 35                         case "需求":
 36                         case "升级-零星需求-一般":
 37                         case "开发类-零星需求-一般":
 38                             return '<span class="label label-success">需</span>' + data + '</a>';
 39                             break;
 40                         case "BUG":
 41                         case "产品BUG":
 42                         case "升级-BUG修改-一般":
 43                         case "升级-BUG修改-紧急":
 44                             return '<span class="label label-danger">B</span>' + data + '</a>';
 45                         case "升级-咨询评估":
 46                             return '<span class="label label-info">咨</span>' + data + '</a>';
 47                         default:
 48                             return '<span class="label label-primary">'+row.ekp_task_type.substring(0,1)+'</span>' + data + '</a>';
 49                     }
 50 
 51                 },
 52                 "targets": 3
 53             },
 54             {
 55                 "render": function(data, type, row, meta) {
 56                     return  (data)? data+'('+row.developer_workload+")":"";
 57                 },
 58                 "targets":6
 59             },
 60             {
 61                 "render": function(data, type, row, meta) {
 62                     return  (data)? data+'('+row.tester_workload+")":"";
 63                 },
 64                 "targets":7
 65             },
 66             {
 67                 "render": function(data, type, row, meta) {
 68                     return  data.substring(0,10);
 69                 },
 70                 "targets":8
 71             },
 72         ],
 73         "createdRow": function ( row, data, index ) {
 74             $(row).attr("rel",data.id);
 75             switch (data.status)
 76             {
 77                 case 1:
 78                     $(row).find("td:eq(6)").addClass("or_doing");
 79                     break;
 80                 case 2:
 81                     $(row).find("td:eq(7)").addClass("or_doing");
 82                     break;
 83 
 84             }
 85         },
 86         lengthMenu: [15,30,45,60,75,90,"ALL"],//这里也可以设置分页,但是不能设置具体内容,只能是一维或二维数组的方式,所以推荐下面language里面的写法。
 87         paging: false,//分页
 88         ordering: true,//是否启用排序
 89 //        order: [ [ 0, 'asc' ]],
 90 //                searching: true,//搜索
 91         dom: "<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>",
 92         language: {
 93             lengthMenu: '每页<select class="form-control input-xsmall">' + '<option value="15">15</option>' + '<option value="30">30</option>' + '<option value="50">50</option>' + '<option value="100">100</option>' + '</select>条记录',//左上角的分页大小显示。
 94             search: '搜索:',//右上角的搜索文本,可以写html标签
 95             paginate: {//分页的样式内容。
 96                 previous: "上一页",
 97                 next: "下一页",
 98                 first: "第一页",
 99                 last: "最后"
100             },
101             zeroRecords: "没有找到相关内容",//table tbody内容为空时,tbody的内容。
102             //下面三者构成了总体的左下角的内容。
103             info: "总共_PAGES_ 页,显示第_START_ 到第 _END_ ,筛选之后得到 _TOTAL_ 条,初始_MAX_ 条 ",//左下角的信息显示,大写的词为关键字。
104             infoEmpty: "0条记录",//筛选为空时左下角的显示。
105             infoFiltered: ""//筛选之后的左下角筛选提示,
106         },
107         showRowNumber:true,
108         bAutoWidth:false,
109     });
View Code

四、说说过程中遇到的问题:


 

Q1:如何自定义查询?

A:datatables支持自定义表格布局,你可以根据自己的情况绘制不一样的布局;我这里是在表格的顶部加入了一个查询和一个自定义按钮。

1 $(document).on("click", ".btn-search", function (e) {
2             var keyword = $('.search-form[type="search"]').val();
3             if(keyword === '') {
4                 $.toast("请输入查找内容","info");
5                 return false;
6             }
7             tt.search(keyword).draw();
8         });

给查询按钮绑定事件,调用datatables的search()方法,然后再重绘datatable(draw())即可。

Q2:表格报错,为什么不能正常展示数据?

 

A:这个问题可能由两种情况导致(我遇到的情况),一种表格头部定义的列数和数据行定义的列不一样会提示以上错误;第二种情况就是服务端返回的数据格式不正确,第一次使用插件的时候,没有认证看api导致在这个地方排查了很久才找到原因。

标准数据源格式:

 1 {
 2     "data": [
 3         {
 4             "id": 1, 
 5             "url": "http://www.gbtags.com/gb/index.htm", 
 6             "title": "Online Program knowledge share and study platform"
 7         }, 
 8         {
 9             "id": 2, 
10             "url": "http://www.gbtags.com/gb/listcodereplay.htm", 
11             "title": "Share Code Gbtags"
12         }, 
13         {
14             "id": 3, 
15             "url": "http://www.gbtags.com/gb/gbliveclass.htm", 
16             "title": "Online live Gbtags"
17         }, 
18         {
19             "id": 4, 
20             "url": "http://www.gbtags.com/gb/explore.htm", 
21             "title": "Explorer Gbtags"
22         }
23     ]
24 }
View Code

Q3:如何给行、列绑定属性?

A:datatables提供了createdRow这个回掉函数(function ( row, data, index )),当创建当前行时执行,入参分别是当前行js对象、当前行数据、行号。对于单元格的属性以及数据翻译都可以使用render函数(function(data, type, row, meta)),入参分别是指当前单元格数据、row是单元格所在行的数据。

 Q4:使用模态窗口编辑行数据后,如何只刷新当前行?

  A:这里可以调用datatables的ajax.reload();第二个参数来控制是否刷新页面。

 tt.ajax.reload(null,false); 

 Q5:待续.... 

推荐阅读