individual column filtering meets AJAX source!

individual column filtering meets AJAX source!

FloFlo Posts: 9Questions: 0Answers: 0
edited August 2013 in DataTables 1.9
Hi,

I am trying to get the individual column filtering (select) example working with an AJAX source.

The table displays perfectly but at this point, unfortunately, all my drop downs are empty.

My code is as follow:

$(document).ready(function() {
var oTable = $('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": 'json.txt',
"aoColumns": [
{ "mData": "id_region" },
{ "mData": "region_name" },
{ "mData": "division" }
]
} );

$("tfoot th").each( function ( i ) {
this.innerHTML = fnCreateSelect(oTable.fnGetColumnData(i));
$('select', this).change( function () {
oTable.fnFilter( $(this).val(), i );
} );
} );
} );

apparently, oTable.fnGetColumnData returns an empty array because aiRows.length is always 0. I just don't understand why!

Am I doing something wrong?

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    You need to create the column filter elements in fnInitComplete . Ajax is async (hence the name :-) ) so currently your `fnCreateSelect` loop is executing before the data has been loaded by Ajax. Put that code block into fnInitComplete and it will work ok.

    Allan
  • FloFlo Posts: 9Questions: 0Answers: 0
    That makes a lot of sense, thank you!

    I am now using fnInitComplete. But it is still not working:

    [code]





    function fnCreateSelect( aData )
    {
    var r='', i, iLen=aData.length;
    for ( i=0 ; i
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    edited August 2013
    Ah - it took me a second there, but I suspect the issue is with the fnGetColumnData plug-in and using mData rather than just an array value.

    I don't suppose you fancy trying out v1.10 (its pre-beta at the moment, but quite stable!)? With 1.10 you would do something like in this example: https://github.com/DataTables/DataTablesSrc/blob/1_10_wip/examples/api/multi_filter_select.xml#L11 .

    1.10-dev latest is available here: https://github.com/DataTables/DataTables/blob/1_10_wip/media/js/jquery.dataTables.js .

    That will work nicely with mData and doesn't require any plug-ins.

    Allan
  • FloFlo Posts: 9Questions: 0Answers: 0
    edited August 2013
    I loaded the v1.10 and I was able to make it work! Thank you!

    I followed the examples in the latest git repository, so this how it looks:

    [code]




    $(document).ready(function() {
    $('#example').dataTable( {
    "bProcessing": true,
    "sPaginationType": "full_numbers",
    "ajax": {
    "url": "json.txt",
    "dataSrc": ""
    },
    "columns": [
    { "data": "model" },
    { "data": "address" },
    { "data": "version" },
    ],
    "fnInitComplete": function(oSettings, json) {
    var table = $('#example').DataTable();
    $("#example tfoot th").each( function ( i ) {
    var select = $('Filter on:')
    .appendTo( this )
    .on( 'change', function () {
    table.column( i )
    .search( $(this).val() )
    .draw();
    } );

    table.column( i ).data().unique().sort().each( function ( d, j ) {
    select.append( ''+d+'' )
    } );
    } );
    }
    } );
    } );

    [/code]

    Now, if I wanted the drop downs to be interdependent, meaning a selection on one of them would determine what fields are available in the other drop downs... How difficult would it be? :D
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    What you'd want to do, I think, is use the `drawCallback` option ( fnDrawCallback in 1.9-) and have it regenerate the s on every draw, using `table.column( i, { filter: 'applied' } )...` to get just the data after filtering.

    Allan
  • FloFlo Posts: 9Questions: 0Answers: 0
    Thanks, I will try to get this working soon, I'll post the code when I am done (or stuck!).
  • FloFlo Posts: 9Questions: 0Answers: 0
    Thanks again Allan.

    Considering the behavior of drawCallback, I can stop using initComplete like so:

    [code]



    $(document).ready(function() {
    $('#example').dataTable( {
    "bProcessing": true,
    "oLanguage": {
    "ajax": {
    "url": "json.txt",
    "dataSrc": ""
    },
    "columns": [
    { "data": "model" },
    { "data": "address" },
    { "data": "version" },
    ],
    "fnDrawCallback": function( oSettings ) {
    var table = $('#example').DataTable();
    $("#example tfoot th").empty();
    $("#example tfoot th").each( function ( i ) {
    var select = $('Filter on:')
    .appendTo( this )
    .on( 'change', function () {
    table.column( i, { filter: 'applied' }).search($(this).val()).draw();
    } );
    table.column( i, { filter: 'applied' }).data().unique().sort().each( function ( d ) {
    select.append( ''+d+'' )
    } );
    });
    }//fnDrawCallback
    } );
    } );

    [/code]

    That's as close as I get. Making it smarter seems a bit out of my league. Anybody interested?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Other than making it as a plug-in and possibly a few optimisations to only regenerate the selects when needed - how would you make it "smarter"?

    Allan
  • FloFlo Posts: 9Questions: 0Answers: 0
    With my code, the dropdown menu from which a value is chosen (on call) sees its list updated as well, it would look better if it became grayed out or kept its original list (becomes "sticky" until the next selection).

    Actually, just as a note, (I don't know if it's a bug or expected behavior) when the dropdown is in the footer, a .draw will reset the dropdown displayed value (so in my case, every dropdowns show "Filter on:" after a draw). But if you create the dropdowns outside the table, the selected value "survives" the .on call since the draw only affects the table.

    Ultimately, I think I would like to be able to do this (left side on the page):
    https://code.google.com/apis/ajax/playground/?type=visualization#dependent_controls
    It's probably easier than I am making it, I just don't have the required brain power! I have been trying to mimic it all day yesterday, no dice... So really when I say smart, I mean something that behave logically.

    And I am pretty sure it should be possible to make it so that you can select more than one value in the dropdown (using a regexp on column?), like so:
    https://code.google.com/apis/ajax/playground/?type=visualization#categoryfilter_control
    But I get easily greedy when it comes to functionality!

    Now, if someone were to implement any of these as a plugin, I would be eternally grateful :D
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    > Actually, just as a note, (I don't know if it's a bug or expected behavior) when the dropdown is in the footer, a .draw will reset the dropdown displayed value

    Expected, but probably still considered a bug. The code would need to get the current value being used for the filter and then set the value on every regeneration. Or perhaps just before the generation, get eh value and immediately after set it again.

    > And I am pretty sure it should be possible to make it so that you can select more than one value in the dropdown (using a regexp on column?)

    Yes - you could use size="..." to allow multiple selections and then a bit of regex to do the filter.

    Allan
  • FloFlo Posts: 9Questions: 0Answers: 0
    Thanks, I will keep trying to get it closer to something that make sens and post the results.
  • drpuddingqdrpuddingq Posts: 9Questions: 0Answers: 0
    Flo -- did you ever make progress on interdependent filtering? I am looking for the same functionality and would appreciate seeing how you solved. Thanks!
  • FloFlo Posts: 9Questions: 0Answers: 0
    I am actually looking at yadcf (http://yadcf-showcase.appspot.com/) but it seems to have difficulties with mData (AJAX source - array of objects).
  • daniel_rdaniel_r Posts: 460Questions: 4Answers: 67
    For the record, yadcf fully support mData , not only that, it support deep mData , here a live showcase example : http://yadcf-showcase.appspot.com/ajax_mData_source.html
This discussion has been closed.