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~

posted @ 2013-04-11 12:03  爱生活者wmmang  Views(22095)  Comments(4Edit  收藏  举报