使用Javascript添加jquery datatables表格页脚而不使用HTML

7
我使用不包含任何HTML的基本表格元素来定义我的jQuery Datatables。以下是我的HTML代码:

```

```

<table id="mytable"></table>

然后我通过datatables定义来进行所有表格配置。示例代码:

var dataSet = [
    {name: "storage101", size: 492},
    {name: "storage102", size: 742},
    {name: "storage103", size: 423}
]

$.extend($.fn.dataTable.defaults, {
    sDom: '<"top"i>rCt<"bottom"flp><"clear">'
});

$("#storages").dataTable({
    data: dataSet,
    aoColumns: [
        {title: "Name", mData: "name"},
        {title: "Size", mData: "size"}
    ],
    oLanguage: {sEmptyTable: "No logs"},
    fnFooterCallback: function(nRow, aaData, iStart, iEnd, aiDisplay) {
        var api = this.api();
        var size = 0;
        aaData.forEach(function(x) {
            size += (x['size']);
        });
        // I need a footer in my table before doing this, what is the smartest way to add the footer?
        $(api.column(1).footer()).html(
            size
        );        
    }
});

现在我希望使用页脚回调函数来显示我的数据集中的总和。
不幸的是,将HTML添加到页脚(就像这个例子中:https://datatables.net/examples/advanced_init/footer_callback.html)是不行的,因为表格不包含任何tfoot元素以及所需的行和列。
有什么干净利落的方法可以为所有列添加页脚呢?
上面的代码JSFiddle链接: http://jsfiddle.net/36twp251/1/

你能否在你的问题中添加更多的代码/信息,以便我们能够重现你的问题?如果可能的话,可以fork这个JS Fiddle来重现你的使用情况吗?可以使用JS Fiddle的"echo" API来包含AJAX,并在另一个SO问题"AJAX in jsFiddle"中进行一些澄清。 - David Thomas
@DavidThomas,好的,我已经相应地更改了代码演示样板,应该可以很好地解决问题! - Wolkenarchitekt
如果没有<tfoot>元素,您将无法为DataTables添加页脚。所以您是在问如何在不修改HTML的情况下完成这个功能吗?我猜您无法控制HTML,对吗? - Gyrocode.com
3个回答

11

原因

在没有 <tfoot> 元素的情况下,无法操作页脚。

解决方案 #1

按照 DataTables - 安装 中所述添加适当的标记。

解决方案 #2

如果您无法访问HTML,请参见以下备选解决方案。

  • Using dom

    You can use dom to create a <div class="footer"></div> and add content there, for example:

    $("#storages").dataTable({
       dom: '<"top"i>rCt<"footer"><"bottom"flp><"clear">',
       columns: [
          {title: "Name", data: "name"},
          {title: "Size", data: "size"}
       ],
       fnFooterCallback: function(nRow, aaData, iStart, iEnd, aiDisplay) {
          var api = this.api();
          var size = 0;
          aaData.forEach(function(x) {
                size += (x['size']);
          });
          $('.footer').html(size);
       }
    });
    

    See this jsFiddle for demonstration.

  • Adding <tfoot>

    You can add <tfoot> element with JavaScript before initializing DataTables, then your original code would work without problems.

    However you need to insert correct number of <th></th> elements for each table.

    $("#storages").append('<tfoot><tr><th></th><th></th></tr></tfoot>');
    

    See this jsFiddle for demonstration.


在通过JavaScript将tfoot(页脚)行添加到表格后,DataTable列不再扩展(nowrap),它们显示固定宽度,并且其中的数据换行。 - rajeev

2
以下是一种做法,虽然我不能保证它是“最聪明的”:
fnFooterCallback: function (nRow, aaData, iStart, iEnd, aiDisplay) {
    // getting a reference to the <table> itself (as a jQuery object):
    var table = this;
    var api = table.api();
    var size = 0;
    aaData.forEach(function (x) {
        size += (x['size']);
    });

    // finding the number of cells in the row with the largest
    // number of cells (for later use as a colspan attribute,
    // assuming that you want only one cell in the <tr> of the
    // footer).
    // first finding all <tr> elements within the <table>,
    // using get() to convert that collection to an array:
    var maxColumnLength = table.find('tr').get()
    // using Array.prototype.reduce() to compare
    // the length (size) of each row's cells collection:
                          .reduce(function (a, b) {
    // keeping the current <tr> (a) if its cells.length
    // is larger than the currently-assessed <tr> (b):
                              return a.cells.length > b.cells.length;
    // finding the number of cells contained in the
    // <tr> that has the largest collection of cells:
                          }).cells.length;

    // setting the tfoot variable to *either* the current
    // <tfoot> element (if one might exist from being
    // previously created), or creating
    // a <tfoot> if one does not already exist:
    var tfoot = this.find('tfoot').length ? this.find('tfoot') : $('<tfoot>', {
    // setting the innerHTML of the created-<tfoot>:
        'html': '<tr><td class="result" colspan="' + size + '"></td></tr>'
    // inserting it before the first <tbody> element:
    }).insertBefore($(this).find('tbody'));

    // finding the <td> element with the class of 'result'
    // (obviously adjust to taste), and setting its text:
    tfoot.find('td.result').text(size);
}

JS Fiddle演示

参考资料:


0

正如其他答案所说,我需要事先定义页脚。虽然不完美,但至少我可以保持我的HTML干净(只定义表格及其ID而已):

// globally defined table to be reused in several views
$.fn.storageTable = function() {
    $(this).append("<tfoot><tr><td></td><td></td></tr></tfoot>")
    return this.dataTable({
        data: dataSet,
        aoColumns: [
            {title: "Name", mData: "name"},
            {title: "Size", mData: "size"}
        ],
        oLanguage: {sEmptyTable: "No logs"},
        fnFooterCallback: function(nRow, aaData, iStart, iEnd, aiDisplay) {
            var api = this.api();
            var size = 0;
            aaData.forEach(function(x) {
                size += (x['size']);
            });
            $(api.column(1).footer()).html(size);       
        }
    });
}

// sample usage
$("table-storages").storageTable();

JSFiddle: http://jsfiddle.net/ifischer/Ljwgrkq0/3/

JSFiddle:{{link1:http://jsfiddle.net/ifischer/Ljwgrkq0/3/}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接