以前用EasyUI的,但是最近想做前端的表格,找到了JQuery的Datatables插件,非常不错。

本来以为给表格加一个序号很简单,可是看了Datatables的官方实现看似代码也不简单,测试发现了一些问题,用的不爽。网络上并没有搜索到好的解决方案,就跟踪代码,自己找到了一种方法,本文在最后就给出了这种实现。


1、版本问题

最新的版本1.10,和以前版本做了很大的调整,但是也部分兼容老版本Api的使用。不过官网给出的例子都是新版的使用方式。

新老版本对照表,可以参照 http://dt.thxopen.com/upgrade/1.10-convert.html


2、表格增加序号列(官方)

官网提供了一个例子 http://www.datatables.net/examples/api/counter_columns.html


测试页如下

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>databases测试页</title>
<link rel="stylesheet" href="css/bootstrap.min.css" />
<link rel="stylesheet" href="css/dataTables.bootstrap.min.css" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="js/dataTables.bootstrap.min.js"></script>
<script>
    var gTable = null;
    function initData() {
        if (gTable) {
            gTable.destroy();//api
        }
        gTable = $('#tables').DataTable({
            "ordering" : true,//options,它是强于列的控制,所以这里开放,列上进制
            "searching" : false,
            "serverSide" : true,
            "language" : {
                "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" : "末页"
                },
                "oAria" : {
                    "sSortAscending" : ": 以升序排列此列",
                    "sSortDescending" : ": 以降序排列此列"
                }
            },
            "ajaxSource" : "books.json",
            "columns" : [ {
                // 序号列,如果不给data就会提示
                width : '40px'
            }, {
                "data" : "imgUrl",
                "width" : '150px',
                "render" : function(data, type, row, meta) {
                    if (data)
                        return '<img src="'+data+'">';
                    else
                        return '';
                }
            }, {
                "data" : "title",
                "width" : '150px'
            }, {
                "data" : "author",
                "width" : '150px'
            }, {
                "data" : "publisher",
                "width" : '125px'
            }, {
                "data" : "pubDate",
                "width" : '100px'
            } ],
            "columnDefs" : [ {
                "searchable" : false,
                "orderable" : false,
                "targets" : [ 0, 1, 2, 3, 4, 5 ]
            } ],
            "order" : [ [ 2, 'asc' ] ]
        });
        gTable.on('order.dt search.dt', function() {
            gTable.column(0, {
                search : 'applied',
                order : 'applied'
            }).nodes().each(function(cell, i) {
                cell.innerHTML = i + 1;
            });
        }).draw();
    }
    $(function() {
        initData();
    });
</script>
</head>
<body class="easyui-layout">
    <div class="container">
        <h1 class="page-header">
            <span class="glyphicon glyphicon-search"></span> 图书信息
        </h1>
    </div>
    <div id="infoShow" class="container">
        <h3>图书信息</h3>
        <div class="row">
            <table id="tables"
                class="table table-striped table-bordered table-hover">
                <thead>
                    <tr>
                        <th>序号</th>
                        <th>图片</th>
                        <th>名称</th>
                        <th>作者</th>
                        <th>出版社</th>
                        <th>出版日期</th>
                    </tr>
                </thead>
                <tbody>
                </tbody>
            </table>
        </div>
    </div>
    <div style="height: 50px;"></div>
</body>
</html>

测试效果如下

总是会提示一个有一个错误


wKiom1ZgT5qSsZTVAACQwrALB0U693.png


问题的说明 https://datatables.net/manual/tech-notes/4。但是这个说明不能提供任何帮助。

点击这个确定按钮后,出现下面的列表。


wKioL1ZgUEuBKPBhAAG2EM_2x0o780.png


上图,序号列没有值,其实下了断点知道,draw()执行的时机比较早,会被column的data数据null刷掉。


wKiom1ZgT_6xIo3tAACPYJIifp8145.png


官方的例子没有给出更多信息,而且我觉得上面的代码实现很复杂,而且资料少,我也不知道提示如何消除,而且是否值得花时间解决呢。

总之,最后成功的刷出第一页的序号列,但是第二页、第N页失败。我是动态从后端返回json数据。



3、data实现(方便,非官方实现)

自己动手丰衣足食啊,既然column的data可以是一个函数,那么就看看参数中的数据。结果确实发现了一些有用的数据,开始动手。


代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>databases测试页</title>
<link rel="stylesheet" href="css/bootstrap.min.css" />
<link rel="stylesheet" href="css/dataTables.bootstrap.min.css" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="js/dataTables.bootstrap.min.js"></script>
<script>
    var gTable = null;
    function initData() {
        if (gTable) {
            gTable.destroy();//api
        }
        gTable = $('#tables').DataTable({
            "ordering" : true,//options,它是强于列的控制,所以这里开放,列上进制
            "searching" : false,
            "serverSide" : true,
            "language" : {
                "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" : "末页"
                },
                "oAria" : {
                    "sSortAscending" : ": 以升序排列此列",
                    "sSortDescending" : ": 以降序排列此列"
                }
            },
            "ajaxSource" : "books.json",
            "columns" : [ {
                width : '40px',
                data : function(row, type, set, meta) {
                    var c = meta.settings._iDisplayStart + meta.row + 1;
                    return c;
                }
            }, {
                "data" : "imgUrl",
                "width" : '150px',
                "render" : function(data, type, row, meta) {
                    if (data)
                        return '<img src="'+data+'">';
                    else
                        return '';
                }
            }, {
                "data" : "title",
                "width" : '150px'
            }, {
                "data" : "author",
                "width" : '150px'
            }, {
                "data" : "publisher",
                "width" : '125px'
            }, {
                "data" : "pubDate",
                "width" : '100px'
            } ],
            "columnDefs" : [ {
                "searchable" : false,
                "orderable" : false,
                "targets" : [ 0, 1, 2, 3, 4, 5 ]
            } ],
            "order" : [ [ 0, 'asc' ] ]
        });
    }
    $(function() {
        initData();
    });
</script>
</head>
<body class="easyui-layout">
    <div class="container">
        <h1 class="page-header">
            <span class="glyphicon glyphicon-search"></span> 图书信息
        </h1>
    </div>
    <div id="infoShow" class="container">
        <div class="row">
            <table id="tables"
                class="table table-striped table-bordered table-hover">
                <thead>
                    <tr>
                        <th>序号</th>
                        <th>图片</th>
                        <th>名称</th>
                        <th>作者</th>
                        <th>出版社</th>
                        <th>出版日期</th>
                    </tr>
                </thead>
                <tbody>
                </tbody>
            </table>
        </div>
    </div>
    <div style="height: 50px;"></div>
</body>
</html>


重点就是下面这一句

meta.settings._iDisplayStart + meta.row + 1;

经过分析得知:

meta.settings._iDisplayStart 每一次显示的记录的起始索引;

meta.row+1 是当前页的行索引,加1就是行号;

两者相加,就是当期的行序号。


这个方法,不是官方提供或推荐的方法,但是在data中处理好显示的数据,我觉得更加的直观,而且代价更小。

也许使用老版本的datatables的朋友有更绝的方法,可以提供给我学习,但是我没有搜索到。但是从代码量上来看,我的实现简单易用。


看效果

wKioL1ZgUKfyor6PAAHygqbtJlM168.png


4、最后

Datatables我是初次尝试,而且一上来就用了1.10新版,网上大把的旧版实现例子,但是就是想试一试新版是否可以更加的方便。

希望能帮助到需要的朋友,抛砖引玉最好。