How can I to keep an accurate count of rows by category?

How can I to keep an accurate count of rows by category?

mike_schmidtmike_schmidt Posts: 2Questions: 0Answers: 0
edited February 2013 in DataTables 1.9
Here is my situation: I have a table with about 500+ items, each of them labelled with a status: running, pending, or dead (these are linux systems being monitored).

Basically, the page should be like this:

total count: count_total, running: count_running, pending: count_pending, dead: count_dead
table here

Here is an appropriate excerpt of the datatables setup:

[code]
function clr_count() {
count_total = 0; $('#disp_total').text(count_total);
count_dead = 0; $('#disp_dead').text(count_dead);
count_pending = 0; $('#disp_pending').text(count_pending);
count_running = 0; $('#disp_running').text(count_running);
}

function set_count(status) {
count_total++; $('#disp_total').text(count_total);
switch(status) {
case 'running': count_running++; $('#disp_running').text(count_running); break;
case 'pending': count_pending++; $('#disp_pending').text(count_pending); break;
case 'dead': count_dead++; $('#disp_dead').text(count_dead); break;
}}

$(document).ready(function() {
var oTable = $('#monitor').dataTable( {
"bJQueryUI": true,
"bProcessing": true,
"bPaginate": true,
"bStateSave": true,
"bInfo": true,
"sScrollX": '100%',
"aLengthMenu": [[10,25,50,100,-1],[10,25,50,100,'All']],
"sAjaxDataProp": "data.aaData",
"sAjaxSource": '/api/Impact/list?group=canada-post;fmt=json',
"aoColumnDefs": [
{ aTargets: [ 0 ], sClass:"tabBodyColAlert", sWidth: "16px" },
{ aTargets: [ 1 ], sClass:"tabBodyColStatus", mRender:function ( data, type, full ) { set_count(full[1]); return set_status(full[1]); }},
.....
"fnPreDrawCallback": function ( oSettings) {
clr_count();
},
....

[/code]

Here is what happens:
1. When the table is drawn from scratch, the mRender function for cell 1 is called three times, sometimes four. This happens twice between the first fnPreDrawCallback call and the second, and once after the second. If I don't clear the count (via the fnPreDrawCallback function) it reflects three times the count. However, with the clear, the final count is all right. (fnPreDrawCallback is effectively called twice, as others have mentioned)

2. If I filter the table, fnPreDrawCallback clears the counts, the mRender function is called for each result, and the new count is correct, reflecting the result of the filter.

3. But if I change the number of lines per page, for example from 10 lines to 25 using the drop down, without reloading the page, the fnPreDrawCallback clears the count, and the row rendering functions are not called, so the count stays at 0. I've tried using fnDrawCallback, fnHeaderCallback, fnInfoCallback, and they all seem to work in lockstep; I have been unable to find a way to get the count to stay when changing pagination. I attempted to check several properties in the oSettings object, but was unable to identify one that didn't break something else.

Is there any way to do what I want to do? I'm nearly there, if I could tell fnPreDrawCallback not to clear on a pagination change, it would be perfect.
Of course, I'm curious as to why the mRender function is called several times, as I have several cases where I expect to use the mRender function.

Replies

  • mike_schmidtmike_schmidt Posts: 2Questions: 0Answers: 0
    Finally, I ended up solving my problems by re-reading the documentation for one part, and the help of the debugger in another part.. I now realize that the functions we provide to mRender need to take into account the processing type, which is critical to managing what is displayed. So, by setting my status/count function to:

    [code]
    function render_status( data, type, full ) {
    switch (type) {
    case 'display':
    set_count(data);
    return set_status(data);
    case 'filter':
    set_count(data);
    default: return data;
    }
    }
    [/code]

    I end up counting only on the display and filter phases. No more extra counts, since on a call to the mRender function with a type of 'type' or 'sort' does not need recounting.

    For the fnPreDrawCallback, I found the solution by carefully looking at oSettings in each different situation, and found that when just changing the page size, neither bFiltered nor bSorted were true, but in all the other cases, one or both were set.
    So the following code fixed now resets the table only if the dataset presented to the user changes:

    [code]
    "fnPreDrawCallback": function ( oSettings) {
    if (oSettings.bFiltered || oSettings.bSorted ) {
    clr_count();
    }
    }
    [/code]

    Just goes to show that sometimes going back to the author's docs are the best thing to do.
    I hope that others can benefit from my experience with this case.
This discussion has been closed.