jqgrid retain filter on reload

10,378

Solution 1

I am not sure, but I suppose that the origin of your first problem could be mixing postData.filters and postData and usage filter property instead of filters``. You use

postfilt = $("#status").jqGrid('getGridParam', 'postData').filter;

to get filter property instead of filters. You get undefined value. So the setting postData to postfilt means nothing.

The next problem is that the server response contains non-filtered data. To force filtering the data locally you have to reload the grid once after the loading from the server have finished. You can do this inside of loadComplete. Exactly here you can set postData.filter if required, set search: true and trigger reloadGrid event. It's important only to do this once to have no recursion and you must don't set datatype back to "json" in the case. The datatype will be changed to "local" and the end of loading from the server in case of usage loadonce: true option. If you want apply filtering locally you have to reload grid once with options datatype: "local", search: true and postData having filters specifying the filter which need by applied. See the code from the answer or another one which do another things, but the code which you need will be very close.

Solution 2

Thanks very much!!!!

I only added a bit to your solution to retain the page number as well:

                loadComplete: function () {
                var $this = $(this);
                var postfilt = $this.jqGrid('getGridParam', 'postData').filters;
                var postsord = $this.jqGrid('getGridParam', 'postData').sord;
                var postsort = $this.jqGrid('getGridParam', 'postData').sidx;
                var postpage = $this.jqGrid('getGridParam', 'postData').page;

                if ($this.jqGrid("getGridParam", "datatype") === "json") {
                    setTimeout(function () {
                        $this.jqGrid("setGridParam", {
                            datatype: "local",
                            postData: { filters: postfilt, sord: postsord, sidx: postsort },
                            search: true
                        });
                        $this.trigger("reloadGrid", [{ page: postpage}]);
                    }, 25);
                }
            }
Share:
10,378
Mike
Author by

Mike

Updated on June 04, 2022

