Reputation: 175
I would like to be able to reload a jqgrid in the event that the page number is higher than the total pages inside the loadComplete event. I am saving the grid settings to the browser local storage as in this answer - Persisting jqGrid column preferences
I have added a call to trigger the reload of the grid and set the page back to 1, but it doesn't seem to work inside the loadComplete method. I have debugged the code and the method is called.
Javascript: (Important part is loadComplete function in the jqGrid definition)
$(document).ready(function() {
var $grid = $('#grid'),
cm = [
{ name: 'Id', index: 'Id', width: 120, align: 'left', editable: false,sortable: true,hidden: true,hidedlg: true,Key: true},
{ name: 'Status', index: 'Status', width: 80, align: 'left', editable: false,sortable: true,hidden: true,hidedlg: false,Key: false},
{ name: 'Reference', index: 'Reference', width: 80, align: 'left', editable: false,sortable: true,hidden: false,hidedlg: false,Key: false},
{ name: 'CustomerReference', index: 'CustomerReference', width: 140, align: 'left', editable: false,sortable: true,hidden: false,hidedlg: false,Key: false},
{ name: 'Logged', index: 'Logged', width: 100, align: 'left', editable: false,sortable: true,hidden: false,hidedlg: false,Key: false}
],
saveObjectInLocalStorage = function (storageItemName, object) {
if (typeof window.localStorage !== 'undefined') {
window.localStorage.setItem(storageItemName, JSON.stringify(object));
}
},
removeObjectFromLocalStorage = function (storageItemName) {
if (typeof window.localStorage !== 'undefined') {
window.localStorage.removeItem(storageItemName);
}
},
getObjectFromLocalStorage = function (storageItemName) {
if (typeof window.localStorage !== 'undefined') {
return $.parseJSON(window.localStorage.getItem(storageItemName));
}
},
myColumnStateName = function (grid) {
return window.location.pathname + '#' + grid[0].id;
},
saveColumnState = function (perm) {
var colModel = this.jqGrid('getGridParam', 'colModel'), i, l = colModel.length, colItem, cmName,
postData = this.jqGrid('getGridParam', 'postData'),
columnsState = {
search: this.jqGrid('getGridParam', 'search'),
page: this.jqGrid('getGridParam', 'page'),
sortname: this.jqGrid('getGridParam', 'sortname'),
sortorder: this.jqGrid('getGridParam', 'sortorder'),
rowNum: this.jqGrid('getGridParam', 'rowNum'),
permutation: perm,
colStates: {}
},
colStates = columnsState.colStates;
if (typeof (postData.filters) !== 'undefined') {
columnsState.filters = postData.filters;
}
for (i = 0; i < l; i++) {
colItem = colModel[i];
cmName = colItem.name;
if (cmName !== 'rn' && cmName !== 'cb' && cmName !== 'subgrid') {
colStates[cmName] = {
width: colItem.width,
hidden: colItem.hidden
};
}
}
saveObjectInLocalStorage(myColumnStateName($grid), columnsState);
},
myColumnsState,
isColState,
restoreColumnState = function (colModel) {
var colItem, i, l = colModel.length, colStates, cmName,
columnsState = getObjectFromLocalStorage(myColumnStateName($grid));
if (columnsState) {
colStates = columnsState.colStates;
for (i = 0; i < l; i++) {
colItem = colModel[i];
cmName = colItem.name;
if (cmName !== 'rn' && cmName !== 'cb' && cmName !== 'subgrid') {
colModel[i] = $.extend(true, {}, colModel[i], colStates[cmName]);
}
}
}
return columnsState;
},
firstLoad = true;
myColumnsState = restoreColumnState(cm);
isColState = typeof (myColumnsState) !== 'undefined' && myColumnsState !== null;
$grid.bind('SaveSettings', function() { saveColumnState.call($grid, $grid.jqGrid('getGridParam', 'remapColumns')); });
$grid.jqGrid({url: '/Databind/',
datatype: 'json',
mtype: 'GET',
height: '100%',
width: 940,
shrinkToFit: false,
colModel: cm,
rowNum: isColState ? myColumnsState.rowNum : 15,
rowList: [5,10,15,30,50],
pager: $('#gridPager'),
page: isColState ? myColumnsState.page : 1,
sortname: isColState ? myColumnsState.sortname : 'BillingRecordId',
sortorder: isColState ? myColumnsState.sortorder : 'asc',
search: isColState ? myColumnsState.search : false,
viewrecords: true,
loadComplete: function () {
if (firstLoad) {
firstLoad = false;
if (isColState) {
$(this).jqGrid('remapColumns', myColumnsState.permutation, true);
}
}
saveColumnState.call($(this), this.p.remapColumns);
if($(this).jqGrid('getGridParam', 'page') > $(this).jqGrid('getGridParam', 'lastpage')) {
alert('reloading'); //this message shows
$(this).trigger('reloadGrid', [{ page: 1}]); //this doens't refresh the grid
}
}
}).navGrid('#gridPager', { edit: false, add: false, del: false, refresh: false, search: false });
$grid.jqGrid('navButtonAdd', '#gridPager', {
buttonicon: 'ui-icon-closethick',
caption: 'Reset Settings',
title: 'Reset Settings',
onClickButton: function () {
removeObjectFromLocalStorage(myColumnStateName($grid));
$grid.unbind('SaveSettings');
window.location.reload();
}
});
$grid.jqGrid('navButtonAdd', '#gridPager', {
buttonicon: 'ui-icon-transferthick-e-w',
caption: 'Choose Columns',
title: 'Choose Columns',
onClickButton: function () {
$(this).jqGrid('columnChooser', {
done: function (perm) {
if (perm) {
this.jqGrid('remapColumns', perm, true);
saveColumnState.call(this, perm);
}
}
});
}
});
});
$(window).unload( function () { $('#grid').trigger('SaveSettings'); });
I have read around and cannot find a solution. I have tried moving the trigger.('reloadGrid') into the gridComplete function but it doesn't work either. Always the alert message shows but the grid is not refreshed.
Upvotes: 2
Views: 9829
Reputation: 8085
This works with jqGrid javascript version 4.4.4.
The primary problem is that reloadGrid doesn't work when we want it to. To understand why I'll explain everything I've learned today about reloadGrid. If none of that is of interest feel free to skip to the solution.
reloadGrid
has the following pseudocode:
populate()
or populateVisible()
)Both populate
and populateVisible
have identical pseudo code:
loading
, if (loading) { return; } else {/*load data*/}
loading = true
loading = false
I can't imagine having a problem without ajax. Therefore, I'm going to just focus on ajax.
The grid provides lots of helpful events we can hook into during the ajax process. Unfortunately, all of the jqGrid events we can hook into occur before step 6. This means that loading
always equals true when our events handlers are triggered. Because loading
is false reloadGrid
won't do anything when it calls out to populate()
.
To get around this we need to be able to inject our logic for reloading into a location after loading
has been set to false. The easiest way I've found to do this is to inject our logic into the ajax complete event. For the given question above it would look like the following.
function reloadGridIfPageIsBeyondLast() {
if($(this).jqGrid('getGridParam', 'page') > $(this).jqGrid('getGridParam', 'lastpage')) {
$(this).trigger('reloadGrid', [{ page: 1}]);
}
}
$('#grid').jqGrid('setGridParam', {
ajaxGridOptions: {
complete: reloadJqGridIfPagePastLast
}
}
Upvotes: 0
Reputation: 175
I found a workaround, it is not perfect though. If I use setTimeout to add a delay to the reload call, everything works. I added an additional check to make sure the lastPage is over 0 otherwise empty grids will constantly reload.
loadComplete: function () {
if (firstLoad) {
firstLoad = false;
if (isColState) {
$(this).jqGrid('remapColumns', myColumnsState.permutation, true);
}
}
saveColumnState.call($(this), this.p.remapColumns);
var lastPage = $(this).jqGrid('getGridParam', 'lastpage');
var page = $(this).jqGrid('getGridParam', 'page');
if(lastPage > 0 && page > lastPage) {
setTimeout(function () { $('#grid').trigger('reloadGrid', [{ page: 1}]); },150);
}
}
Upvotes: 4