How to refresh jqgrid and go back to the current page using loadonce: true - jqgrid

I am using the following setting which loads all the data from the server at once:
loadonce: true
Now I attempt to reload the grid after an edit:
// options for the Edit Dialog
{
closeAfterEdit: true,
closeOnEscape: true,
reloadAfterSubmit: true,
editCaption: "Edit User",
width: 1140,
height: 370,
afterSubmit: function () {
$('#jqGrid').jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');
return [true,'']; // no error
},
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
The data is refreshed from the server however, there is an issue: For example, If I edit a record in page 2, it shows page 2 on the navbar on the bottom but it always brings up the data from page 1. Any help would be appreciated. Thanks.
Update #1
I tried the following code:
var $self = $(this), p = $self.jqGrid("getGridParam");
p.datatype = "json";
$self.trigger("reloadGrid", { page: p.page, current: true });
Then I edit and click on submit, it still loads page 1 data even though the navbar stays on page 2. Then I click the forward arrow to go to page 3, then the back arrow to go to page 2 again and now it shows the page 2 data.
Update #2
Here is additional relevant code of all I am doing and still not working:
...
cmTemplate: { editable: true, editrules: { edithidden: true } },
pager: "#jqGridPager",
rowNum: 10,
rowList: [5, 10, 20, 50],
sortname: 'lastName, firstName',
sortorder: 'asc',
loadonce: true,
viewrecords: true,
gridview: true,
recreateForm: true,
width: 1140,
height: "auto",
multiselect: false,
altRows: false,
shrinkToFit: true,
scroll: false
}
});
...
$('#jqGrid').navGrid('#jqGridPager',
// the buttons to appear on the toolbar of the grid
{
edit: true,
add: true,
del: true,
search: true,
view: true,
refresh: true,
position: "left",
cloneToTop: false,
beforeRefresh: function () {
//Note: This function is only called after user clicks the refresh button
$('#jqGrid').jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');
}
},
// Options for the Edit Dialog
{
closeAfterEdit: true,
closeOnEscape: true,
reloadAfterSubmit: false,
editCaption: "Edit User",
width: 1140,
height: 370,
afterSubmit: function () {
var $self = $(this), p = $self.jqGrid("getGridParam");
p.datatype = "json";
$self.trigger("reloadGrid", { page: p.page, current: true });
return [true, '']; // no error
},
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
...
FINAL OUTCOME
I finally got the issue resolved! I switched from the not free Guriddo jqGrid to free jqGrid by Oleg and the bug was gone! I originally could not get the navigation buttons to appear on the free jqgrid but the reason they didnt appear is because I had the tag iconSet: "fontAwesome" and I did not reference that font. When I removed that tag completely, everything worked perfect. You can use that tag but you must reference the iconset url. In my case I did not need a different icon set.

You can use page option of reloadGrid (see the answer for the corresponding demo). You can use $(this).jqGrid("getGridParam", "page") to get page parameter, which hold the current page.
afterSubmit: function () {
var $self = $(this), p = $self.jqGrid("getGridParam");
p.datatype = "json";
$self.trigger("reloadGrid", { page: p.page, current: true });
return [true]; // no error
}
I used current: true option of reloadGrid to select the currently selected row after reloading of the grid.

Related

Why "allData" is an empty array?

I am trying to get the data from a jqGrid (free version and latest version) and it's suppose that I get:
all the data if none is selected
the selected data if any
This is how I am doing it:
$(function () {
var $order_logs = $('#order_logs');
$order_logs.jqGrid({
url: Routing.generate('api_order_logs'),
datatype: "json",
colModel: $colmodel.data('values'),
width: 980,
height: 300,
pager: true,
toppager: true,
hoverrows: true,
shrinkToFit: true,
autowidth: true,
rownumbers: true,
viewrecords: true,
rowList: [25, 50, 100],
rownumWidth: 60,
gridview: true,
sortable: {
options: {
items: ">th:not(:has(#jqgh_order_logs_cb,#jqgh_order_logs_rn,#jqgh_order_logs_actions),:hidden)"
}
},
jsonReader: {
root: 'rows',
page: 'page',
total: 'total',
records: 'records',
cell: '',
repeatitems: false
},
cmTemplate: {autoResizable: true, editable: true},
autoResizing: {compact: true, resetWidthOrg: true},
autoresizeOnLoad: true
}).jqGrid('navGrid', {
edit: false,
add: false,
del: false,
search: false,
refresh: true,
refreshstate: "current",
cloneToTop: true
}).jqGrid('navButtonAdd', {
caption: 'Export',
title: 'Export',
onClickButton: function () {
var filteredData = $order_logs.jqGrid("getGridParam").lastSelectedData,
allData = $order_logs.jqGrid('getGridParam', 'data');
exportData(filteredData, allData);
}
});
});
function exportData(filteredData, allData) {
if (filteredData.length === 0 || allData.length === 0) {
alert('There is no data to export');
return;
}
// Export only the filtered data
if (filteredData.length > 0) {
return;
}
// Export all the grid data
}
For some reason the value of allData is always an empty array and I am not sure since I am using the same code as everyone is using out there and found in a lot of answer here in SO.
UPDATE:
Currently the grid is holding six columns and a set of 60 records as total paginated by 20 each time however you can change the pagination to be 50 or 100.
Can any tell me why is this?
I'd recommend to use loadonce: true, forceClientSorting: true options in case of small dataset: less at 1000 or 10000 rows. It simplifies the code server side and you can use full functionality of free jqGrid. The problem with access to lastSelectedData and data will be solved.
More then that, you can easy use many advanced features like createColumnIndex: true, generateValue: true of generateDatalist: true options and so on. See demos included in README of version 4.14.1. Good and comfortable filtering of the data is, in my option, the part of displaying the data. Having the data locally allows to find unique values and build <select> in the filter bar or to use <datalist> to have autocomplete functionality.

Hide navgrid buttons depending on the number of records in jqgrid

I need to hide the delete button if there are less than 2 records in the grid. This is the js code. For some reason, the flag showDelCurrencyButton is not working out here and is always false.
Any other way to do it?
showDelCurrencyButton = false;
grid.jqGrid({
datatype: 'local',
jsonReader: jqgrid.jsonReader('CurrCd'),
mtype: 'POST',
pager: '#currencyPager',
colNames: ['Abbrev.', 'Name', 'Symbol'],
colModel: [
{
name: 'CurrCd', index: 'CurrCd', width: 200, sortable: false,
editable: true,
edittype: 'select', stype: 'select',
editrules: { required: true },
editoptions: {
dataUrl: getServerPath() + 'Ajax/GetCurrencies',
buildSelect: function (data) {
var currSelector = $("<select id='selCurr' />");
$(currSelector).append($("<option/>").val('').text('---Select Currency---'));
var currs = JSON.parse(data);
$.each(currs, function () {
var text = this.CurName;
var value = this.CurCode;
$(currSelector).append($("<option />").val(value).text(text));
});
return currSelector;
}
}
},
{ name: 'CurrName', index: 'CurrName', width: 200, sortable: false },
{ name: 'CurrSymbol', index: 'CurrSymbol', width: 200, sortable: false },
],
loadtext: 'Loading...',
caption: "Available Currencies",
scroll: true,
hidegrid: false,
height: 116,
width: 650,
rowNum: 1000,
altRows: true,
altclass: 'gridAltRowClass',
onSelectRow: webview.legalentities.billing.onCurrencySelected,
loadComplete: function (data) {
if (data.length > 1) {
showDelCurrencyButton = true;
}
var rowIds = $('#currencyGrid').jqGrid('getDataIDs');
$("#currencyGrid").jqGrid('setSelection', rowIds[0]);
},
rowNum: 1000
});
grid.jqGrid('navGrid', '#currencyPager', {
edit: false,
del: (showDelCurrencyButton == true),
deltitle: 'Delete record',
search: false,
refresh: false
}
});
Your current code uses datatype: 'local' without specifying data parameter with input data. It seems strange. In any way you can hide the Delete button dynamically identifying it by id. It's "del_" + grid[0].id in your case. Thus you can use $("#del_" + grid[0].id).hide(); to hide it. By the way one can use this instead of grid[0] inside of loadComplete.
I'd recommend you to read the old answer for more details and to read the answer, which shows how to disable/enable navigator buttons (like Delete button) instead of hiding.

jqgrid save previous row onSelectRow not working

I'm using jqgrid 4.8.2. If a user clicks on a row, I want to save the previously selected row and display the current row in edit mode. I've used the code from previous answers but can't get this functionality to work. After some debugging and looking through the source code for jqgrid, it appears saveRow does not fire because the 'editable' attribute for the previous row is immediately set to 0. There is a clause in the jqgrid source code that looks for this attribute before saving the row:
editable = $(ind).attr("editable");
o.url = o.url || $t.p.editurl;
if (editable==="1") {....saveRow occurs...}
Any suggestion on how to work around this?
var editingRowId;
var myEditParam = {
keys: true,
extraparam: {activityID: aID},
oneditfunc: function (id) { editingRowId = id; },
afterrestorefunc: function (id) { editingRowId = undefined; },
aftersavefunc: function (id) { editingRowId = undefined; }
};
var myGrid = jQuery("#spend_grid").jqGrid({
url: parentGridURL,
mtype: "POST",
datatype: "json",
postData: {filters: myFilters},
gridview: false, //added for IE
altRows: true,
emptyrecords: 'NO PAYMENTS FOUND',
editurl: savePaymentURL,
onSelectRow: function (id) {
console.log('id=' + id + ' editingRowId =' + editingRowId);
var $this = $(this);
if (editingRowId !== id) {
if (editingRowId) {
// save or restore currently editing row
console.log('should be saving ' + editingRowId);
$this.jqGrid('saveRow', editingRowId, myEditParam);
console.log('done saving');
}
$this.jqGrid("editRow", id, myEditParam);
}
},
search: true,
sortname: lastSortName,
sortorder: lastSortOrder,
page: lastPage,
pager: jQuery('#report_pager'),
rowNum: lastRowNum,
rowList: [10,20,50,100],
viewrecords: true,
clearSearch: false,
caption: "Payments",
sortable: true,
shrinkToFit: false,
excel: true,
autowidth: true,
height: 300,
subGrid: true, // set the subGrid property to true to show expand buttons for each row
subGridRowExpanded: showChildGrid, // javascript function that will take care of showing the child grid
colModel: [
{ label: 'Payment ID',
name: 'PAYMENTID',
index: 'p.paymentID',
key: true, width: 75
},...// removed for brevity
{name : 'actions',
label: 'Actions',
index: 'formAction',
formatter:'actions',
width: 75,
search:false,
formatoptions: {
keys: true,
editbutton: false,
delOptions: { url: savePaymentURL }
}
}
]
}).inlineNav('#report_pager',
// the buttons to appear on the toolbar of the grid
{
restoreAfterSelect: false, // *****SOLUTION******
save:false,
edit: false,
add: false,
cancel: false
});
Found a solution to the issue. After examining the jqgrid source code I found that restoreAfterSelect: true is the default setting for the inlineNav. I added restoreAfterSelect: false and now the previous row saves.

jqGrid filterToolbar with local data

I have a jQgrid that loads data initially via an ajax call from backend(java struts). Again, this is one time load and once loaded, the jqGrid should operate on the data available locally.
Initially, datatype:json and once loadcomplete, set datatype:local.
Now is there a way to use filterToolbar for local datatype with the following options in free jqgrid;
autocomplete enabled in the toolbar
excel like filtering options
Jqgrid Options:
jQuery("#listTable").jqGrid({
url:'/WebTest/MainAction.do',
datatype: "json",
colNames: ['Label','Value'],
colModel: [
{name:'label',index:'label',width: 40,search:true, stype:'text',sorttype:'int'},
{name:'value',index:'value',width: 56,search:true, stype:'text',sorttype:'text'}
],
autowidth: true,
autoResizing: { compact: true, widthOfVisiblePartOfSortIcon: 13 },
rowNum: 10,
rowList: [5, 10, 20, "10000:All"],
viewrecords: true,
pager: true,
toppager: true,
rownumbers: true,
sortname: "label",
sortorder: "desc",
caption: "Test 235",
height: "200",
search: true,
loadonce: true,
loadComplete: function (data) {
},
gridComplete: function(){
jQuery("#listTable").jqGrid('setGridParam', { datatype: 'local' });
}
}) .jqGrid("navGrid", { view: true, cloneToTop: true})
.jqGrid("filterToolbar")
.jqGrid("gridResize");
All the features are enabled by default if I understand you correctly. The server just have to return all data instead of one page of data to make loadonce: true property work correctly. You need just call filterToolbar after creating the grid. All will work like with local data. You should consider to set sorttype property for correct local sorting and stype and searchoptions for correct filtering of data.
To have "autocomplete" and "excel like filtering options" you need additionally to follow the answer which set autocomplete or stype: "select", searchoptions: { value: ...} properties based on different values of input data. You can do this inside of beforeProcessing callback. The code from the answer use this.jqGrid("getCol", columnName) which get the data from the grid. Instead of that one have access to data returned from the server inside of beforeProcessing callback. So one can scan the data to get the lists with unique values in every column and to set either autocomplete or stype: "select", searchoptions: { value: ...} properties.
UPDATED: I created JSFiddle demo which demonstrates what one can do: http://jsfiddle.net/OlegKi/vgznxru6/1/. It uses the following code (I changed just echo URL to your URL):
$("#grid").jqGrid({
url: "/WebTest/MainAction.do",
datatype: "json",
colNames: ["Label", "Value"],
colModel: [
{name: "label", width: 70, template: "integer" },
{name: "value", width: 200 }
],
loadonce: true,
pager: true,
rowNum: 10,
rowList: [5, 10, "10000:All"],
iconSet: "fontAwesome",
cmTemplate: { autoResizable: true },
shrinkToFit: false,
autoResizing: { compact: true },
beforeProcessing: function (data) {
var labelMap = {}, valueMap = {}, i, item, labels = ":All", values = [],
$self = $(this);
for (i = 0; i < data.length; i++) {
item = data[i];
if (!labelMap[item.label]) {
labelMap[item.label] = true;
labels += ";" + item.label + ":" + item.label;
}
if (!valueMap[item.value]) {
valueMap[item.value] = true;
values.push(item.value);
}
}
$self.jqGrid("setColProp", "label", {
stype: "select",
searchoptions: {
value: labels,
sopt: ["eq"]
}
});
$self.jqGrid("setColProp", "value", {
searchoptions: {
sopt: ["cn"],
dataInit: function (elem) {
$(elem).autocomplete({
source: values,
delay: 0,
minLength: 0,
select: function (event, ui) {
var grid;
$(elem).val(ui.item.value);
if (typeof elem.id === "string" && elem.id.substr(0, 3) === "gs_") {
grid = $self[0];
if ($.isFunction(grid.triggerToolbar)) {
grid.triggerToolbar();
}
} else {
// to refresh the filter
$(elem).trigger("change");
}
}
});
}
}
});
// one should use stringResult:true option additionally because
// datatype: "json" at the moment, but one need use local filtreing later
$self.jqGrid("filterToolbar", {stringResult: true });
}
});

jqGrid Top Toolbar

I am trying to replicate the action buttons that are present in the bottom toolbar on the top toolbar.
But so far no luck, I have included the truncated code below.
Paging is not an option in this case so the user requires both top and bottom toolbars.
jQuery("#GridName").jqGrid({
url: '<%= ResolveUrl("~") %>SomeController/SomeMethod ....',
datatype: 'json',
colNames: ['Column1', 'Column2', 'Details', 'Date'],
colModel: [
//......
],
pager: '#GridNamePager',
viewrecords: true,
emptyrecords: "Nothing to display",
shrinkToFit: true,
hidegrid: false,
scroll: false,
width: 976,
height: 'auto',
loadui: 'enable',
pgtext: '',
pgbuttons: false,
pginput: false,
multiselect: true,
multiboxonly: true,
toolbar:[true,"top"],
ondblClickRow: function(id) {
var publishedUrl =
$("#GridName").find("tbody")[0].rows[id-1].cells[5].innerHTML;
},
caption: "Grid Results"
}).navGrid('#GridNamePager', { add: false, edit: false, del: false,
search: false, cloneToTop:true })
.navButtonAdd('#GridNamePager', { caption: "Save", onClickButton:
function() { Save(); return false; }, position: "last" })
.navButtonAdd('#GridNamePager', { caption: "Back", onClickButton:
function() { redirectBack(); return false; }, position: "last" })
where
<table id="GridName" class="scroll"></table>
<div id="GridnamePager" class="scroll" style="text-align:center;"></div>
Probably the answer Adding button to jqGrid top toolbar would helps you? If not try to explain more exactly which elements of navigation bar or other jqGrid elements you would be move to another place.

Resources