0

(I'm sure this is a UFU but I can't seem to find the cause)

Using jqGrid to display data. Double-click on a row opens a new page with drill-down info. I want to restore the filter terms when the 'back' button is clicked.

Filter terms are stored in the localStorage from grid.getGridParam( "postData" ).filters. Am attempting to restore this at load time but not getting values back.

The confounding factor is probably that I'm creating the values for the filtertoolbar at load time by finding unique values for each column (see here). This says (to me) that I can't set filter values until after the drop-lists are filled. To this end I'm trying to use the 'loadComplete' function (where the list filling function is called). Once the controls are populated I'm calling grid.jqGrid( 'setGridParam', { 'postData' : localStorage[ "filter" ]});. Unfortunately this doesn't seem to have any effect.

From everything I've read this is doable. What did I miss?

NOTE: I also tried this but figured it wasn't working owing to the values being set in 'loadComplete' above.


EDIT: filter values are being saved here:

ondblClickRow: function( rowid, iRow, iCol, e )
{
    localStorage[ 'filter' ] = grid.getGridParam("postData").filters;
    window.location = "info.php?idx=" +  grid[0].p.data[ rowid - 1 ].IssueId;
}

There are values saved from this. I test when the page is reloaded (and also eyeball it using console.log())

loadonce is definitely true.

Here are the params I use:

url: "loadIssues.php",
datatype: "json",
colNames: [  (list of values) ],
colModel: [ (array of values)  ],
pager: "#pager2",
viewrecords: true,
sortorder: "desc",
gridview: true,
autoencode: true,
ignoreCase : true,
loadonce : true,
width: 800,
height: "auto",
shrinkToFit: true,
search: true,
jsonReader: {
  repeatitems: false,
  root: "rows"
 },

EDIT:

This is the fix: using the $( this ) was my mistake. Replacing it with a reference to the grid control fixes the problem.

Here is the code I'm using in loadComplete:

loadComplete: function( data )
{
    setSearchSelect( <column name> );

    if( localStorage.hasOwnProperty( 'filter' ))
    {
       postData = $( "#list2" ).jqGrid( "getGridParam", "postData" );
       paramNames = $( "#list2" ).jqGrid("getGridParam", "prmNames");

       postData.filters = JSON.parse( localStorage[ 'filter' ]);
       postData[paramNames.search] = true;

       localStorage.removeItem( 'filter' );

       setTimeout( function()
       {
           $( "#list2" ).trigger( "reloadGrid" );
       }, 100 );
   }
}
Community
  • 1
  • 1
ethrbunny
  • 10,379
  • 9
  • 69
  • 131
  • Could you include code fragments which shows how and where you save the data in `localStorage` and how and where you restore it? You wrote "Am attempting to restore this at load time but not getting values back." Do you mean that `localStorage["filter"]` is empty or just that the filters are not applied? Which `datatype` you use? Do you use `loadonce: true` or not? Setting of filters inside of `loadComplete` is definitively too late. – Oleg Jul 09 '14 at 15:53
  • Poor grammar on my part: should have read "Am attempting to restore this at load time but filter values are not being restored". Values from localStorage **are** being returned properly. – ethrbunny Jul 09 '14 at 16:09

1 Answers1

2

I answered in the answer and in this one how one could save the preferences in localStorage and restore it during loading the grid.

First of all I would mention that the usage of localStorage["filter"] in your code can make some conflicts. Each domain and subdomain has its own separate local storage area, but you can use different grids on different pages of your web server. Some pages could have more as one grid. So it would be better to use another rules as "filter" for the name of the property of localStorage. I used in the answer the property names which will be build from window.location.pathname and the grid id.

Now I go back to your main question. I see two main problems which you have to solve:

  • setting the filter before the first request will be send to the server
  • filling the fields of the filter toolbar based on the filter

A possible solution of the second part I described in the answer (see the code of refreshSerchingToolbar function called inside of loadComplete). I used the same approach in the answer where I used localStorage for persisting users preferences of jqGrid.

Setting of filter in jqGrid can be implemented in different ways. It's important to specify which behavior you want to have in case of usage datatype: "json", loadonce: true. If you implemented server side filtering then you can set the filter inside of beforeRequest callback:

var storageName = "filters"; // or some better value

...

datatype: "json",
loadonce: true,
beforeRequest: function () {
    var $self = $(this),
        postData = $self.jqGrid("getGridParam", "postData"),
        filters = postData.filters,
        paramNames = $self.jqGrid("getGridParam", "prmNames"),
        dataType = $self.jqGrid("getGridParam", "datatype"),
        lastFilter = localStorage[storageName];

    // one can add in the below condition testing of dataType === "json" if one need to set
    // the filter on loading the data from the server only
    if ((filters === null || filters === "" || filters === undefined) && lastFilter !== undefined) {
        // current filter is not set, but it exists in localStorage
        // we need to applay it
        postData.filters = lastFilter;

        // set _search parameter to true
        postData[paramNames.search] = true;
    }

    return true;
},
loadComplete: function () {
    var filters = $(this).jqGrid("getGridParam", "postData").filters;
    if (filters !== null && filters !== "" && filters !== undefined) {
        localStorage[storageName] = filters;
    }
}

Alternatively you can just set the filter before the grid will be created like I do it in already referenced answers (this one and this one).

If you don't implemented filtering on the server side then the filter will be not applied automatically. In the case you can follow the answer and reloads the grid once after loading the data from the server. One will sees flickers, but the sorting and filter will be do applied.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • This is definitely loadonce - no server side filtering. Once all the data is loaded I comb through each filtered column to find unique values and use this to fill the list box. Any filter value would have to be set after this is done or it would be over written. – ethrbunny Jul 10 '14 at 15:59
  • @ethrbunny: There are difference whether you implemented filtering **on the server side** (base on `filters` parameter which will be sent to the server) or not. If the server returns **full unfiltered data** and you want to filter the data on the client side then everything is more easy, you should remove `beforeRequest` and just follow [the answer](http://stackoverflow.com/a/16383288/315935). – Oleg Jul 10 '14 at 16:18
  • @ethrbunny: Inside of `loadComplete` you need test whether `datatype` is `"json"`. If it's true then we are in the first loading. Now one can get `filters` from `localStorage`, set the values in `postData.filters`, set `search` option of jqGrid to true and trigger `reloadGrid` to apply the filter and the sorting. – Oleg Jul 10 '14 at 16:20
  • I posted my updates in the original question. Thanks for your help. – ethrbunny Jul 10 '14 at 16:36
  • 1
    @ethrbunny: You are welcome! I would only recommend you don't use `$( "#list2" )` in the code of callbacks (like `loadComplete`). Instead of that you could save `$(this)` in a variable (to have no problems inside of `setTimeout`): `var $self = $(this);` at the beginning of `loadComplete`. Late you can use `$self` instead of `$( "#list2" )`. It makes the code of `loadComplete` more smart, so you could cut&paste it in another your project without modifications. Moreover `$(this)` is a little quickly as `$("#list2")`. – Oleg Jul 10 '14 at 16:51
  • @RaviChauhan: I'm not sure what you mean. I referenced another answers in the answer, which contain more detailed code. In general, one can use [localStorage.removeItem](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), for example, `localStorage.removeItem("filters");` – Oleg Sep 26 '19 at 18:06