Remember (persist) the filter, sort order and current page of jqGrid
Asked Answered
F

5

28

My application users asked if it were possible for pages that contain a jqGrid to remember the filter, sort order and current page of the grid (because when they click a grid item to carry out a task and then go back to it they'd like it to be "as they left it")

Cookies seem to be the way forward, but how to get the page to load these and set them in the grid before it makes its first data request is a little beyond me at this stage.

Does anyone have any experience with this kind of thing with jqGrid? Thanks!

Finfoot answered 10/6, 2010 at 14:13 Comment(0)
F
28

PROBLEM SOLVED

I eventually ended up using cookies in javascript to store the sort column, sort order, page number, grid rows and filter details of the grid (using JSON/Javascript cookies - the prefs object)

Save Preferences - Called from $(window).unload(function(){ ... });

var filters = {
    fromDate: $('#fromDateFilter').val(),
    toDate: $('#toDateFilter').val(),
    customer: $('#customerFilter').val()
};

prefs.data = {
    filter: filters,
    scol: $('#list').jqGrid('getGridParam', 'sortname'),
    sord: $('#list').jqGrid('getGridParam', 'sortorder'),
    page: $('#list').jqGrid('getGridParam', 'page'),
    rows: $('#list').jqGrid('getGridParam', 'rowNum')
};

prefs.save();

Load Preferences - Called from $(document).ready(function(){ ... });

var gridprefs = prefs.load();

$('#fromDateFilter').val(gridprefs.filter.fromDate);
$('#toDateFilter').val(gridprefs.filter.toDate);
$('#customerFilter').val(gridprefs.filter.customer);

$('#list').jqGrid('setGridParam', {
    sortname: gridprefs.scol,
    sortorder: gridprefs.sord,
    page: gridprefs.page,
    rowNum: gridprefs.rows
});

// filterGrid method loads the jqGrid postdata with search criteria and re-requests its data
filterGrid();

jqGrid Reference: http://www.secondpersonplural.ca/jqgriddocs/_2eb0fi5wo.htm

BY POPULAR DEMAND - THE FILTERGRID CODE

    function filterGrid() {
        var fields = "";
        var dateFrom = $('#dateFrom').val();
        var dateTo = $('#dateTo').val();

        if (dateFrom != "") fields += (fields.length == 0 ? "" : ",") + createField("shipmentDate", "ge", dateFrom);
        if (dateTo != "") fields += (fields.length == 0 ? "" : ",") + createField("shipmentDate", "le", dateTo);

        var filters = '"{\"groupOp\":\"AND\",\"rules\":[' + fields + ']}"';

        if (fields.length == 0) {
            $("#list").jqGrid('setGridParam', { search: false, postData: { "filters": ""} }).trigger("reloadGrid");
        } else {
            $("#list").jqGrid('setGridParam', { search: true, postData: { "filters": filters} }).trigger("reloadGrid");
        }

    }

    function createField(name, op, data) {
        var field = '{\"field\":\"' + name + '\",\"op\":\"' + op + '\",\"data\":\"' + data + '\"}';
        return field;
    }
Finfoot answered 15/6, 2010 at 12:14 Comment(3)
I recommend you to think about update of different data on the server side. Will be the filter work? Could you delete the saved filters after updates on the server? The easieast example is the page number. How will look like jqGrid on the client side if at the next time the maximal count of pages will be less then the current page saved in the cookie? Nevertheless I find your implementation good and you go definitively in the correct direction.Relique
Hey, Jimbo. I'll have that filterGrid from you if you've got it. +1 on question and answer - exactly what I was looking for.Quark
@David - Updated my answer above to include the filterGrid code - all the best :)Finfoot
P
3

I was working on the same thing but also needed to get and save the column ordering. It's not simple as jqGrid.remapColumns is relative to what ever the current stat of the grid is...

