dataTable是個非常強大的顯示數據表插件。不僅如此,它還可以結合TableTools導出數據,可以導出的類型有 csv,excel,pdf.而且還可以copy,print.
我在項目中用到了這個插件,折騰了好久。遂記錄之。
需求描述:需要從sAjaxSource這個屬性指定的url獲取json數據,然后在顯示出來。
部分頁面:
<table id="example"> <thead> <tr> <th>教師編號</th> <th>教師姓名</th> <th>所屬學院</th> <th>管理對象</th> <th>電話</th> <th>郵箱</th> <th>操作</th> </tr> </thead> <tbody> </tbody> <tfoot> <tr> <th>教師編號</th> <th>教師姓名</th> <th>所屬學院</th> <th>管理對象</th> <th>電話</th> <th>郵箱</th> <th>操作</th> </tr> </tfoot> </table>
該頁面的部分js:
$(document).ready(function () { dt = $('#example').dataTable({ "bProcessing": true, "bServerSide": true, "bSort": false, "sAjaxSource": "xxxx",//這是要請求json數據的url "oLanguage": { "sLengthMenu": "每頁顯示 _MENU_ 條記錄", "sZeroRecords": "對不起,查詢不到任何相關數據", "sInfo": "當前顯示 _START_ 到 _END_ 條,共 _TOTAL_ 條記錄", "sInfoEmtpy": "找不到相關數據", //"sInfoFiltered": "數據表中共為 _MAX_ 條記錄", "sProcessing": "正在加載中...", "sSearch": "搜索", "sInfoEmpty": "顯示 0 至 0 共 0 項", "oPaginate": { "sFirst": "第一頁", "sPrevious": "上一頁 ", "sNext": "下一頁 ", "sLast": "末頁 " } }, "aoColumns": [ { "mData": "teacher_id", "sClass": "center" }, { "mData": "teacher_name", "sClass": "center" }, { "mData": "organization_name", "sClass": "center" }, { "mData": "manageOrganization_name", "sClass": "center" }, { "mData": "teacher_phone", "sClass": "center" }, { "mData": "teacher_email", "sClass": "center" }, { "mData": "admin_id", "sClass": "center" } ], "aoColumnDefs": [ { "aTargets": [6], "mData": "操作", "mRender": function (data, type, full) { return '<a href="javascript:void(0);" class="delete" tag=' + data + '>刪除</a>'; } } ], "fnServerData": fnDataTablesPipeline });
用紅色顯示的aoColumns 是說明請求的json數據是如何對應於表中的單元格。在沒指定之前,遇到了各種各樣的問題,比如有
Datatables warning(table id = 'example'): cannot reinitialise data table
DataTables warning (table id = 'xxxx'): Requested unknown parameter 'xx' from the data source for row 0
不過上段的js要依賴於另一個js文件。該js文件是我從網上獲取並自己做了些修改。它的作用有兩個:第一,請求的數據可以加倍,第二,加倍的數據是緩存的,因此達到了預加載的功能。
貼上 DataTableServerSideData.js:

//前台與后台交互數據,並實現分頁的功能 var oCache = { iCacheLower: -1, bNeedServer: false, //為true則開啟緩存模式 iPipe: 1, //加載數據的倍數 }; function isNeedServer(flag) { oCache.bNeedServer = flag; } function setIpipe(pipe) { if ("/^\d&/".test(pipe)) { oCache.iPipe = pipe; } } function fnSetKey(aoData, sKey, mValue) { for (var i = 0, iLen = aoData.length ; i < iLen ; i++) { if (aoData[i].name == sKey) { aoData[i].value = mValue; } } } function fnGetKey(aoData, sKey) { for (var i = 0, iLen = aoData.length ; i < iLen ; i++) { if (aoData[i].name == sKey) { return aoData[i].value; } } return null; } function fnDataTablesPipeline(sSource, aoData, fnCallback, oSettings) { //var iPipe = 2; /* Ajust the pipe size */ // var bNeedServer = false; var sEcho = fnGetKey(aoData, "sEcho"); var iRequestStart = fnGetKey(aoData, "iDisplayStart"); var iRequestLength = fnGetKey(aoData, "iDisplayLength"); var iRequestEnd = iRequestStart + iRequestLength; oCache.iDisplayStart = iRequestStart; /* outside pipeline? */ if (oCache.iCacheLower < 0 || iRequestStart < oCache.iCacheLower || iRequestEnd > oCache.iCacheUpper) { oCache.bNeedServer = true; } /* sorting etc changed? */ if (oCache.lastRequest && !oCache.bNeedServer) { for (var i = 0, iLen = aoData.length ; i < iLen ; i++) { if (aoData[i].name != "iDisplayStart" && aoData[i].name != "iDisplayLength" && aoData[i].name != "sEcho") { if (aoData[i].value != oCache.lastRequest[i].value) { oCache.bNeedServer = true; break; } } } } /* Store the request for checking next time around */ oCache.lastRequest = aoData.slice(); //bNeedServer = true; if (oCache.bNeedServer) { if (iRequestStart < oCache.iCacheLower) { iRequestStart = iRequestStart - (iRequestLength * (oCache.iPipe - 1)); if (iRequestStart < 0) { iRequestStart = 0; } } oCache.iCacheLower = iRequestStart; oCache.iCacheUpper = iRequestStart + (iRequestLength * oCache.iPipe); oCache.iDisplayLength = fnGetKey(aoData, "iDisplayLength"); fnSetKey(aoData, "iDisplayStart", iRequestStart); fnSetKey(aoData, "iDisplayLength", iRequestLength * oCache.iPipe); oSettings.jqXHR = $.getJSON(sSource, aoData, function (json) { /* Callback processing */ oCache.lastJson = jQuery.extend(true, {}, json); if (oCache.iCacheLower != oCache.iDisplayStart) { json.aaData.splice(0, oCache.iDisplayStart - oCache.iCacheLower); } json.aaData.splice(oCache.iDisplayLength, json.aaData.length); fnCallback(json); }); } else { json = jQuery.extend(true, {}, oCache.lastJson); json.sEcho = sEcho; /* Update the echo for each response */ json.aaData.splice(0, iRequestStart - oCache.iCacheLower); json.aaData.splice(iRequestLength, json.aaData.length); fnCallback(json); return; } }
至此,使用sAjaxSource請求數據完成了。
有些時候,需要刪除表中的某行數據。如果想像刪除普通表一樣刪除tr,我試了貌似不得行。只能利用dataTable提供的方法fnDeleteRow刪除才行。
貼上小段代碼:
//回調函數 function ProcessJson(data) { if (data == "false") { alert("程序錯誤!"); } else { //提交成功 /* delete row which has been checked */ var anSelected = dt.$('tr.row_selected'); if (anSelected.length !== 0) { dt.fnDeleteRow(anSelected[0]); } } }
注意,紅色標識的是獲取class為row_selected一行。如果想試着通過$(this).parent().parent()獲取點擊的tr,那得傳入點擊的this作用域才行。不然怎么獲取得到呢?因為若想刪除,首先得通過后台將數據表中的某條記錄刪除,刪除成功了才能刪除表中的數據吧。所以后來我在處理點擊刪除按鈕時為tr加上一個class,所以在回調函數中就能通過dt.$('tr.row_selected')獲取當時選中的行了。
之前說過,dataTable可以結合TableTools導出excel,csv,pdf格式的文件,不過可惜的是,當導出pdf時會出現中文亂碼,查了很多資料,pdf不支持utf8格式。。如果你知道,希望能告訴我呀~
若要導出數據呢,可以在datatable()中添加:
"oTableTools": { "sSwfPath": "/CSS/swf/copy_csv_xls_pdf.swf", "aButtons": [ { "sExtends": "xls", "sButtonText": "導出excel格式", "mColumns": [1,2,3,4,5,6,7] }, { "sExtends": "csv", "sButtonText": "導出csv格式", "mColumns": [1, 2, 3, 4, 5, 6, 7] }, ] }
那么在頁面中就會出現按鈕了,點擊按鈕,就會出來彈出框,這樣就可以保存文件了。不過需要注意的是:第一,sSwfPath的地址需要正確,如果不正確是不會成功的哦~。第二,你需要引入的js文件有:
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.dataTables.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/TableTools.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/ZeroClipboard.js")"></script>
第三,需要引入css文件:<link rel="stylesheet" href="@Url.Content("~/CSS/TableTools.css")"/>.你不引入試試,你會像我一樣花了一個多小時google做無用功-_-!!
最后,附上官網地址:
TableTools example地址:http://datatables.net/extras/tabletools/examples
需要注意的是:在官網上的TableTools example中操作導出,是能夠成功的。但是,,如果下載到本地,然后通過瀏覽器打開html文件進行操作(也就是瀏覽器地址欄出現E://xxx/xxx/),是不會成功的。外國一個很牛的人Allen說是flash setting的安全問題T_T~