cyberhobo / ColumnFilterWidgets

This is an add-on for the DataTables plugin for jQuery that creates filtering widgets based on the data in table columns.
69 stars 34 forks source link

StateSave Request #6

Open jasonbryan opened 12 years ago

jasonbryan commented 12 years ago

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.

cyberhobo commented 12 years ago

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?

jasonbryan commented 12 years ago

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.

cyberhobo commented 12 years ago

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.

geroyche commented 12 years ago

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.

arbyter commented 12 years ago

i'm also interested in this feature! :)

mbdesign commented 12 years ago

me, too.

i need this feature!

Can somebody help?

Rodrigoing commented 12 years ago

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!!!

mbdesign commented 12 years ago

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?

Rodrigoing commented 12 years ago
    <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...

navihtot commented 12 years ago

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

spacehill commented 11 years ago

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() {
malkstar commented 10 years ago

@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 commented 10 years ago

@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.

miquelcamprodon commented 10 years ago

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)

nikunj-digicorp commented 7 years ago

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

svanmoerkerke commented 5 years ago

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
                    }
                }
            }
        }
    }
}