Comments

  • Mike
    Mike almost 2 years

    This question has been as a lot so please forgive me asking again.

    I have a grid loaded from a url.

    I use loadonce: true

    I use filtertoolbar:

    $("#status").jqGrid('filterToolbar', { stringResult:true, searchOnEnter:false, autosearch: true, defaultSearch: "cn" });
    

    I have a dropdown search list from which I can select what I'm looking for. Works great.

    I have a navbutton I click to initiate a reload every 30 seconds. Works great.

    $("#status").jqGrid('navButtonAdd','#statuspager', { caption: '', buttonicon: 'ui-icon-play', onClickButton: function ()
    {
    stint = setInterval (function() {
          postfilt = $("#status").jqGrid('getGridParam', 'postData').filter;
    
          $("#status").jqGrid('setGridParam',{
                 url: './ar_status.cgi?systemtype=' + systype,
                 datatype: "json",
                 postData: postfilt,
                 search: true,
                 loadtext: "Refreshing grid...",
                 loadonce: true,
                 loadui: "block"
          });
          $("#status").jqGrid().trigger("reloadGrid");
    }, 30000);
    },
    title: 'Start Auto Refresh (every 30 sec.)'
    });
    

    Using google chrome I can see the filters that were specified being posted to the server:

    systemtype:production
    _search:true
    nd:1358887757603
    rows:1000
    page:1
    sidx:system
    sord:asc
    totalrows:700
    filters:{"groupOp":"AND","rules":[{"field":"system","op":"eq","data":"ATTDA02"}]}
    

    I can change the filter between reloads and see the new, even multiple filters:

    systemtype:production
    _search:true
    nd:1358887847592
    rows:1000
    page:1
    sidx:system
    sord:asc
    totalrows:700
    filters:{"groupOp":"AND","rules":[{"field":"system","op":"eq","data":"ATTDA02"},{"field":"dow","op":"cn","data":"MO"}]}
    

    I am using multipleSearch: true on the initial load. I'm pretty sure that's retained on reload

    On the grid, the filtertoolbar retains my filter criteria, both text and selects, but when the grid reloads, the filters are ignored and the entire dataset is diplayed in the grid.

    I've tried many examples posted here on SO. I've tried adding [{current:true}] to the reloadGrid call - no difference. I can't seem to retain and apply the filters on a reload.

    I would like the reload to always return the full dataset from the server (which happens fine), and allow the current filter settings to control what is shown after the reload. I do not want to use the postdata to build a new SQL select statement - server side filtering, because at any time the user may want to click the pause button, select a new filter and view something else from the entire dataset without another reload.

    $("#status").jqGrid('navButtonAdd','#statuspager', { caption: '', buttonicon: 'ui-icon-pause', onClickButton: function ()
    {
       clearInterval(stint);
    },
    title: 'End Auto Refresh'
    });
    

    How can this be done without using cookies, as I saw in one post?

    I could try using jqGridExport'ing the postfilt var, and then jqGridImport'ing it but was hoping for a more direct approach. I'm not even sure this would help since I already have everything I need right here in the grid via postData.

    As a side note, in my setGridParam above, the loadtext I specify is never displayed. Instead, the default "Loading..." is displayed. All of the other parameters are working.

    Many thanks in advance, Mike

    Solution. The complete loadComplete to retain filters, sort index and sort order after a [json] reload from the server:

                        loadComplete: function() {
                                var $this = $(this);
                                postfilt = $this.jqGrid('getGridParam','postData').filters;
                                postsord = $this.jqGrid('getGridParam','postData').sord;
                                postsort = $this.jqGrid('getGridParam','postData').sidx;
    
                                if ($this.jqGrid("getGridParam", "datatype") === "json") {
                                        setTimeout(function () {
                                                $this.jqGrid("setGridParam", {
                                                        datatype: "local",
                                                        postData: {filters: postfilt, sord: postsord, sidx: postsort},
                                                        search: true
                                                });
    
                                                $this.trigger("reloadGrid");
                                        }, 50);
                                }
                        }
    
  • Mike
    Mike over 11 years
    Thanks for the guidance, Oleg. I still haven’t managed to make this work. I have to refresh the grid from the server each time and that means the datatype will be json each time. I’ve tried immediately setting the datatype to “local” but’ it’s not sticking, or the grid refreshes empty. I can follow the progress with a bunch of alert() calls and I can see it’s getting close; that datatype is being set to local, but even then the filters are not applied. I'll keep hacking at it.
  • Oleg
    Oleg over 11 years
    @Mike: You are welcome! I can only repeat that you should follow the code from the answer. You should load full data from the server having datatype: "json" and loadonce: true. Then you should trigger reloadGrid immediately from loadCompleted like in the answer. It make local sorting and filtering applied on the data loaded. Later you should change datatype to "json" when you need refresh the data by reloading it from the server.
  • Mike
    Mike over 11 years
    You are very patient, Oleg. I went over this again and [on purpose] I had left out the setTimeout function on loadComplete. It didn't seem necessary, but adding it back makes all the difference. I now have exactly what I'm after. I'm not big on copy/paste/hope it works. Can you explain why setTimeout is needed?
  • Oleg
    Oleg over 11 years
    @Mike: The difference is very large. The callback function loadComplete will be called by jqGrid during processing of the data returned from the server (see the line). So the processing of the response returned from the server is not finished. Usage of setTimeout allows to finish current processing of responses and then the next reloadGrid will be processed.
  • Mike
    Mike over 11 years
    I thought it might be something other than a delay mechanism because I can set the timeout to zero and still get the expected results. Anyway, thanks again for the help, and for all of your contributions to the jqgrid community. Very generous.
  • Oleg
    Oleg over 11 years
    @Mike: It is delay mechanism. You can set breakpoint inside of setTimeout having 0 and you would see that the code inside of setTimeout will be executed later. If you examine source code of jqGrid you will find some places where setTimeout with 0 do used.
  • Oleg
    Oleg over 11 years
    @Mike: I recommend you remove setTimeout and repeat the same with setting breakpoint somewhere inside of populete function (for example here) and you will see that code without setTimeout will process populete at the second time before the first call (inside of loadComplete) will be completed.