multiple rows per record

multiple rows per record

greitsmagreitsma Posts: 3Questions: 0Answers: 0
edited March 2009 in General
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.

Replies

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Hi greitsma,

    Nice one! Thanks for sharing that with us.

    Allan
  • Philip HarveyPhilip Harvey Posts: 23Questions: 0Answers: 0
    Hi Greita, Allan,

    This looks as if it may be useful to me as well, would you be prepared to post an example ?

    Many thanks
    Phil
  • BelisariusBelisarius Posts: 26Questions: 0Answers: 0
    I'll second that request please? It's something I need to look at soon and an example would be great.

    Does the odd/even row colouring work across each row or each record?

    Cheers

    Andy
  • greitsmagreitsma Posts: 3Questions: 0Answers: 0
    I do not have an example of the output to share partly because I cannot share the company confidential data it would show so I hope the before and after picture of the table is clear.

    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
  • rafis23rafis23 Posts: 6Questions: 0Answers: 0
    i used this code snippet, and it looks great initially. but as soon as i sort the table, the even rows disappear (except for the header).

    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!
  • rafis23rafis23 Posts: 6Questions: 0Answers: 0
    to clarify, the "second half" rows are the ones that disappear after i sort. this code snippet you posted seems to clone the odd/even so that each row pair is either odd or even. i would prefer to have it so that the new even numbered rows (the second halves of the rows) are class "even". but that's a separate issue. the main question i have for now is why the "second-half" rows disappear after i touch the sortable headers.
  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Hi rafis23,

    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
  • rafis23rafis23 Posts: 6Questions: 0Answers: 0
    this is great, allan, thank you! to clarify, do i use fnDrawCallback to add the new row, or fnGetData?
  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Hi rafis23,

    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
  • rafis23rafis23 Posts: 6Questions: 0Answers: 0
    beautiful. thanks again!

    -raf
This discussion has been closed.