Jqgrid: Grid refresh on edit, paging - jqgrid

Using latest version of free jqgrid.
I am using the below code for my jqgrid.
I have some issues and question:
1) When I go to next page and previous page not sure what happens but my grid items keep moving up and down.
2) When I add/edit an item for form field I want the grid to refresh and get updated from the server but this does not happens and again my newly added data is lost in the grid as mentioned in my point1. I tried to add navOptions: { reloadGridOptions: { fromServer: true } } but still nothing.
3) When the user clicks on edit button on my pager it opens the user form field. I want the submit button to show edit instead of "Add" which it shows currently.
Here is my code below:
<script type="text/javascript">
$(function () {
"use strict";
var $grid = $("#list");
$grid.jqGrid({
url: '#Url.Action("GetData", "Home")',
datatype: "json",
mtype: 'Get',
colNames: ['Id', 'Name', 'Sex', 'Address'],
loadonce: true,
height: '100%',
autowidth: true,
emptyrecords: "No Users found.",
colModel: [
{ name: 'empid', index: 'empid', editable: true, editrules: { required: true}},
{ name: 'fname', index: 'fname', editable: true, editrules: { required: true}}, //currently these are texbox, but I want this to be label which gets filled based on the empid
{ name: 'lname', index: 'lname', editable: true, editrules: { required: true}},
{ name: 'address', index: 'address', editable: true, editrules: { required: true}}
],
cmTemplate: { autoResizable: true, editable: true },
autoResizing: { compact: true, resetWidthOrg: true },
iconSet: "fontAwesome",
guiStyle: "bootstrap",
rowNum: 10,
rowList: [5, 10, 20, "10000:All"],
viewrecords: true,
autoencode: true,
sortable: true,
pager: true,
rownumbers: true,
sortname: "empid",
sortorder: "desc",
pagerRightWidth: 150,
inlineEditing: {
keys: true
},
searching: {
loadFilterDefaults: false,
closeOnEscape: true,
searchOperators: true,
searchOnEnter: true,
caption: "Search",
Find: "Search"
},
editurl:'#Url.Action("GetDetails", "Home")',
formEditing: {
reloadGridOptions: { fromServer: true },
reloadAfterSubmit: true,
width: 460,
closeOnEscape: true,
closeAfterEdit: true,
closeAfterAdd: true,
closeAfterDelete: true,
savekey: [true, 13],
addCaption: "Add",
editCaption: "Edit",
bSubmit: "Add"
},
formDeleting: {
width: 320,
caption: 'Delete'
},
navOptions: { reloadGridOptions: { fromServer: true } }
}).jqGrid("navGrid")
.editGridRow("new", properties);
});
</script>

The first two items above I was able to resolve using below code:
navOptions: { reloadGridOptions: { fromServer: true } }
But the 3rd item I am still not able to resolve where I am not able to change the text of the Add button to change it to edit when the edit toolbar button is clicked

Related

JqGrid: Autocomplete in form fields

I am using free version (latest) of jqgrid with MVC c#.
I have form fields setup. When the user clicks add in the footer button (add) it shows a modal popup with all the form fields.
I want my first textbox in the form field to autocomplete, ie when they start typing their empployee number in the textbox, I should query my mvc controller and fetch the data and then prefill if there is a match. Once that prefills I also want to update 2 more label on the form, firstname & lastname. Also the button should be disabled until the correct id is fetched in the employee textbox.
Not sure how should I go about this. I can share my sample grid that I have used.
Thanks
<script type="text/javascript">
$(function () {
"use strict";
var $grid = $("#list");
$grid.jqGrid({
url: '#Url.Action("GetData", "Home")',
datatype: "json",
mtype: 'Get',
colNames: ['Id', 'Name', 'Sex', 'Address'],
loadonce: true,
height: '100%',
autowidth: true,
colModel: [
{ name: 'empid', index: 'empid', editable: true, editrules: { required: true}},
{ name: 'fname', index: 'fname', editable: true, editrules: { required: true}}, //currently these are texbox, but I want this to be label which gets filled based on the empid
{ name: 'lname', index: 'lname', editable: true, editrules: { required: true}},
{ name: 'address', index: 'address', editable: true, editrules: { required: true}}
],
cmTemplate: { autoResizable: true, editable: true },
autoResizing: { compact: true, resetWidthOrg: true },
iconSet: "fontAwesome",
rowNum: 10,
rowList: [5, 10, 20, "10000:All"],
viewrecords: true,
autoencode: true,
sortable: true,
pager: true,
rownumbers: true,
sortname: "uid",
sortorder: "desc",
pagerRightWidth: 150,
inlineEditing: {
keys: true
},
formEditing: {
reloadGridOptions: { fromServer: true },
reloadAfterSubmit: true,
width: 310,
closeOnEscape: true,
closeAfterEdit: true,
closeAfterAdd: true,
closeAfterDelete: true,
savekey: [true, 13]
}
caption: "MyData"
}).jqGrid("navGrid")
.editGridRow("new", properties);
});
Updated:
If there is also option to use onkeyup, mouseover etc on the textbox so that I can validate whats entered in the textbox and then also update other textbox based on this value
I have done this by using keyup event instead of using autocomplete.
Relevant code as below:
colModel: [
{
name: 'empid', index: 'empid', editable: true, , editrules: { required: true },
editoptions:
{
dataEvents: [
{
type: 'keyup',
fn: function (e) {
$.ajax({
url: //call to my method in my mvc controller,
data: "empid=" + $(this).val(),
type: "GET",
success: function (data) {
//validate and populate other fields here
}
else {
}
},
error: function (passParams) {
// code here
}
});
}
}
]
}
]

