I define my jquery datatables without any HTML besides the base table element. This is my HTML:
<table id="mytable"></table>
Then I do all the table configuration via the datatables definition. Example code:
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
        );        
    }
});
Now I would like to use the footer callback to show sums of my dataset inside the footer.
Unfortunately, adding HTML to the footer (like in this example: https://datatables.net/examples/advanced_init/footer_callback.html) does not work as the table does not contain any tfoot element and the required row and columns. What would be a clean way to add footer for all my columns?
JSFiddle with the code above: http://jsfiddle.net/36twp251/1/
It's not possible to manipulate footer without presence of <tfoot> element. 
Add appropriate markup as described in DataTables - Installation.
If you don't have access to HTML, see alternative solutions below.
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.
One means of doing this is the following – though I can't necessarily claim it to be 'the smartest':
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 demo.
References:
Array.prototype.reduce().HTMLTableRowElement.find().get().insertBefore().If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With