Custom filter trigger after table is loaded first time

Custom filter trigger after table is loaded first time

mdiessnermdiessner Posts: 34Questions: 0Answers: 0
edited November 2012 in General
I am having a DT with a working custom column filter that gets triggered by a drop down in the footer of one column. Depending on the value of the drop down it either shows all rows, rows with column value 0, or rows with column value >0.

The on change triggers a oTable.fnDraw() which has a $.fn.dataTableExt.afnFiltering.push() function attached.

I am struggling to set the default filter when page/table is loaded first time to filter value>0. I tried to trigger a change event on the drop down box after page is loaded, and also using fnInitComplete but despite no error in console still all data is shown.

Any ideas / workarounds?

thx
Martin

[code]


$(document).ready(function() {
var oTable = $('#table_main').dataTable( {
"fnInitComplete": function(oSettings, json) {
$('#sel_search_positions').val('zero').change();
}
});


//Select button that wil trigger the filter function by current positions
$('#sel_search_positions').change( function() {
oTable.fnDraw();
});

//filter function that gets triggered by column 3 select drop down (see above)
$.fn.dataTableExt.afnFiltering.push(
function( oSettings, aData, iDataIndex ) {
//filter on current position which is column 3 for example
colFilterID = 3;

//get our filter element
filterElement = aData[colFilterID]*1;

//get our filter critera from the SELECT drop down in footer of column
filterCriteria = $('#sel_search_positions').val();

//CURENT: based on SELECT field sel_search_positions decide how to filter
if(filterCriteria == 'current') {
//filter on current values only
if(filterElement > 0) {
return true;
}
return false;
}

//ZERO: based on SELECT field search_curr_pos decide how to filter
if(filterCriteria == 'zero') {
//filter on not current stock values only, e.g. where current Position is zero 0
if(filterElement == 0) {
return true;
}
return false;
}

//ALL: based on SELECT field search_curr_pos decide how to filter
if(filterCriteria == 'all') {
//show all value regardless
return true;
}
}
);

.....






Current Pos
No Positions
Show All



........
normal table


[/code]

Replies

  • mdiessnermdiessner Posts: 34Questions: 0Answers: 0
    Forgot to say that when changing the drop down 'manually' the filtering is working perfectly - I can show all, zero or >0 values without problems - just struggling to filter initially after DT load to current=>0 positions.
  • allanallan Posts: 63,530Questions: 1Answers: 10,473 Site admin
    edited November 2012
    Hi Martin,

    If you put the `afnFiltering` plug-in code before your DataTables initialisation this should actually work as is. At the moment you initialise the DataTable and then add the filtering function (assuming the document ready has fired, which I'm going to guess it has since its not working!). If you add the filtering function to DataTables first and then initialise the table the filter should be applied on first draw.

    I've put an example of that up here: http://live.datatables.net/ayegog/edit#javascript,html - its a useless filter of course, but it shows that the custom filtering should be applied on 'build'.

    Regards,
    Allan
  • mdiessnermdiessner Posts: 34Questions: 0Answers: 0
    Hi Allan,
    Thanks for your quick reply. Your example works, and I put the [code]afnFiltering[/code] plug-in code before the DT initialisation.

    The problem that I now have is that this stipulates the main data set, e.g. when I then try to use different range column filters (after init) based on user behaviour it will never apply those custom filters on the WHOLE dataset but only on the one that got filtered initially.

    Just to be clear: I have basically created the [code]afnFiltering[/code] push function twice - once with the initial filter before the [code]$(document).ready(function()[/code] and then the second one with the custom range filtering based on a SELECT drop down after the table init [code]var oTable = $('#table_main').dataTable( {...[/code].

    Both functions work, just the second custom function does not have access to the full dataset prior initial filter from the [code]afnFiltering[/code] function.

    Basically I guess I am looking for a "Clear Filter" function to be called prior the custom filter function.

    I am sure someone had this problem before?

    I tried this [code]fnResetAllFilters()[/code] but its not working.

    thx
    Martin
  • mdiessnermdiessner Posts: 34Questions: 0Answers: 0
    I tried the following to clear the filter but it did not work either:

    [code]
    $.fn.dataTableExt.oApi.fnFilterClear = function ( oSettings )
    {
    /* Remove global filter */
    oSettings.oPreviousSearch.sSearch = "";

    /* Remove the text of the global filter in the input boxes */
    if ( typeof oSettings.aanFeatures.f != 'undefined' )
    {
    var n = oSettings.aanFeatures.f;
    for ( var i=0, iLen=n.length ; i
  • mdiessnermdiessner Posts: 34Questions: 0Answers: 0
    Hi Allan,

    In addition to the previous 2 comments I have taken my source code and cleaned out everything that is not necessary and uploaded to your test environment:

    http://live.datatables.net/aqifun/2/edit#preview

    In case you can't see the code a copy at the bottom of this comment.

    Basically once you un-comment the first $.fn.dataTableExt.afnFiltering.push() javascript function then your suggested solution of pre-filtering works just fine.

    However, the SELECT dropdown column filter [3] does not have access to the full data set, although it works for filtering over zero positions.

    Can you please suggest how to clear that filter or any other solution?

    Thanks so much. By the way - your whole system rocks - it's amazing how powerful it is. I have built a massive backend system with it and truly enjoy working with it (apart from the odd thing that I need your help with ;-).

    Thanks,
    Martin


    FULL CODE AS AVAILABLE HERE: http://live.datatables.net/aqifun/2/edit#source

    [code]










    /*
    //initial filter on current bonds only TEMPORARILY DISABLED TO SHOW ALLAN ALL TABLE VALUES OTHERWISE WORKS FINE
    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {
    //filter on current position which is column 3 for example
    colFilterID = 3;

    //get our filter element
    filterElement = aData[colFilterID].replace(',','')*1;

    //filter on current values only
    if(filterElement > 0) {
    return true;
    }
    return false;
    }
    );

    */

    //function to remove all filtering
    $.fn.dataTableExt.oApi.fnFilterClear = function ( oSettings )
    {
    /* Remove global filter */
    oSettings.oPreviousSearch.sSearch = "";

    /* Remove the text of the global filter in the input boxes */
    if ( typeof oSettings.aanFeatures.f != 'undefined' )
    {
    var n = oSettings.aanFeatures.f;
    for ( var i=0, iLen=n.length ; i 0) {
    return true;
    }
    return false;
    }

    //ZERO: based on select field sel_search_positions decide how to filter
    if(filterCriteria == 'zero') {
    //filter on not current stock values only, e.g. where current Position is zero 0
    if(filterElement == 0) {
    return true;
    }
    return false;
    }

    //ALL: based on select field sel_search_positions decide how to filter
    if(filterCriteria == 'all') {
    //show all value regardless
    return true;
    }
    }
    );

    } );







    ID
    Name*
    Crn*
    CurrPos#





     



    Show All
    Current Pos
    No Positions







    1
    Bond 1
    USD
    0



    2
    Bond 2
    EUR
    0



    3
    Bond 3
    EUR
    100,000



    4
    Bond 4
    GBP
    0



    5
    Bond 5
    EUR
    100,000














    [/code]
  • allanallan Posts: 63,530Questions: 1Answers: 10,473 Site admin
    Hi Martin,

    Thanks very much for putting up your example on the live site - its really helpful to be able to see what you are working with. Thanks also for your kind words - great to hear that DataTables is working well for you!

    So to the problem at hand - I might be over simplifying, but I think you only need one filter here do you not - the last column filter. And more specifically you want to me able to have an initial filter applied and allow the user to change the filtering value - is that correct?

    The key thing to remember is that filters in DataTables are cumulative - so if you filter a row out using one filter (your first one here) another filter cannot add it back in (the second one). So yes, you could attempt to clear the filter applied by the first filter (fnClearFilter won't help you since the custom filter is outside of DataTables' scope and it has no idea what a 'clear' might be - set a value to 'NONE' or empty string, or null etc...). To clear the value you'd need to add a little logic to your first filter which would cause it to always return true after the first draw.

    However, rather than having two different filters operating on the same data, can you just use the main filter and set an initial value in the `select` element to get the effect you want? I've made that modification here: http://live.datatables.net/aqifun/3/edit

    Regards,
    Allan
  • mdiessnermdiessner Posts: 34Questions: 0Answers: 0
    Hi Allan,

    You are a star, and I am an idiot. I should have read your first response again and again - as it was actually clear.

    I have moved the ONE function needed outside the document.ready, and made the CURRENT=SELECTED in the drop down.

    All working fine - thanks so much for the help.

    Also thanks for giving more insights into the other API functions - now I read about it a bit more and understand why they don't access the DT scope.

    Best,
    Martin
  • mdiessnermdiessner Posts: 34Questions: 0Answers: 0
    Last question on this topic (I promise!) - if I wanted another custom drop down filter on another (second) column - I am not sure how to do that.

    Either add another afnFiltering function that does this on another column, or in the same function just combine if/then and the output result false/true statements accordingly?

    Thx Allan,
    M
  • allanallan Posts: 63,530Questions: 1Answers: 10,473 Site admin
    I'd say probably add a new filtering function. To be honest you could take either approach, but I like breaking the problem down into its component parts - you've got two filters so you'd have two filtering functions. Then if you want to remove one in future its easier to do.

    > Also thanks for giving more insights into the other API functions - now I read about it a bit more and understand why they don't access the DT scope.

    Scoping is probably the part of DataTables I'm least proud about. The callbacks execute with the scope of the DataTables instance (so you can do things like `this.fnDraw();` in the callback, but internally DataTales uses static functions rather than prototype methods. That's why the settings object is passed around everywhere. Not particularly nice clean Javascript, but changing it would break _everything_. Perhaps when DataTables 2 is on the horizon...

    Not something to worry about unless you are developing complex plug-ins (mainly feature plug-ins), but probably something worth being aware of!

    Regards,
    Allan
  • mdiessnermdiessner Posts: 34Questions: 0Answers: 0
    Hi Allan,

    Thanks - works perfectly with a second filtering function.

    Best,
    Martin
This discussion has been closed.