When i use "loadonce" set to be "true",my problem is searching or filtering works ,but pagination doesn't work.If i change loadonce to be false,searchong can't work,but pagination works.
How do I make sure I set the data type to be json during the pagination alone.
$grid = $("#list"),
numberTemplate = {
formatter: 'number',
align: 'right',
sorttype: 'number',
editrules: {
number: true,
required: true
},
searchoptions: {
sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge', 'nu', 'nn', 'in', 'ni']
}
};
var myDelOptions = {
onclickSubmit: function (rp_ge, rowid) {
// we can use onclickSubmit function as "onclick" on "Delete" button
// alert("The row with rowid="+rowid+" will be deleted");
// delete row
grid.delRowData(rowid);
$("#delmod" + grid[0].id).hide();
if (grid[0].p.lastpage > 1) {
// reload grid to make the row from the next page visable.
// TODO: deleting the last row from the last page which number is higher as 1
grid.trigger("reloadGrid", [{
page: grid[0].p.page
}]);
}
return true;
},
processing: true
};
$.extend($.jgrid.inlineEdit, {
keys: true
});
$grid.jqGrid({
url: $('#contextPath').val() +"/globalcodes/getList?masterCodeSysid="+$('#Sysid').val(),
datatype: 'json',
colNames: ['Sequence', 'Detail Code', 'Code Description', 'Status', 'Cross Referrences', '', ''],
colModel: [ {
name: 'seqNumber',
width: 50,
editable: false,
search:true
}, {
name: 'dtlCode',
width: 50,
editable: true,
searchoptions:{sopt:['cn','eq','ne']}
}, {
name: 'codeDesc',
width: 200 ,
searchoptions:{sopt:['cn','eq','ne']}
}, {
name: 'statusFlag',
width: 150,
edittype:"select",
formatter : 'select',
editoptions:{value:"Y:Active;N:Inactive"},
searchoptions:{sopt:['cn','eq','ne']}
}, {
name: 'crossReferrenced',
width: 100,
editable: false,
searchoptions:{sopt:['cn','eq','ne']}
},{
name: 'act',
index: 'act',
width: 55,
align: 'center',
search: false,
sortable: false,
formatter: 'actions',
searchoptions:{sopt:['cn','eq','ne']} ,
editable: false,
formatoptions: {
keys: true, // we want use [Enter] key to save the row and [Esc] to cancel editing.
onEdit: function (rowid) {
$('#add_detail_code').attr('disabled','disabled').addClass("btnDisabled").removeClass("btnNormalInactive");
},
onSuccess: function (jqXHR) {
$grid.setGridParam({ rowNum: 10 }).trigger('reloadGrid');
},
afterSave: function (rowid) {
$('#add_detail_code').removeAttr('disabled').addClass("btnNormalInactive").removeClass("btnDisabled");
},
afterRestore: function (rowid) {
$('#add_detail_code').removeAttr('disabled').addClass("btnNormalInactive").removeClass("btnDisabled");
},
delOptions: myDelOptions
}
},{
name: 'dtlCodeSysid',
hidden: true
}],
cmTemplate: {
editable: true
},
jsonReader: {id:'dtlCodeSysid',
},
rowList: [5, 10, 20],
pager: '#detailCodePager',
gridview: true,
ignoreCase: true,
rowNum:10,
rownumbers: false,
sortname: 'col1',
loadonce:true,
viewrecords: true,
sortorder: 'asc',
height: '100%',
deepempty: true,
editurl: $('#contextPath').val() +"/globalcodes/saveMasterCodeDetails?masterCodeSysId="+$('#masterCodeSysid').val(),
//caption: 'Usage of inlineNav for inline editing',
});
$grid.jqGrid('filterToolbar', {
searchOperators: true
});
$grid.jqGrid('navGrid', '#detailCodePager', {
add: false,
edit: false,
del: false,
search:false,
refresh:true
});
You don't posted any code which you use, so I try to guess. Probably you implemented pagination on the server side and returns only one page of data in case of usage loadonce: true option. Correct usage of loadonce: true on the server side would be returning all data, the data need be just correctly sorted based on sorting parameters sent by jqGrid. By the way the format of returned data from the server could be just array of items instead of wrapping results in { "total": "xxx", "page": "yyy", "records": "zzz", "rows" : [...]}. In case of usage loadonce: true option the data from total, page and records will be ignored and calculated based on the size of array returned data.
Related
Here is my scenario. My jqgrid v5.2.1 doesn't display any data when a page loads up. It is by design. Users will either have to enter all the data for the grid and subgrid manually or click a button to load a default data from the server in the json format via
$("#jqGrid").jqGrid('setGridParam', { datatype: 'local', data: dataResponse.groups }).trigger("reloadGrid");
Users perform CRUD operations locally until the data is right in which case a button is clicked and the grids data goes to the server via $("#jqGrid").jqGrid('getGridParam', 'data').
Edit/Delete operations work fine with the default data loaded but I have a problem with adding new records.
Id's of new rows are always _empty(which is fine because the server side will generated it), but the new rows from the subgrids are not transferred to the server. The question is how to establish the relationship between the newly created rows in the main grid and associated rows in the subgrid and then transfer everything to the server for processing?
Here is the code:
var mainGridPrefix = "s_";
$("#jqGrid").jqGrid({
styleUI: 'Bootstrap',
datatype: 'local',
editurl: 'clientArray',
postData: {},
colNames: ['Id', 'Group', 'Group Description', 'Markets', 'Group sort order'],
colModel: [
{ name: 'id', key: true, hidden: true },
{ name: 'name', width: 300, sortable: false, editable: true, editrules: { required: true }, editoptions: { maxlength: 50 } },
{ name: 'description', width: 700, sortable: false, editable: true, editoptions: { maxlength: 256 } },
{ name: 'market', width: 200, sortable: false, editable: true, editrules: { required: true }, editoptions: { maxlength: 50 } },
{ name: 'sortOrder', width: 130, sortable: false, editable: true, formatter: 'number', formatoptions: { decimalSeparator: ".", thousandsSeparator: ',', decimalPlaces: 2 } }
],
sortname: 'Id',
sortorder: 'asc',
idPrefix: mainGridPrefix,
subGrid: true,
//localReader: { repeatitems: true },
jsonReader: { repeatitems: false},
autowidth: true,
shrinkToFit: true,
loadonce: true,
viewrecords: true,
rowNum: 5000,
pgbuttons: false,
pginput: false,
pager: "#jqGridPager",
caption: "Group Template",
altRows: true,
altclass: 'myAltRowClass',
beforeProcessing: function (data) {
var rows = data.rows, l = rows.length, i, item, subgrids = {};
for (i = 0; i < l; i++) {
item = rows[i];
if (item.groupItems) {
subgrids[item.id] = item.groupItems;
}
}
data.userdata = subgrids;
},
subGridRowExpanded: function (subgridDivId, rowId) {
var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
pureRowId = $.jgrid.stripPref(mainGridPrefix, rowId),
subgrids = $(this).jqGrid("getGridParam", "userData"),
subgridPagerId = subgridDivId + "_p";
$("#" + $.jgrid.jqID(subgridDivId)).append($subgrid).append('<div id=' + subgridPagerId + '></div>');
$subgrid.jqGrid({
datatype: "local",
styleUI: 'Bootstrap',
data: subgrids[pureRowId],
editurl: 'clientArray',
colNames: ['Item', 'Item Description', 'Health Standard', 'Sort order', 'Statuses', 'Risks', 'Solutions', 'Budgets'],
colModel: [
{ name: 'itemName', width: '200', sortable: false, editable: true, editrules: { required: true }, editoptions: { maxlength: 50 } },
{ name: 'itemDescription', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 } },
{ name: 'healthStandard', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 } },
{ name: 'itemSortOrder', width: '200', sortable: false, editable: true, formatter: 'number', formatoptions: { decimalSeparator: ".", thousandsSeparator: ',', decimalPlaces: 2 } },
{ name: 'statuses', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 } },
{ name: 'risks', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 } },
{ name: 'solutions', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 } },
{ name: 'budgets', width: '400', sortable: false, editable: true, editoptions: { maxlength: 100 } }
],
//rownumbers: true,
rowNum: 5000,
autoencode: true,
autowidth: true,
pgbuttons: false,
viewrecords: true,
pginput: false,
jsonReader: { repeatitems: false, id: "groupId" },
gridview: true,
altRows: true,
altclass: 'myAltRowClass',
idPrefix: rowId + "_",
pager: "#" + subgridPagerId
});
$subgrid.jqGrid('navGrid', "#" + subgridPagerId, { edit: true, add: false, del: true, search: true, refresh: false, view: false }, // options
{ closeAfterEdit: true }, // edit options //recreateForm: true
{ closeAfterAdd: true }, // add options
{}, //del options
{} // search options
);
}
});
$('#jqGrid').navGrid('#jqGridPager', { edit: true, add: false, del: true, search: true, refresh: false, view: false }, // options
// options for Edit Dialog
{
editCaption: "Edit Group",
beforeShowForm: function (form) {
form.closest('.ui-jqdialog').center();
},
bottominfo: "<br/>",
recreateForm: true,
closeOnEscape: true,
closeAfterEdit: true
},
// options for Add Dialog
{
//url:'clientArray',
addCaption: "Add Group",
beforeShowForm: function (form) {
form.closest('.ui-jqdialog').center();
},
bottominfo: "<br/>",
recreateForm: true,
closeOnEscape: true,
closeAfterAdd: true
},
// options for Delete Dailog
{
caption: "Delete Group",
beforeShowForm: function (form) {
form.closest('.ui-jqdialog').center();
},
msg: "Are you sure you want to delete?",
recreateForm: true,
closeOnEscape: true,
closeAfterDelete: true
},
// options for Search Dailog
{
caption: "Search Group",
beforeShowForm: function (form) {
form.closest('.ui-jqdialog').center();
},
recreateForm: true,
closeOnEscape: true,
closeAfterDelete: true
}
);
There was a small bug in the form editing which is fixed now. Thank you for help us to find them.
Now to the problem.
When you add data in main grid it is natural to add a unique id of every row. Since of the bug instead of inserting a row with the Guriddo id Generator there was a wrong insertion with id = s_empty. This causes every inserted row in main grid to have same id, which is not correct.
The fix is published in GitHub and you can try it.
We have updated your demo in order to insert correct the data in the subgrid. The only small addition is in afterSubmit event in add mode, where the needed item is created.
Hope this will solve the problem
Here is the demo with the fixed version
Edited
At server you can analyze the id column if contain string 'jqg', which will point you that this is a new row. The corresponding id for the subgrid is in userData module which will connect the main grid id with the subgrid data
EDIT 2
One possible solution to what you want to achieve is to get the main data and the to get the subgrid data using userData property. After this make a loop to main data and update it like this
var maindata = $("#jqGrid").jqGrid('getGridParam', 'data');
var subgrids = $("#jqGrid").jqGrid('getGridParam', 'userData');
for(var i= 0;i < maindata.length;i++) {
var key = maindata[i].id;
if(subgrids.hasOwnProperty(key) ) {
if(!maindata[i].hasOwnProperty(groupItems) ) {
maindata[i].groupItems = [];
}
maindata[i].groupItems = subgrids[key];
}
}
The code is not tested, but I think you got the idea.
The other way is to update the groupitems on every CRUD of subgrid, which I think is not so difficult to achieve.
My jqgrid is working perfectly but now i am implementing the subgrid. It shows the + sign and when i click on it the blank row displayed with loading.... this is the client side code
$(document).ready(function () {
$("#Grid").jqGrid({
url: '/Home/GetDetails',
datatype: 'json',
myType: 'GET',
colNames: ['id','Name', 'Designation', 'Address', 'Salary'],
colModel: [
{ key: false, name: 'Id', index: 'Id', },
{ key: false, name: 'Name', index: 'Name', editable: true },
{ key: false, name: 'Designation', index: 'Designation', editable: true },
{ key: false, name: 'Address', index: 'Address', editable: true },
{ key: false, name: 'Salary', index: 'Salary', editable: true }
],
jsonReader: {
root: 'rows',
page: 'page',
total: 'total',
records: 'records',
id: '0',
repeatitems: true
},
pager: $('#pager'),
rowNum: 10,
rowList: [10, 20, 30],
width: 600,
viewrecords: true,
multiselect: true,
sortname: 'Id',
sortorder: "desc",
caption: 'Employee Records',
loadonce: true,
gridview: true,
autoencode: true,
subGrid: true,
subGridUrl: '/Home/Subgrid',
subGridModel: [{
name: ['No', 'Item','Quantity'],
width: [55, 55,55]
}
],
}).navGrid('#pager', { edit: true, add: true, del: true },
{
zIndex: 100,
url: '/Home/Edit',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText)
{
alert(response.responseText);
}
}
},
{
zIndex: 10,
url: '/Home/Add',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
},
{
zIndex: 100,
url: '/Home/Delete',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
}
);
});
Subgrid url action method is as below:
public JsonResult Subgrid(String id)
{
Database1Entities db = new Database1Entities();
Product p= new Product {No=1,Item="Juice",Quantity=23};
var jsondata = new { rows=2,
cell = new string[] { p.No.ToString(),
p.Item,p.Quantity.ToString()}.ToArray()
};
return Json(jsondata, JsonRequestBehavior.AllowGet);
}
I am doing this first time. What is the mistake?Thanks in advance
I don't recommend you to use subGridModel. Instead of that it's much more flexible to use Subgrid as Grid. If the user clicks "+" icon (expand subgrid) then jqGrid just inserts empty row under selected with simple structure described in the answer for example. The id of the <div> where some custom "subgrid" information need be displayed will be the first parameter of subGridRowExpanded callback which you need to implement. The second parameter is the rowid of the expending row. By implementing the corresponding callback you can create any custom "subgrid". See the old answer for very simple demo.
So what you need to do is just write the code which creates grid which will be placed in subgrid row. It's only strictly recommended to use idPrefix parameter which used any values which depends from subgriddivid or parent rowid. Additionally you can consider to use autowidth: true option for subgrid, which will make the width of subgrid be exact correspond to the width of the main grid. Of cause to have rowid of the parent row send as id parameter to '/Home/Subgrid' you need use postData: { id: rowid }. See the code from the answer for example which I referenced previously.
I have a customer details where I am showing the customers bill status which is working fine,
Is it possible to rebind the grid once we loaded the data in grid for example:
when I am coming from another page how to apply search on the existing grid data and rebind it to grid.
Below is my colmodel and other properties which I am using but not working properly,
$("#BillDetails").jqGrid({
url: '../Handler.ashx,
datatype: "json",
colNames: [ 'S.No', 'Bill NO', 'Customer Name', 'Customer Type', 'Bill Date',Bill Status'],
colModel: [
{ name: 'SERIAL', sortable: false, search: true, stype: 'text', width: 40, hidden: false,
align: 'right', sorttype: 'int' },
{ name: 'BILL_NO', sortable: false, search: true, width: 80, hidden: false,
align: 'right',formatter: editLink,},
{ name: 'CUSTOMER_NAME', search: true, align: 'left', width: 150, aligh: 'left',
sortable: false },
{ name: 'CHECK_TYPE', align: 'left', width: 150, search: true, aligh: 'left',
sortable: false},
{ name: 'BILL_DATE', width: 85, sortable: false, search: true, align: 'center',
sorttype: 'date', formatter: "date", formatoptions: { newformat: 'd/m/Y' } },
{ name: 'BILL_STATUS', width: 90, align: 'left', search: true, stype: 'select',
searchoptions: { value: 'Pending:Pending;
On Hold:On Hold;Clear:Clear;Incompelete:InComplete,sortable: false } },
],
width: '980',
height: '450',
shrinkToFit: false,
sortable: true,
mtype: 'GET',
scrollbar: true,
sortname: 'BILL_NO',
sortorder: 'asc',
hidegrid: false,
loadonce: true,
ignoreCase: true,
rowNum: 50,
pager: '#Pager',
viewrecords: true,
// Search on page load from grid data
gridComplete: function () {
var searchFilter = "Clear"; // In this I will receive the the status from query string,
//for now i have provided the the hard core value to test
var gridData = $("#jQGridDemo").jqGrid('getGridParam', 'data');
console.log(gridData);
if (searchFilter != "") {
var grid = $("#BillDetails"), f;
f = { rules: [] };
f.rules.push({ field: "STATUS", op: "eq", data: searchFilter });
grid[0].p.search = true;
$("#BillDetails").setGridParam({ data: gridData, postData: { filters: f },
datatype: "local", });
}
}
});
If you want to reload jqGrid when coming from another page with search parameters you could use postData property of jqGrid.
Something like this:
$("#BillDetails").jqGrid({
url: '../Handler.ashx',
datatype: "json",
mtype: 'GET',
postData:
{
Page: 'Dashboard',
strUserID: strUserID,
}
You can populate this property with js or on server side as you need.
UPDATE
You also can use setGridParam method of jqgrid:
$("#BillDetails").jqGrid('setGridParam',
{
postData: {
Page: 'Dashboard',
strUserID: strUserID,
}
});
$("#BillDetails").trigger("reloadGrid");
But as i understand this way you also just add values to postData property.
Also you can try it this way:
$("#BillDetails").trigger('reloadGrid', [{page:1}]);
You can pass there your new params as on grid init.
I'm using jqGrid 4.4.5 and the toolbar filter.The grid can reloads base on condition(for example inbox or outbox letters).I use select options of a column.I need to change the select options of a 'type' column.For example if the grid show 'inbox letter' Then 'select options' show 'A,B' Otherwise show 'C,D'.
I use this code for create grid:
function creatGrid() {
var inboxSearchOptions = 'A:A;B:B;All:';//inbox Options
var inboxEditOptions = 'A:A;B:B';
var outboxSearchOptions = 'C:C;D:D;ALL:';
var outboxEditOptions = 'C:C;D:D';
grid.jqGrid({
url: 'jqGridHandler.ashx',
datatype: 'json',
width: 100,
height: 200,
colNames: ['Email', 'Subject', 'Type', 'ID'],
colModel: [
{ name: 'Email', width: 100, sortable: false, },
{ name: 'Subject', width: 100, sortable: false, },
{
name: 'Type',
width: 100,
search: true,
formatter: 'select',
edittype: 'select',
editoptions: { value: (($.cookie("calledFrom") == "inbox") ? inboxEditOptions : outboxEditOptions), defaultValue: 'ALL' },
stype: 'select',
searchoptions: { sopt: ['eq', 'ne'], value: (($.cookie("calledFrom") == "inbox") ? inboxSearchOptions : outboxSearchOptions) },
},
{ name: 'ID', width: 100, sortable: false, hidden: true, key: true },
],
rowNum: 20,
loadonce: true,
rowList: [5, 10, 20],
recordpos: "left",
ignoreCase: true,
toppager: true,
viewrecords: true,
multiselect: true,
sortorder: "desc",
scrollOffset: 1,
editurl: 'clientArray',
multiboxonly: true,
jsonReader:
{
repeatitems: false,
},
gridview: true,
}
}
Then i use this code for reload grid:
function doReloadMainGrid() {
switch (($.cookie("calledFrom")) ) {
case "inbox":
{
window.grid.setColProp("Type", {
searchoptions: {
value: inboxSearchOptions,
},
editoptions: {
value: inboxEditOptions
},
});
}
break;
case "outbox":
window.grid.setColProp("Type", {
searchoptions: {
value: outboxSearchOptions,
},
editoptions: {
value: outboxEditOptions
},
});
break;
}
var url = createUrl();
window.grid.setGridParam({ datatype: 'json' });
window.grid.setGridParam({ url: url });
window.grid.trigger("reloadGrid", { current: true });
}
But the 'setColProp' has no effect.I read this answer but it was not a good solution for me.What i got wrong?
Thanks in advance
setColProp don't change existing filter toolbar. If you just get the values from cookie or localStorage than it would be better to do this before the filter toolbar will be created by filterToolbar method.
You can use destroyFilterToolbar to recreate the filter toolbar using new values in colModel. If you have to use old version of jqGrid you can just follow the answer which describe how to add the code destroyFilterToolbar to old version of jqGrid.
$("#grid").jqGrid({
datatype: 'local',
mtype: 'GET',
loadui: 'block',
altRows: true,
altclass: "myAltRow",
multiselect: false,
recordpos: "right",
pagerpos: "center",
pager: $('#gridt_summarypager'),
pginput: false,
rowNum: 100,
recordtext: "Showing {0} - {1} of {2}",
viewrecords: true,
sortname: 'Project',
sortorder: 'asc',
colNames: ['ProjectID', '<%: Project %>', '<%: ProjectTitle %>' , 'ProjectItemID', '<%: usProjectItem %>', 'Hours To Authorise', 'Hours Not Posted', 'Hours Rejected', 'Last 12 Months'],
colModel: [
{ name: 'ProjectID', index: 'ProjectID', width: 0, hidden: true},
{ name: 'Project', index: 'Project', width: 90, align: 'left', formatter: htmlEncodedString },
{ name: 'ProjectTitle', index: 'ProjectTitle', width: 90, align: 'left', formatter: htmlEncodedString },
{ name: 'ProjectItemID', index: 'ProjectItemID', width: 0, hidden:true },
{ name: 'ProjectItem', index: 'ProjectItem', width: 100, align: 'left', formatter: htmlEncodedString },
{ name: 'HoursToAuthorise', index: 'HoursToAuthorise', width: 125, align: 'right', formatter: timesheetsProjectToAuthoriseQueryFormat },
{ name: 'HoursNotPosted', index: 'HoursNotPosted', width: 125, align: 'right', formatter: timesheetsProjectUnpostedQueryFormat<% if (!(bool)ViewData["PostingEnabled"]) { %>, hidden: true <% } %> },
{ name: 'HoursRejected', index: 'HoursRejected', width: 125, align: 'right', formatter: timesheetsProjectRejectedQueryFormat },
{ name: 'HoursSubmitted12Months', index: 'HoursSubmitted12Months', width: 125, align: 'right', formatter: timesheetsProjectYearQueryFormat }],
imgpath: '../../Scripts/css/ui-lightness/images',
height: 145,
shrinkToFit: false,
hoverrows: false,
loadError: function (xhr, st, err) {
if (xhr.status == 200) {
window.location = '<%= loginPage %>';
}
else if (xhr.status == 500) {
$('#grid_summary_errors').html(xhr.statusText);
}
},
beforeSelectRow: function(rowid, e) {
/* disable row selection */
return false;
},
onSortCol: function (index, columnIndex, sortOrder) {
var col = $("#grid_summarygrid").getGridParam('colNames');
var label = "Ordered by " + col[columnIndex] + " " + sortOrder + "ending";
$("#gridsort").text(label);
}
});
$("#grid").setGridParam({ url: '<%= Url.Action(dataMethod, controllerName)%>?qid=xxx', page: 1, datatype: "json" })
.trigger('reloadGrid');
Currently using jqGrid 4.4.1 and it loads data fine but once sort is applied it updates the sort label buy grid data is not sorted. What is going on? Any help most appreciated...
If you set url and change datatype of grid to "json" then your server code is responsible for sorting of data like for paging too. If you want to load all data for the grid at once and want that jqGrid do sorting and paging for you then you should use loadonce: true option.
I recommend you additionally to include gridview: true option in jqGrid, replace pager: $('#gridt_summarypager') to pager: '#gridt_summarypager', remove not existing parameter imgpath and consider to use autoencode: true option of jqGrid which makes HTML encoding of strings in all columns which not contains custom formatter.
{
name: "name",
index:"name",
**sortable: true,**
editable: true,
**sorttype: 'text',**
key: true
},
Make sure that sorttype complies with the fields data type. for example if the grid field "name" contains int numbers, then you should have sorttype: 'int'.
Also as mentioned by Oleg, you need to set loadonce to true.
pager: "#pager",
gridview: true,
rowNum: 5,
loadonce:true,
multiSort: true,
rownumbers: true,
viewrecords: true,
rowList: [5, 10, 15],
include sortable: true in column as well as jqgrid property.
Chaning this parameter value worked for me.
loadonce: true