Just in case anyone finds this helpful (and I'd love to know if there is already something to do this that I missed):

(function($){

$.jgrid.extend({

    getColumnOrder : function ()
    {
        var $grid = $(this);

        var colModel = $grid[0].p.colModel;

        var names = [];
        $.each(colModel, function(i,n){
            var name = this.name;
            if (name != "" && name != 'subgrid')
                names[names.length] = name;
        });

        return names;
        //return JSON.stringify(names);
        //$('#dbgout').val(j);

    },


    setColumnOrder : function (new_order)
    {
        var $grid = $(this);

        //var new_order = JSON.parse($('#dbgout').val());
        //new_order = ['a', 'c', 'd', 'b', 'e'];
        //              0    1    2    3    4

        var new_order_index = {};

        $.each(new_order, function(i,n){
            new_order_index[n] = i;
        });

        //new_order = ['a', 'c', 'd', 'b', 'e'];
        //              0    1    2    3    4
        // new_order_index a=>0 c=>1 d=>2 b=>3 e=>4

        var colModel = $grid[0].p.colModel;

        cur = [];
        $.each(colModel, function(i,n){
            var name = this.name;
            if (name != "" && name != 'subgrid')
                cur[cur.length] = name;
        });
        //cur = ['a', 'b', 'c', 'd', 'e'];
        //        0    1    2    3    4

        cur_index = {};
        $.each(cur, function(i,n){
            cur_index[n] = i;
        });


        // remapColumns: The indexes of the permutation array are the current order, the values are the new order.

        // new_order       0=>a 1=>c 2=>d 3=>b 4=>e
        // new_order_index a=>0 c=>1 d=>2 b=>3 e=>4

        // cur             0=>a 1=>b 2=>c 3=>d 4=>e
        // cur_index       a=>0 b=>1 c=>2 d=>3 e=>4

        // permutati       0    2    3    1    4
        //                 a    c    d    b    e
        var perm = [];
        $.each(cur, function(i, name){   // 2=>b

            new_item = new_order[i];     // c goes here
            new_item_index = cur_index[new_item];

            perm[i] = new_item_index;
        });

        if (colModel[0].name == 'subgrid' || colModel[0].name == '')
        {
            perm.splice(0, 0, 0);
            $.each(perm, function(i,n){
                ++perm[i]
            });
            perm[0] = 0;
        }

        $grid.jqGrid("remapColumns", perm, true, false);

    },



});
})(jQuery);
Pug answered 6/1, 2011 at 3:44 Comment(0)
R
2

I part of work what you need you can implement with respect of jqGridExport and jqGridImport (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:import_methods), but it seems to me you want more as exist out of the box in jqGrid. Some additional features you will have to implement yourself.

Relique answered 10/6, 2010 at 15:15 Comment(2)
Thanks Oleg, I hadnt seen this functionality before. It doesnt quite solve my current problem (I have documented my solution below) but will be useful in the future im sure!Finfoot
I understand that jqGridExport and jqGridImport gives you too less features, but I don't know nothing more what exist out-of-the-box in jqGrid which supports your requirements. You have to impement it yourself.Relique
C
1

If the user logs in, you might be able to make AJAX requests back to the server when these parameters change. You could then save the settings, either to database (to make them permanent), to session (to persist them temporarily), or both (for performance reasons).

In any case, with the parameters stored server-side, you could just send them to the page when it is requested.

Cello answered 10/6, 2010 at 14:21 Comment(2)
Considered doing this, but the problem is that: When a page loads for the first time, it gets a blank filter and sort order and page. How would your server-side data provider know whether that was a "reset the filter and change sort order etc." or a "load my defaults" request? For this reason I thought client side cookies would be better.Finfoot
Does it matter? If these are the defaults then you should be able to save them on the server and apply them as needed without changing default behavior - or am I missing something?Cello
I
0

Hi You can make this easier (no other dependency needed) in Pure Js not a jQuery plugin

var prefs = {

    data: {},

    load: function () {
        var the_cookie = document.cookie.split(';');
        if (the_cookie[0]) {
            this.data = JSON.parse(unescape(the_cookie[0]));
        }
        return this.data;
    },

    save: function (expires, path) {
        var d = expires || new Date(2020, 02, 02);
        var p = path || '/';
        document.cookie = escape( JSON.stringify(this.data) )
                          + ';path=' + p
                          + ';expires=' + d.toUTCString();
    }

}

How to use ?

to_save = { "size": 40, "color": "green", "products":"jeans"};//and any other data/filters you wanna store here

prefs.data = to_save;
prefs.save();//now our json object is saved on the client document cookie


// delete
var date_in_the_past = new Date(2000,02,02);
prefs.save(date_in_the_past);


// read
var what = prefs.load();
// load populates prefs.data and also returns
alert(what.color);
// or ...
alert(prefs.data.color);

PS : All modern browsers support native JSON encoding/decoding (Internet Explorer 8+, Firefox 3.1+, Safari 4+, and Chrome 3+). Basically, JSON.parse(str) read more. PSS : the Object i used there is just optimization and removing the dependency of .toJSONstring ... source

Take a look at these jQuery plugins

USE this don't use the custom funcation above https://github.com/carhartl/jquery-cookie

https://github.com/ScottHamper/Cookies

Immunology answered 9/1, 2015 at 3:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.