How to use last row of data as datatables footer

How to use last row of data as datatables footer

xfloydxfloyd Posts: 35Questions: 12Answers: 1

Hi Allan,
I'm looking for a best way to use last row of the json data as a footer row for datatables. Here is what I have so far, http://jsfiddle.net/tdonp2db/ all works great. I just can't figure out how to do the above. I understand that I can use jquery or datatables API to create dynamic footer with totals, but because my json already provides the totals I would rather use it. Any help would be greatly appreciated, and as always inspiring work on your part.

Answers

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    Hi xfloyd,

    Here you go - http://jsfiddle.net/ppvxt8cn/11/.

    The last row is still present, so it is duplicated, but it works a treat! :)

    Hope that's what you were looking for.

    Cheers,

    Colin

  • xfloydxfloyd Posts: 35Questions: 12Answers: 1

    Thanks Colin, I see your code change but I do not see it working. I still only see one footer. Am I missing something?

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    Erm, no idea what happened there, hold on, I'll knock it out again! :(

  • colincolin Posts: 15,112Questions: 1Answers: 2,583
    edited March 2018

    Thankfully, it wasn't too far from the finished version - here it is, hopefully intact this time: http://jsfiddle.net/0v22zr0u/1/

  • colincolin Posts: 15,112Questions: 1Answers: 2,583
    edited March 2018

    Really struggling here - Friday night mental slowdown! Here's the code in case something else goes wrong:

        footerCallback: function(tfoot, data, start, end, display) {
          var api = this.api();
          var lastRow = api.rows().count();
          for (i = 0; i < api.columns().count(); i++) {
            $(tfoot).find('th').eq(i).html(api.cell(lastRow-1,i).data());
          }
        },
    
  • xfloydxfloyd Posts: 35Questions: 12Answers: 1

    Now it does work, thanks Colin. I was looking more for an API approach without jquery. But that might work as well.

  • xfloydxfloyd Posts: 35Questions: 12Answers: 1

    Cool it does the job, and I was able to remove the last row, by using a splice before I loaded the json, http://jsfiddle.net/jmrt4mff/
    Thanks for your help Colin.

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    edited April 2018

    I think this is going to be the most "DataTables way" of doing it:

        this.api().columns().every( function ( i ) {
          this.footer().innerHTML = footer_data[i][ this.dataSrc() ];
        } );
    

    http://jsfiddle.net/jmrt4mff/5/

    It uses columns().every() to loop over the columns, from which you can then use column().footer() to get the cell to update and column().dataSrc() to determine the name of the data point you want to show in that column.

    Allan

    edit fix typo of the footer_data index.

  • xfloydxfloyd Posts: 35Questions: 12Answers: 1

    Hi Allan this is nice solution, now how can I convert "i" index to column data name (data key)

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    column().dataSrc() is the method to get the data source property for the column.

    Allan

  • alvarozalvaroz Posts: 3Questions: 0Answers: 0

    Hi, I'm working with DataTables with an Ajax data source. I'm at lost as how to use this method with Ajax: I can set the tfoot to the last row, however it's duplicated, as I can't use the "data" option, since the data is coming from the "ajax" option. How can the last row be removed? I've tried several ways, but either the row is not removed, or it is removed and shows after a column sorting (and the "total" row is replaced by other in the tfoot). "draw()" in the footerCallback causes the browser to stall.

    Thanks!

  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736

    How can the last row be removed? I've tried several ways, but either the row is not removed, or it is removed and shows after a column sorting (and the "total" row is replaced by other in the tfoot).

    Sounds like you aren't using Datatables API's to remove the row. Have you tried row().remove()?

    "draw()" in the footerCallback causes the browser to stall.

    What are you trying to do with draw() in the footerCallback? Seems like that would cause an infinite loop as the footerCallback would be called after each draw.

    Kevin

  • alvarozalvaroz Posts: 3Questions: 0Answers: 0

    Thank you Kevin. Yes, I'm using row().remove(). It doesn't remove any row. Also, where, then, should I use draw(), if not in the footerCallback?

    Thanks again,
    Alvaro

  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736

    I'm confused why you have draw() in the footerCallback. Please post your Datatables init code so we can see what you are doing.

    Kevin

  • alvarozalvaroz Posts: 3Questions: 0Answers: 0

    Thanks Kevin. I'm not using draw(), because it chokes the browser (recursion, I understand now). However, per the API reference, it must be used after a row().remove().

    My code (minus unrelated functions):

        informe_data = $("#informe-tabla .informe").DataTable({
            colReorder: true,
            fixedHeader: {
                header: true,
            },
            "autoWidth": false,
            paging: false,
            pageLength: false,
            stateSave: false,
            language: {
                  "emptyTable": "No hay resultados. Revise los rangos de fecha y filtros."
            },
            ajax: {
                url: informeName,
                type: 'POST',
                dataSrc: 'informe_rows',
                data: function(d){
                    d.date_start = $("#date-start").val();
                    d.date_end = $("#date-end").val();
                },
            },
            footerCallback: function(tfoot, data, start, end, display) {
                var api = this.api();
                var lastRow = api.rows().count();
                if(lastRow>0) {
                    var footer_data = data.slice(-1) ;
                    api.columns().every( function (i) {
                        this.footer().innerHTML = footer_data[0][this.dataSrc()];
                        
                    });
                    var row = api.row($("#informe-tabla table tr").last()) ;
                    row.remove() ;
                }
            },
        }) ;
    
  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736

    You would be better off trying that code inside initComplete. The footerCallback will be called on each draw (sort, search, page) which would then remove the last row after each draw.

    Kevin

  • alvarozalvaroz Posts: 3Questions: 0Answers: 0

    Thanks, but it didn't work in the initComplete function either. However, I took another approach: I split the totals from the rest of the rows on another array, used "dataSrc" for the main array, and used the "footer" array (informe_totales in my code, below) as HTML for the tfoot. And that worked.

            initComplete: function(settings, data) {
                var api = this.api();
                var lastRow = api.rows().count();
                if(lastRow>0) {
                    var footer_data = data.informe_totales ;
                    api.columns().every( function (i) {
                        this.footer().innerHTML = footer_data[i];
                    });
                }
            }
    
This discussion has been closed.