问题
I have a jqgrid displaying a large amount data. The data is retrieved from the server periodically via a jquery ajax call (outside of the jqgrid logic). The retrieved data is compared to the data previously retried ( and stored as a var in js. it is served as the data for the jqgrid). if they are different the local data is refreshed, then trigger the jqgrid to reload. the jqgrid datatype is jsonstring.
This solution is working quite well, except when the user have a filter value in the filter toolbar. because i set a timer for 0.1 sec to trigger filter in the loadcomplete event, the whole grid refresh when there is a filter string looks like this:
- 20 records were displayed in the jqgrid originally (because the user is filtering on a certain value in a column)
- jqgrid is refreshed, because the data polled from the server by the separated ajax call is different than the one stored in the browser
- jqgrid will show all the new data for a very short period of time
- jqgrid filter is triggered within loadcomplete. and the screen is showing 20 records again.
it is technically still working. but is there a way to re-apply the filter locally on the jsonstring before the grid is visualised? put in a different way, can the jqgrid to visualise only once, which will both load the new jsonsting and apply the filter that was placed in the filter box before at the same time?
thanks casbby
update:
I have tried one of Oleg's solution to apply filter while reloading the grid. this is demo. it worked perfectly as long as the the datatype is local. my page actually use the datatype jsonstring to reload the grid. This function from the code does seem to apply to jsonstring. i was hoping to call such a function after a external jquery ajax successfully retrieved the data form the server.
function filter() {
var searchFiler = $("#filter").val(), f;
if (searchFiler.length === 0) {
grid[0].p.search = false;
$.extend(grid[0].p.postData,{filters:""});
}
f = {groupOp:"OR",rules:[]};
f.rules.push({field:"name",op:"cn",data:searchFiler});
f.rules.push({field:"note",op:"cn",data:searchFiler});
grid[0].p.search = true;
$.extend(grid[0].p.postData,{filters:JSON.stringify(f)});
grid.trigger("reloadGrid",[{page:1,current:true}]);
}
can someone please help me out? many thanks.
回答1:
There are small differences in the usage of datatype: "jsonstring"
in comparing with the usage of datatype: "local"
. You can compare the corresponding parts of the code here. One from the differences in the code of datatype: "local"
is the usage of addLocalData
and populateVisible
functions. The last function (populateVisible
) will be used only in case of virtual scrolling (scroll: 1
or scroll: true
). In your case important difference between datatype: "jsonstring"
and datatype: "local"
is the call of addLocalData
in case of datatype: "local"
.
The function addLocalData
apply grouping and filtering of local data (see here). Moreover it cut the list of displayed rows to the current page (see here).
So if the server returns unfiltered data and you need display filtered data then you should use datatype: "local"
instead of datatype: "jsonstring"
. Instead of datastr
you should use data
. You can need to use localReader
instead of jsonReader
(see the documentation) or just convert manually the data returned from the server to the format which could be read by default localReader
.
UPDATE: In another answer I described and included the demo which shows how localReader
can be used.
What you can alternatively do is to convert your input data returned from the server to the standard format (or return the data from the server in the format). The data
parameter should be array of named objects with properties like the column names in colMode
. So what you can do is just a simple loop through rows
array and creating another array in the format which jqGrid required. The corresponding code could be about the following:
// let us you have myImput with myImput.rows
// and you have cm which you use as the value of colModel parameter
var mydata = [], input = myImput.rows, l = input.length,
cmLength = cm.length, i, j, inputItem, item;
for (i = 0; i < l; i++) {
inputItem = input[i];
item = {id: inputItem.id};
inputItem = inputItem.cell;
for (j = 0; j < cmLength; j++) {
item[cm[j].name] = inputItem[j];
}
mydata.push(item);
}
After such conversion you can use mydata
array as the value of data
parameter.
来源:https://stackoverflow.com/questions/12983215/alternative-to-jqgrid-triggertoolbar-on-a-local-dataset