dataTable使用sAjaxSource請求數據的操作


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:

 

View Code
//前台與后台交互數據,並實現分頁的功能
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做無用功-_-!!

 最后,附上官網地址:

http://datatables.net/api

TableTools example地址:http://datatables.net/extras/tabletools/examples

需要注意的是:在官網上的TableTools example中操作導出,是能夠成功的。但是,,如果下載到本地,然后通過瀏覽器打開html文件進行操作(也就是瀏覽器地址欄出現E://xxx/xxx/),是不會成功的。外國一個很牛的人Allen說是flash setting的安全問題T_T~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM