on page reload multiple filter values are not shown in input field with bStateSave true

on page reload multiple filter values are not shown in input field with bStateSave true

edited September 2010 in General Posts: 2
I don't know if this is a bug or I'm doing something wrong but here is a question:

- if you add in your example (api/multi_filter.html) a state saving option like this:

$(document).ready(function() { var oTable = $('#example').dataTable( { "oLanguage": { "sSearch": "Search all columns:" }, "bStateSave": true } ); )}; etc... etc...

...the result should be a table with multiple filter on every column and with saving values to cookies. And everything works fine except that on page reload I get every saved value except values in multiple filters. Actually, I get them too, the data in table shows that these filters are active, but they are not printed in input fields like the main search value.

I tried to find anything in .js but everything looks just fine. The cookie is reloaded, value is here, data in table shows that the multiple filter is active, but the value got from cookie is not printed in input field after page reload.
(the same thing on FF, Safari, Chrome on OS X 10.6)

Is it possible that we can show this values somehow?

Regards,
Marko

Replies

  • Posts: 22,739
    Hi Marko,

    I'm afraid this isn't a bug - the input controls for the individual columns are outside the control of DataTables - i.e. the DataTables core knows nothing about them, it just gets a function call from the filters when they have a suitable event take place on them. So there is no way for DataTables to fill in that information, since there could be many, or only some or whatever combination of input elements...

    So what needs to be done for this, is make use of the fnInitComplete callback function which fires when DataTables has been initialised - then loop over the oSettings.aoPreSearchCols[...] array (sSearch is the object you want) and fill in the input elements as you need. So using a little bit of the DataTables internals state storage (oSettings) there, in order to achieve this (it's not part of the publicly documented API :-) ).

    Regards,
    Allan
  • Hi Allan,

    thanks for your help and very quick reply. According to your tip I change a little bit your example api/multi_filter.html with this:

    <script type="text/javascript" charset="utf-8"> var asInitVals = new Array(); $(document).ready(function() { /* * Support functions to provide a little bit of 'user friendlyness' to the textboxes in * the footer */ $("tfoot input").each( function (i) { asInitVals[i] = this.value; } ); $("tfoot input").focus( function () { if ( this.className == "search_init" ) { this.className = ""; this.value = ""; } } ); $("tfoot input").blur( function (i) { if ( this.value == "" ) { this.className = "search_init"; this.value = asInitVals[$("tfoot input").index(this)]; } } ); var oTable = $('#example').dataTable( { "oLanguage": { "sSearch": "Search all columns:" }, "bStateSave": true, "fnInitComplete": function() { var oSettings = $('#example').dataTable().fnSettings(); for ( var i=0 ; i<oSettings.aoPreSearchCols.length ; i++ ){ if(oSettings.aoPreSearchCols[i].sSearch.length>0){ $("tfoot input")[i].value = oSettings.aoPreSearchCols[i].sSearch; $("tfoot input")[i].className = ""; } } } } ); $("tfoot input").keyup( function () { /* Filter on the column (the index) of this element */ oTable.fnFilter( this.value, $("tfoot input").index(this) ); } ); } ); </script>
    ... and get what I need... multi filter with state saving. I hope someone else could benefit from it also. If you find anything wrong, please, let me know.

    Kind regards,
    Marko
  • Posts: 22,739
    Hi Marko ,

    Very nice indeed! Thanks for sharing your code with us! Think I'll add a link from the example to your post shortly :-)

    Regards,
    Allan
  • Very nice and thanks a lot!
    But I have to say, that you should not use the second call of "$('#example').dataTable()" for gathering table settings, because of error with initialization of table.

    So, I think, it should be:
    var oSettings = this.fnSettings();
    And something else for noting. If you'd like to use column filtering with column hiding plugin, it will incorrectly pass your search values prompter text -- I say about initial values of inputs -- with integer range of an array (asInitVals). I'd recommend you to use the string range with names of each input.

    For example:
    jQuery("tfoot input").each( function (i) { asInitVals[this.name] = this.value; } ); jQuery("tfoot input").focus( function () { if ( this.className == "search_init" ) { this.className = ""; this.value = ""; } } ); jQuery("tfoot input").blur( function (i) { if ( this.value == "" ) { this.className = "search_init"; this.value = asInitVals[this.name]; } } );
  • Posts: 22,739
    Good points yunoshev - thanks for posting them.

    With the settings object, it's possible (possibly preferable) not yo use fnSettings at all, since fnInitComplete is passed the settings object as the first parameter: http://datatables.net/usage/callbacks#fnInitComplete .

    Allan
  • edited November 2010 Posts: 5
    Thank you, Allan.
    I wanna ask you, maybe you have any ideas about how can I retrieve correct ID's (order) of inputs?
    I use ColVis & ColReorder plug-ins together and also I use input searching by column in the bottom of the table.
    So, my problem. For example, I have 5 columns. I do 1st column hidden, then search some value in 5th column, go to the needle item (page) and after go back to table view, but!.. I retrieve the searching value for 4th column, not for 5th as it should be. :(
    I hope, you understand me. :)

    Well, what callbacks I have to use to monitoring right value for my searching input?
  • edited December 2010 Posts: 5
    I found the more easier way to work with initial values of inputs -- we can use titles.
    For example:
    ... jQuery("tfoot input").blur( function (i) { if ( this.value == "" ) { this.className = "search_init"; this.value = this.title; } } ); ... So, we don't need to use an array of initial values.
  • Posts: 22,739
    Yup nice one. I've used exactly that kind of thing myself somewhere :-)

    Allan
  • Thank you Marko,
    it is exactly i was looking for!

    And thank you yunoshev for your tips.
  • Posts: 26
    I'm using this method just fine, but I've also implemented ColVis. If I filter, then I hide some rows before the filter, the column filter value is indexed wrong. (If i hide column 1 after filtering on column 3, the index stays 3 and it is filtered on what was column 4).

    Anyone know of a way to either update the cookie when hiding the columns or maybe a better fix to get the correct index for the filters after hiding columns?

    thanks in advance...
  • edited September 2011 Posts: 3
    @versak: this works for me:

    Add id's to your column search fields like this:
    <tfoot> <tr> <th><input type="text" id="i-0" class="search_init"></th> <th><input type="text" id="i-1" class="search_init"></th> <th><input type="text" id="i-2" class="search_init"></th> <th><input type="text" id="i-3" class="search_init"></th> <th><input type="text" id="i-4" class="search_init"></th> <th><input type="text" id="i-5" class="search_init"></th> </tr> </tfoot>
    And use the id while filtering like this:

    $("#example tfoot input").keyup( function () { var id = $(this).attr('id').split("-")[1]; oTable.fnFilter( this.value, id ); });
  • Posts: 1
    Hi all,

    Actually the live example script has an error: if we have hidden columns the <tfoot> count will be wrong and thus the search index on the GET will be wrong. Fortunately the offset is deterministic and its pretty simple to calculate: if we are sorting column X just count the invisible columns with index<X

    Example (based on the provided script: you just need to edit the top rows)
    $("tfoot input",__ctl00_content_datatableTable).keyup( function () { /*Lets find the index after render (does not include the hidden columns). Then we must add N, N being the hidden columns with index<N */ var renderedIndex=$("tfoot input").index(this); var hiddenColumnsCount=0; var aoColumns=__ctl00_content_datatableTable.fnSettings().aoColumns; for(i=0; i<=renderedIndex; i++) { if (!aoColumns[i].bVisible) { hiddenColumnsCount++; } } /* Filter on the column (the index) of this element */ __ctl00_content_datatableTable.fnFilter( this.value,renderedIndex+hiddenColumnsCount ,false,false,false); }); /* * Support functions to provide a little bit of 'user friendlyness' to the textboxes in * the footer */ $("tfoot input").each( function (i) { ___ctl00_content_datatableasInitValsArray[i] = this.value; } );

    Et voila!

    Felt like it could be worth sharing.

    Best,
    Gonçalo
  • Posts: 26
    rubyan said: <span class="Author"><a href="/forums/profile/19188/rubyan">rubyan</a> </span>
    <span class="DateCreated">
    <a href="/forums/discussion/comment/26039#Comment_26039" class="Permalink" name="Item_12" rel="nofollow"></a></span>

    Your method doesn't work with what i already have:
    oTable.fnFilter(this.value, oTable.oApi_fnVisibleToColumnsIndex(oTable.fnSettings(), $("thead input").index(this)); which works great for the initial filter. however, once i hide the columns, it remains correct. once i leave the page and come back to it, the cookies are read and the filter value is in the wrong index. i'm using the fnInitComplete function to put the values back into the inputs.
    "fnInitComplete" : function(){ oTable = $j("#openTable").dataTable(); var oSettings = oTable.fnSettings(); for(var i = 0; i<oSettings.aoPreSearchCols.length; i++){ $("thead input")[i].value = oSettings.aoPreSearchCols[i].sSearch; ....... (When i replace it with your idea, i lose the filter once i tab out of the column.)
  • Posts: 1
    Is it possible to combine this with the Filterin Plug-In? Can you please help me?

    This is my code:
    $('#dataTable').dataTable({ "bStateSave": true, } ).columnFilter({ sPlaceHolder: "head:after", aoColumns: [{}, {type: "text"}, {type: "text"}, {} ]});
    I tried it some times, ob nothing works.
This discussion has been closed.