jqgrid v5.2.1 with subgrid and local data CRUD operations

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.

How to show subgrid in jqgrid in ASP.NET MVC 5?

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.

change searchoptions in jqgrid toolbar filter with setColProp

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.

how to add refresh button to jqgrid toolbar?

i am working on jqgrid. i want to add refresh button to jqgrid toolbar to refresh the grid.
here is my js code:
jQuery(document).ready(function () {
var grid = jQuery("#gridemp");
grid.jqGrid({
url: '/Admin/GetTimeInOut_ForAdmin',
datatype: 'json',
mtype: 'Post',
height: '100%',
multipleSearch: false,
rownumbers: true,
//formatCell: emptyText,
colNames: ['User', 'Date', 'TimeIn', 'TimeOut'],
colModel: [
{ name: 'User', index: 'User', align: "center", sorttype: 'text', resizable: true, editable: false },
{ name: 'Date', index: 'Date', align: "center", sorttype: 'text', resizable: true, editable: false, searchoptions: { dataInit: function (el) { $(el).datepicker({ dateFormat: 'mm/dd/yy' }).change(function () { $('#gridemp')[0].triggerToolbar(); }); } } },
{ name: 'TimeIn', index: 'TimeIn', align: "center", sorttype: 'text', resizable: true, editable: false },
{ name: 'TimeOut', index: 'TimeOut', align: "center", sort:false, resizable: true, editable: false }
],
//shrinkToFit: true,
// loadonce: false,
//ignoreCase: true,
width: '690',
pager: '#emppager',
caption: 'Employee Time IN/OUT',
rowNum: 10,
rowList: [10, 20, 50, 100],
viewrecords: true,
hidegrid: false,
}
);
grid.jqGrid('filterToolbar',{ stringResult: true, searchOnEnter: true, defaultSearch: 'cn' });
grid.jqGrid('navGrid', '#emppager',
{ resize: false, add: false, search: false, del: false, refresh: false, edit: false, alerttext: 'Please select one user' }
).jqGrid('navButtonAdd', '#pager');
});
actually i need 2 refresh buttons one for to clear the search bar text boxes without refreshing the jqgrid, and one for refreshing the whole grid. i will mark your answer if it works for me. thanks in advance. happy coding :), if you the question is not clear please comment i will explain.
First of all it seems your code contains typing error: you use pager: '#emppager' during creating grid, in navGrid but not in navButtonAdd.
To add "standard" reload button which reset filter toolbar and reload the grid you need just remove refresh: false option.
To add custom clear filter you need call navButtonAdd in the way like below
.jqGrid("navButtonAdd", "#emppager", {
caption: "", // no text near the button
title: "Clear filters in toolbar without reloading of data",
buttonicon: "ui-icon-close", // an example of icon
onClickButton: function () {
this.clearToolbar(false); // don't reload grid
}
});
You can change icon used by Refresh button by usage refreshicon option (at the same place where you specify del, refresh, alerttext etc). Default value is refreshicon: "ui-icon-refresh". Moreover you can consider to use refreshstate: "current" (default is refreshstate: "firstpage").

Resources