multiple rows per record
multiple rows per record
I had a situation where the table contained about 20 items or cells per row (where a row is a database 'record'). This was too many to simply display in a single row as the page would be too wide and require excessive left/right scrolling to see a single record. I could not find any table support functions that could display a single record in multiple rows and keep those associated rows together when sorting and filtering. DataTables solved the problem by using 'fnHeaderCallback' and 'fnRowCallback'. The server simply returns one row per record with 20 cells per row and the two functions split each row into multiple rows for display. The filtering and sorting continue to work fine on the original table from the server and only the presentation is modified with these calllbacks.
This discussion has been closed.
Replies
Nice one! Thanks for sharing that with us.
Allan
This looks as if it may be useful to me as well, would you be prepared to post an example ?
Many thanks
Phil
Does the odd/even row colouring work across each row or each record?
Cheers
Andy
The row coloring is preserved because the css attributes have already been applied to the rows before they are cloned and split.
The callbacks for the header and each row are similar but not identical. The steps are:
1) clone the row
2) calculate half the length of the row
3) delete the cells from the last half of the original row and the first half of the cloned row
4) add the cloned row to the DOM
Following the same principle a row can be split into more than two if needed.
Here is an example of the code.
"fnHeaderCallback": function( firstHeader, aData, displayStart, displayEnd ) {
if ( aData[0]!= undefined && $('th', firstHeader).length >= aData[0].length ){
var secondHeader = $(firstHeader).clone(true);
var half = aData[0].length / 2;
$('th:gt(' + (half-1) + ')', firstHeader).remove();
$('th:lt(' + half + ')', secondHeader).remove();
$(firstHeader).after(secondHeader);
}
},
"fnRowCallback": function( aRow, aData, iDisplayRow, iTableRow) {
var secondRow = aRow.cloneNode(true);
var half = aData.length / 2;
$('td:gt(' + (half-1) + ')', aRow).remove();
$('td:lt(' + half + ')', secondRow).remove();
var frag = document.createDocumentFragment();
frag.appendChild(aRow);
frag.appendChild(secondRow);
return frag;
},
Hope this is helpful.
Glenn Reitsma
what could cause this? i want the rows to cut in half no matter how it is sorted, with the even rows displayed right under the odd rows (2 rows per record).
any help would be appreciated. thanks!
The reason for this is that on the first draw you are modifying the original TR element to be half the width that it was initially. That's fine, but then when you loop around to try and draw the row again, the _now_ "original" row is half of what you expected, since a number of the nodes have been removed! Therefore I'm not sure that this will work all that well.
What I would perhaps suggest trying instead is to use bVisible on the second half of the columns to make DataTables hide them from the display, and then use fnDrawCallback() (or possibly fnRowCallback - although I suspect the former might be slightly easier - see for something similar: http://datatables.net/examples/advanced_init/row_grouping.html) to add the new row. You can use fnGetData, or possibly find the original TDs in the DataTables storage and clone them, to create the new row.
Regards,
Allan
You use a combination of them. In the fnDrawCallback function (you write it - it's a callback from DataTables whenever it does a draw) you can use fnGetData to get the information you want, and then create a new TR element and insert it.
Regards,
Allan
-raf