Filter by column doesn't work after loading server data

Filter by column doesn't work after loading server data

Ironwil616Ironwil616 Posts: 50Questions: 0Answers: 0
edited September 2011 in General
I ran the example in the multi_filter_select.html page, but after plugging it into my web application, I wasn't getting anything in the drop-down lists. I debugged for awhile, and found that my call to fnGetColumnData wasn't yielding any usable data, because the variable 'aiRows' was empty after grabbing server data via ajax and rendering the table with it. I changed to the static HTML table with the data already in it, and the column drop-down lists filters populated correctly. This was from the page:

DataTables individual column filtering example (using select menus)

Anyway, this is all that changed from the working version to the non-working version:
Working
[code]
var oTable = $('#example').dataTable({
"oLanguage": {
"sSearch": "Search all columns:"
}
});
[/code]

Non-working
[code]
var oTable = $('#example').dataTable({
"sDom": 'Rlfrtip',
"bProcessing": true,
"sAjaxSource": "/Home/GetData",
"oLanguage": {
"sSearch": "Search all columns:"
}
});
[/code]

Like I said, the table loads the data without problems, and the data can then be sorted, paged, etc., but the drop-down lists in the footer don't populate with any of the column data. For my last test even the table was exactly the same. I used static data for both, but when I ran the datatables initialization code with the 'sAjaxSource' specified, the static content was replaced with my server data, and the drop-down lists no longer worked. Is this is problem caused by the data not being available when the initialization for the drop-down lists runs? How can I get around this issue?

Replies

  • Ironwil616Ironwil616 Posts: 50Questions: 0Answers: 0
    Looks like my hypothesis was correct. I added this in:

    setTimeout(function () { InitializeFooter(oTable) }, 3000);

    I also wrapped the footer initialization in the function in the above enclosure. After 3 seconds, the drop-down lists populated with the correct values. There's probably a "data retrieved" event that I'll wire this into. I wanted to test it first to make certain I had the cause isolated.
  • Ironwil616Ironwil616 Posts: 50Questions: 0Answers: 0
    I looked over the reference, and thought that what I was looking for was probably 'fnServerData'. There's a success callback, 'fnCallback', which I thought I could use to initialize the footer drop-down list filters. Unfortunately, I couldn't find one example of 'fnCallback' actually being used for anything, so I experimented with it. I tried the following:

    [code]
    var oTable = $('#example').dataTable({
    "sDom": 'Rlfrtip',
    "bProcessing": true,
    "sAjaxSource": "/Home/GetData",
    "fnServerData": function ( sSource, aoData, fnCallback ) {
    /* Add some data to send to the source, and send as 'POST' */
    // aoData.push( { "name": "my_field", "value": "my_value" } );
    $.ajax( {
    "dataType": 'json',
    "type": "GET",
    "url": sSource,
    "data": aoData,
    "success": fnCallback(InitializeFooter(oTable))
    } );
    },
    "oLanguage": {
    "sSearch": "Search all columns:"
    }
    });
    });
    [/code]

    Of course this didn't work, because when I tried to send 'oTable' as a variable to the 'InitializeFooter' function, it hadn't itself been initialized yet. But if I can't use the success callback to initialize the drop-down list column filters, how do I get this to work after fetching server data?
  • Ironwil616Ironwil616 Posts: 50Questions: 0Answers: 0
    Problem fixed! I used the 'fnInitComplete' function to initialize the footer drop-down list filters, and now all is good. I tried 'fnDrawCallback' first, and the first load works great, but it re-initializes the drop-down list filters on every draw, including after a filter occurs. Not exactly what I wanted. The 'fnInitComplete' worked perfectly. Here's the complete setup (minus the 'fnGetColumnData' extension code):

    [code]
    function InitializeFooter() {
    var oTable = $('#example').dataTable();
    /* Add a select menu for each TH element in the table footer */
    $("tfoot th").each(function (i) {
    this.innerHTML = fnCreateSelect(oTable.fnGetColumnData(i));
    $('select', this).change(function () {
    oTable.fnFilter($(this).val(), i);
    });
    });
    }

    $(document).ready(function () {
    $('#example').dataTable({
    "sDom": 'Rlfrtip',
    "bProcessing": true,
    "sAjaxSource": "/Home/GetData",
    "fnInitComplete": function () {
    InitializeFooter();
    },
    "fnServerData": function (sSource, aoData, fnCallback) {
    /* Add some data to send to the source, and send as 'POST' */
    // aoData.push( { "name": "my_field", "value": "my_value" } );
    $.ajax({
    "dataType": 'json',
    "type": "GET",
    "url": sSource,
    "data": aoData,
    "success": fnCallback
    });
    },
    "oLanguage": {
    "sSearch": "Search all columns:"
    }
    });
    });
    [/code]

    I didn't really need to use 'fnServerData' for this example, but there's a strong chance that I'll need to send parameters to the server for this table, so I left it in for now, with the 'aoData.push' commented out. I no longer needed the oTable variable when initializing the datatables table, so I just grabbed it in the 'InitializeFooter' function. When debugging this, I came across that setTimeout enclosure I used to verify the problem:

    setTimeout(function () { InitializeFooter(oTable) }, 1000);

    And I think this is pretty cool. Generally, sending a parameter into setTimeout isn't trivial, especially in IE, but this allows it to work seamlessly. Just an extra nugget.
This discussion has been closed.