jqgrid retain filter on reload
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);
}
}
Mike
Updated on June 04, 2022Comments
-
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 over 11 yearsThanks 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 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"
andloadonce: true
. Then you should triggerreloadGrid
immediately fromloadCompleted
like in the answer. It make local sorting and filtering applied on the data loaded. Later you should changedatatype
to"json"
when you need refresh the data by reloading it from the server. -
Mike over 11 yearsYou 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 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 ofsetTimeout
allows to finish current processing of responses and then the nextreloadGrid
will be processed. -
Mike over 11 yearsI 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 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 ofsetTimeout
will be executed later. If you examine source code of jqGrid you will find some places wheresetTimeout
with 0 do used. -
Oleg over 11 years@Mike: I recommend you remove
setTimeout
and repeat the same with setting breakpoint somewhere inside ofpopulete
function (for example here) and you will see that code withoutsetTimeout
will processpopulete
at the second time before the first call (inside ofloadComplete
) will be completed.