Je définis mes tables de données jquery sans aucun code HTML en plus de l'élément de table de base. C'est mon HTML:
<table id="mytable"></table>
Ensuite, je fais toute la configuration de la table via la définition de datatables. Exemple de 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
);
}
});
Maintenant, j'aimerais utiliser le rappel de pied de page pour afficher les sommes de mon jeu de données à l'intérieur du pied de page.
Malheureusement, l'ajout de HTML au pied de page (comme dans cet exemple: https://datatables.net/examples/advanced_init/footer_callback.html ) ne fonctionne pas car la table ne contient aucun élément tfoot et la ligne requise colonnes. Quel serait un moyen propre d’ajouter un pied de page pour toutes mes colonnes?
JSFiddle avec le code ci-dessus: http://jsfiddle.net/36twp251/1/
Comme le disent les autres réponses, je dois définir le pied de page à l’avance. Pas parfait, mais au moins, je peux garder mon code HTML propre (il suffit de définir un tableau et son identifiant mais rien de plus)
// 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/
Il n'est pas possible de manipuler le pied de page sans la présence de l'élément <tfoot>
.
Ajoutez le balisage approprié, comme décrit dans DataTables - Installation .
Si vous n'avez pas accès au HTML, voyez les solutions alternatives ci-dessous.
Utilisation de dom
Vous pouvez utiliser dom
pour créer un <div class="footer"></div>
et y ajouter du contenu, par exemple:
$("#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);
}
});
Voir ce jsFiddle pour démonstration.
Ajout de <tfoot>
Vous pouvez ajouter un élément <tfoot>
avec JavaScript before initialiser DataTables, votre code original fonctionnerait sans problème.
Cependant, vous devez insérer le nombre correct d'éléments <th></th>
pour chaque table.
$("#storages").append('<tfoot><tr><th></th><th></th></tr></tfoot>');
Voir ce jsFiddle pour démonstration.
Un moyen de le faire est le suivant - bien que je ne puisse pas nécessairement prétendre que ce soit «le plus intelligent»:
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);
}
Références: