ColumnFilterWidgets icon indicating copy to clipboard operation
ColumnFilterWidgets copied to clipboard

StateSave Request

Open jasonbryan opened this issue 13 years ago • 16 comments

The state of the filter is held when refreshing the browser but once that data is filtered out it cant be removed after refreshing. For example I'll filter on all Apple entries and then refresh the browser. You can no longer uncheck Apples and show all the data again. So once you filter and end your session you can't unfilter that item. I was wondering if this was an bug or could possibly be added.

jasonbryan avatar Jan 13 '12 20:01 jasonbryan

I would expect a refresh to restore the table to the initial state when loaded, which is what it appears to do if I try on the online examples. Maybe I'm misunderstanding something?

cyberhobo avatar Jan 16 '12 22:01 cyberhobo

Yes, it does. The core datatables library has a bStateSave function that allows the state of the table to be held through the browsers cookies. This is the feature I'm using but when I filter, say a column and then refresh the page. It will not allow me to change that filter again. It appends the filter in the previous state as requested but removes the option to remove that filter. I put up some picture examples https://plus.google.com/u/0/photos/103260879875817802782/albums/5698611822751882241 that may help. Sorry I cut off the Type column when cropping the image.

jasonbryan avatar Jan 17 '12 14:01 jasonbryan

Gotcha - I wasn't getting that bStateSave is a DataTables option. I'd have to learn more about how it works to know whether support for it is feasible. I'm not able to volunteer for the job currently, but other developers may need it also, so let's encourage them to join in the discussion.

cyberhobo avatar Jan 17 '12 15:01 cyberhobo

the datables state cookie has the filter information stored like this:

{"iCreate":1331226938603,"iStart":0,"iEnd":1,"iLength":50,"aaSorting":[[3,"desc",1]],"oSearch":{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},"aoSearchCols":[{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true}, {"bCaseInsensitive":true,"sSearch":"(^|,)(Friedrichshafen)(,|$)","bRegex":true,"bSmart":false},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true}, {"bCaseInsensitive":true,"sSearch":"(^|,)(Agentur\ Holzheimer)(,|$)","bRegex":true,"bSmart":false}, {"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true},{"bCaseInsensitive":true,"sSearch":"","bRegex":false,"bSmart":true}]

so columnfilterwidgets would have to somehow identify the state cookie, just as datatables does, and parse it.

geroyche avatar Mar 08 '12 17:03 geroyche

i'm also interested in this feature! :)

arbyter avatar Apr 25 '12 11:04 arbyter

me, too.

i need this feature!

Can somebody help?

mbdesign avatar Jul 05 '12 09:07 mbdesign

Hola a todos "I get it", resolvi esto cancelando los filtros, dspues de la creacion de la tabla llamen esta funcion: QuitarFiltros(); y dicha funcion es esta:

function Quitarfiltros() {

var index = 0;
$('#example thead th').each(function (index) {
    index++;
    $('#example').dataTable().fnFilter('', index);
});

}

y listo!!!

Rodrigoing avatar Aug 10 '12 13:08 Rodrigoing

Great but can you write in english please, the google translation is not the best.

Can you post the full example please. i don´t know what function Quitarfiltros() is?

mbdesign avatar Aug 10 '12 13:08 mbdesign

    <script type="text/javascript" charset="utf-8">
        $(document).ready( function () {
            $('#example').dataTable( {
                "sDom": 'W<"clear">lfrtip',
                "bStateSave": true// Recuerda el estado de la tabla via cookies 

            } );
            Quitarfiltros();
        } );

        function Quitarfiltros()
        {
            var index = 0;
            $('#example thead th').each(function (index) {
                index++;
                $('#example').dataTable().fnFilter('', index);
            });


        }
    </script>

that solve the problem, and I have to say that its not fair, I have to translate all conversation...

Rodrigoing avatar Aug 10 '12 13:08 Rodrigoing

problem solved with adding in ColumnFilterWidgets.js: $.fn.dataTableExt.oApi.fnResetAllFilters = function (oSettings, bDraw/default true/) { for(iCol = 0; iCol < oSettings.aoPreSearchCols.length; iCol++) { oSettings.aoPreSearchCols[ iCol ].sSearch = ''; } oSettings.oPreviousSearch.sSearch = ''; if(typeof bDraw === 'undefined') bDraw = true; if(bDraw) this.fnDraw(); }

then simply calling: oTable.fnResetAllFilters();

solution found at: http://www.datatables.net/forums/discussion/997/fnfilter-how-to-reset-all-filters-without-multiple-requests./p1

navihtot avatar Aug 21 '12 10:08 navihtot

I wanted to keep the filter alive but on the "full" result, so I added the following function to the ColumnFilterWidget:

        $.fn.dataTableExt.oApi.fnResetAndSetFilters = function (oSettings) {
            var aOldPreSearchCols = new Array(oSettings.aoPreSearchCols.length);
            for(iCol = 0; iCol < oSettings.aoPreSearchCols.length; iCol++) {
                aOldPreSearchCols[iCol] = oSettings.aoPreSearchCols[ iCol ].sSearch;
                oSettings.aoPreSearchCols[ iCol ].sSearch = '';
            }
            this.fnDraw();
            for(iCol = 0; iCol < aOldPreSearchCols.length; iCol++) {
                if(aOldPreSearchCols[iCol]){
                    var aSearchTerm = aOldPreSearchCols[iCol].split(/[()]/);
                    aSearchTerm = aSearchTerm[1].split("|");
                    for(n=0;n<aSearchTerm.length; n++){
                        $("#filter_" + iCol).val(aSearchTerm[n].replace("\ ", " "))
                        $("#filter_" + iCol).trigger('change');
                    }
                }
            }
        }

Furthermore I added an id to the generated select boxes:

change

widget.$Select = $( '<select></select>' ).change( function() {

to

widget.$Select = $( '<select id="filter_' + widget.iColumn + '" ></select>' ).change( function() {

spacehill avatar Jan 18 '13 17:01 spacehill

@spacehill My man, had to do a bit of tweaking but I like the process of your fix.

For those who need to work out if it's what they want, his code removes the filters (saves to a variable first), draws the table, then manually selects the filters previously removed.

Useful to put in fnInitComplete for those using Ajax/Server-side.

malkstar avatar Feb 03 '14 11:02 malkstar

@cyberhobo FYI, the only problem OOB (that I experienced with ajax loading) was that the option would be selected (and functions fine) but there is no removable anchor generated underneath (through messing about, I think this is only because it isn't a option at the time it is selected because of the data delay).

The snippet @spacehill posted removes the the old term (then draws so the table renders as normal) then applies the old term again as if it were to be newly selected which confirms that logic.

I'll take a deeper at the code in a bit and see if I can shuffle something to make it click straight away.

malkstar avatar Feb 03 '14 15:02 malkstar

Hello, @spacehill solution has a bug when working with spaces.

Instead of $("#filter_" + iCol).val(aSearchTerm[n].replace("\ ", " "))

The correct solution is $("#filter_" + iCol).val(aSearchTerm[n].replace("\ ", " "))

(note the double backslash)

miquelcamprodon avatar May 19 '14 08:05 miquelcamprodon

@spacehill , Where to keep your function and how to call it? Can you please guide? Select change event is not triggering.

nikunj-digicorp avatar Jul 05 '17 11:07 nikunj-digicorp

Hello, i created a workaround as follows.

The function works like this: i loop through all the localStorage keys to find one which starts with DataTables_. If found, i get this one, because that's where the state of the filters are saved. I loop through the columns to see if a value is found in property search. If so, i enable the corresponding search widget dropdown, and i select all the values in it and trigger a change. This causes the selected values to be selected and visible underneath the dropdown. the user then easily can remove the filters by clicking them.

I hope i can help someone with this, so have fun with it :-)

var checkSaveStateFilters = function()
{
    var i = 0,
        oJson = [],
        sKey;
    //loop through all localStorage key's to search for DataTables_
    for (; sKey = window.localStorage.key(i); i++) {
        if(sKey.indexOf("DataTables_") != -1)
        {
            var vObjState = JSON.parse(localStorage.getItem(sKey)).columns;
            for(var j=0;j<vObjState.length;j++)
            {
                //if there is a value in the search filter
                if(vObjState[j].search.search !="")
                {
                    $(".column-filter-widget .widget-"+j).removeAttr("disabled"); //enable filter dropdown
                    for(var k=$(".column-filter-widget .widget-"+j+" option").length;k>1;k--)
                    {
                        $('.column-filter-widget .widget-'+j+' option:eq('+parseInt(k-1)+')').attr('selected', 'selected'); //select value
                        $('.column-filter-widget .widget-'+j).trigger('change'); //trigger change
                    }
                }
            }
        }
    }
}

svanmoerkerke avatar Aug 27 '19 13:08 svanmoerkerke