Add/edit/delete a row in free jqGrid - javascript
I am using free jqGrid 4.12.1. I want to add, edit and delete rows in the grid and wish to make server side calls for each operation.
I have added editurl and 'actions' formatter as below,
{
name: "actions",
width: 100,
formatter: "actions",
formatoptions: {
keys: true,
editOptions: {},
addOptions: {},
delOptions: {}
}
}
I am adding 'inlineNav' as below,
$("#itemList").jqGrid('inlineNav',"#itemListPager",
{
edit: true,
add: true,
del: true,
search: true,
searchtext: "Search",
addtext: "Add",
edittext: "Edit",
deltext: "Delete"
},
{
closeOnEscape: true, //Closes the popup on pressing escape key
reloadAfterSubmit: true,
drag: true,
url: "${pageContext.request.contextPath}/billing/saveItem",
errorfunc: function (rowId, resp) {
alert(resp);
},
afterSubmit: function (response, postdata) {
if (response.responseText == "") {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid'); //Reloads the grid after edit
return [true, '']
}
else {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid'); //Reloads the grid after edit
return [false, response.responseText]//Captures and displays the response text on th Edit window
}
},
editData: {
EmpId: function () {
var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
return value;
}
}
},
{
closeAfterAdd: true, //Closes the add window after add
url: "${pageContext.request.contextPath}/billing/saveItem",
afterSubmit: function (response, postdata) {
if (response.responseText == "") {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
return [true, '']
}
else {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
return [false, response.responseText]
}
}
},
{ //DELETE
closeOnEscape: true,
closeAfterDelete: true,
reloadAfterSubmit: true,
url: "${pageContext.request.contextPath}/billing/saveItem",
drag: true,
afterSubmit: function (response, postdata) {
if (response.responseText == "") {
$("#itemList").trigger("reloadGrid", [{ current: true}]);
return [false, response.responseText]
}
else {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');
return [true, response.responseText]
}
},
delData: {
EmpId: function () {
var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
return value;
}
}
},
{//SEARCH
closeOnEscape: true
}
);
The 'inlineNav' added above has no effect because no server side call is made on adding a new row or deleting existing row. The server side call is made only in case of edit, and that call too does not happen through 'inlineNav' code above. Because even if i remove 'inlineNav' code the server side call is still made to the 'editurl'.
So how can i make server side calls on adding/editing/deleting rows and also pass parameters to these calls. I will really appreciate if someone can point me to a working example somewhere. Thanks
UPDATE:-
I have removed 'actions' formatter and modified code to look as below,
<script type="text/javascript">
var dataGrid = $('#itemList');
var firstClick = true;
$(document).ready(function () {
$('#action').click(function () {
if (!firstClick) {
$("#itemList").setGridParam({datatype:'json'}).trigger("reloadGrid");
}
firstClick = false;
$("#itemList").jqGrid({
url: "${pageContext.request.contextPath}/billing/medicines",
datatype: "json",
//styleUI : 'Bootstrap',
mtype: "POST",
autowidth: true,
shrinkToFit: true,
sortname: "Id",
sortorder: "asc",
loadBeforeSend: function(jqXHR) {
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
},
postData: {
},
loadError: function (jqXHR, textStatus, errorThrown) {
alert('HTTP status code: ' + jqXHR.status + '\n' +
'textStatus: ' + textStatus + '\n' +
'errorThrown: ' + errorThrown);
alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText);
},
colNames: ["Id", "Item Type", "Item Code", "Unit", "Stock", "Batch No.", "Expiry Date", "Quantity Per Unit", "Price"],
colModel: [
{ name: "itemId", width: 35, align: "left", sorttype:"int", search: false},
{ name: "itemType", width: 100, align: "left", editable: true},
{ name: "itemCode", width: 120, align: "left", editable: true},
{ name: "unit", width: 70, align: "left", search: false, editable: true},
{ name: "availableQuantity", width: 55, align: "left", search: false, formatter: "number", editable: true},
{ name: "batchNumber", width: 80, align: "left", search: false, editable: true},
{ name: "expiryDate", width: 80, align: "left", search: false, sorttype: "date", editable: true, formatoptions: {srcformat:'d/m/Y', newformat:'d/m/Y'}},
{ name: "quantityPerUnit", width: 80, align: "left", search: false, formatter: "number", editable: true},
{ name: "price", width: 55, align: "left", search: false, formatter: "number", editable: true}
],
pager: "#itemListPager",
rowNum: 50,
rowList: [50, 100, 150, 200],
rownumbers: true,
rownumWidth: 25,
sortname: "id",
sortorder: "desc",
viewrecords: true,
height: '100%',
loadonce: true,
//gridview: true,
autoencode: true,
editurl: "${pageContext.request.contextPath}/billing/saveItem",
caption: "Item List",
ondblClickRow: function(rowId){}
}).navGrid('#itemListPager',{add:false,edit:false,del:true});
$("#itemList").jqGrid('filterToolbar', {autoSearch: true, stringResult: true, searchOnEnter: false, defaultSearch: 'cn'});
$("#itemList").jqGrid('gridResize', { minWidth: 450, minHeight: 150 });
var saveparameters = {
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/saveItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var editparameters = {
"keys" : false,
"oneditfunc" : null,
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/editItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var parameters = {
edit: true,
editicon: "ui-icon-pencil",
add: true,
addicon:"ui-icon-plus",
save: true,
saveicon:"ui-icon-disk",
cancel: true,
cancelicon:"ui-icon-cancel",
addParams : saveparameters,
editParams : editparameters
};
$("#itemList").jqGrid('inlineNav',"#itemListPager", parameters);
});
});
</script>
The sample json dada is as,
[
{"itemDetailId":1,"itemId":1,"itemType":"Medicine","itemCode":"Aler-Dryl","itemDesc":"Aler-Dryl","batchNumber":"batch1","expiryDate":"18/02/2017","unit":"tablet","subUnit":"tablet","availableQuantity":120.0,"quantityPerUnit":60.0,"price":122.0},
{"itemDetailId":2,"itemId":2,"itemType":"Medicine","itemCode":"Benadryl","itemDesc":"Benadryl","batchNumber":"batch1","expiryDate":"18/02/2017","unit":"ml","subUnit":"ml","availableQuantity":60.0,"quantityPerUnit":120.0,"price":90.0}
]
Now the url specified in editparameters and saveparameters is getting invoked on editing and adding a row respectively.
Please suggest if above approach is a good one. Also how can we set a request header before edit or save data is posted to server. And i can not find anything like deleteparameters similar to editparameters and saveparameters so that i can use delete specific parameters.
UPDATE 2:-
I could successfully set a request header before server side code is invoked on add/edit row using following code,
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
}});
UPDATE 3:-
Cleaned up code as per Oleg's suggestions as below. But in the strict mode i am getting JS error now - "Uncaught ReferenceError: saveparameters is not defined"
<script type="text/javascript">
$(document).ready(function () {
"use strict";
var dataGrid = $('#itemList');
var firstClick = true;
$('#action').click(function () {
if (!firstClick) {
$("#itemList").setGridParam({datatype:'json'}).trigger("reloadGrid");
}
firstClick = false;
$("#itemList").jqGrid({
url: "${pageContext.request.contextPath}/billing/medicines",
datatype: "json",
mtype: "POST",
autowidth: true,
loadBeforeSend: function(jqXHR) {
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
},
colNames: ["Id", "Item Type", "Item Code", "Unit", "Stock", "Batch No.", "Expiry Date", "Quantity Per Unit", "Price"],
colModel: [
{ name: "itemId", width: 35, align: "left", sorttype:"int", search: false, editable: false, key: true},
{ name: "itemType", width: 100, align: "left"},
{ name: "itemCode", width: 120, align: "left"},
{ name: "unit", width: 70, align: "left", search: false},
{ name: "availableQuantity", width: 55, align: "left", search: false, formatter: "number",},
{ name: "batchNumber", width: 80, align: "left", search: false},
{ name: "expiryDate", width: 80, align: "left", search: false, sorttype: "date", formatoptions: {srcformat:'d/m/Y', newformat:'d/m/Y'}},
{ name: "quantityPerUnit", width: 80, align: "left", search: false, formatter: "number"},
{ name: "price", width: 55, align: "left", search: false, formatter: "number"}
],
cmTemplate: {editable: true},
pager: true,
rowNum: 50,
rowList: [50, 100, 150, 200],
rownumbers: true,
rownumWidth: 25,
sortname: "itemType",
sortorder: "asc",
forceClientSorting: true,
viewrecords: true,
height: '100%',
loadonce: true,
//gridview: true,
autoencode: true,
editurl: "${pageContext.request.contextPath}/billing/saveItem",
caption: "Item List"
//ajaxRowOptions: { beforeSend: myTokenSetting }, loadBeforeSend: myTokenSetting where var myTokenSetting = function(jqXHR) { jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val()); }
}).navGrid({add:false,edit:false,del:true});
$("#itemList").jqGrid('filterToolbar', {autoSearch: true, stringResult: true, searchOnEnter: false, defaultSearch: 'cn'});
$("#itemList").jqGrid('gridResize', { minWidth: 450, minHeight: 150 });
var saveparameters = {
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/saveItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var editparameters = {
"keys" : false,
"oneditfunc" : null,
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/editItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var parameters = {
edit: true,
editicon: "ui-icon-pencil",
add: true,
addicon:"ui-icon-plus",
save: true,
saveicon:"ui-icon-disk",
cancel: true,
cancelicon:"ui-icon-cancel",
addParams : saveparameters,
editParams : editparameters
};
$("#itemList").jqGrid('inlineNav',parameters);
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
alert('Before Row Send');
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
}});
});
});
</script>
You should examine the options of inlineNav to find out that you use absolutely wrong options:
jQuery("#grid_id").jqGrid('inlineNav', pagerid, parameters);
where parameters have the form
{
edit: true,
editicon: "ui-icon-pencil",
add: true,
addicon: "ui-icon-plus",
save: true,
saveicon: "ui-icon-disk",
cancel: true,
cancelicon: "ui-icon-cancel",
addParams: {useFormatter : false},
editParams: {}
}
You use the options of another method navGrid
jQuery("#grid_id").jqGrid('navGrid', '#gridpager', {parameters},
prmEdit, prmAdd, prmDel, prmSearch, prmView);
which allows to use form editing.
You wrote that you want to use both formater: "actions" andinlineNav. Thus you would have to provide some options of inline editing twice. I would recommend you to read [the wiki article](https://github.com/free-jqgrid/jqGrid/wiki/New-style-of-usage-options-of-internal-methods). It describes the problems with the usage of form editing usingformatter: "actions"andnavGridtogether. The usage of inline editing have very close problems. You will have to provideaddParamsandeditParamsproperties ofinlineNavand the corresponding options offormatter: "actions"` (see here). To make the code more readable and simple free jqGrid provides another form of editing options.
You can specify all inline editing options inside of inlineEditing option of jqGrid, additional specific options of inlineNav method (if required) in navOptions or in inlineNavOptions, the options of Delete operation in formDeleting and so on. Moreover reloadGrid have the option fromServer: true to restore the original value of datatype ("json", "jsonp", "xml", ...) which you used. You can use reloadGridOptions: { fromServer: true } option of form editing or formDeleting to force reloading from the server.
Moreover your existing code contains many very suspected parts with _id and EmpId. I would strictly recommend you to include the example of format of input JSON data which you use to fill the grid. If you want to use EmpId as the name of rowid why you use _id instead? The code fragment like
EmpId: function () {
var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
return value;
}
shows that the current rowid seems be wrong and _id column contains correct information which you need as rowid under the name EmpId.
You can for example use prmNames: { id: "EmpId"} and to add key: true to the column _id. The property key: true in the column _id will inform jqGrid to use the value from the column _id as the rowid and prmNames: { id: "EmpId"} will rename default id property used in Edit and Delete to EmpId. Thus jqGrid will automatically send EmpId parameter with the value from _id column during Delete and Edit operations to the server.
Probably you can remove unneeded column _id from the grid too (at least if you hold the column hidden), but I need to see input data of jqGrid to say you exact options of jqGrid which you can use.
I'm sure that you can essentially reduce your existing code and make it more readable using free jqGrid options, but you have to review your existing code carefully. I suggest you to start with the usage of correct rowid and elimination of all hidden columns which you use. Free jqGrid provides additionalProperties feature which structure is very close to the structure of colModel, but the corresponding properties of input data will be saved in the local data only and not placed in DOM of the table. I can explain all more clear if you would post your existing colModel, jsonReader and example of JSON response returned from the server (1-2 rows of data with dummy data would be enough).
Related
extra parameters in delete action of JQgrid
I want to pass extra parameters like action=delete jQuery(grid_selector).jqGrid({ url: '<?php echo A_CLIENT_URL?>/getClientAppointment/<?= $userdata['U_ID']?>', datatype: "json", mtype: 'POST', colNames:['Actions','Service Provider','Service','Created Date','Status','',], height: 250, colModel:[ {name: 'myac', index: '', width: 80, fixed: true, sortable: false, resize: false, formatter: 'actions', formatoptions: { keys: true, delOptions: {recreateForm: true, beforeShowForm: beforeDeleteCallback}, editbutton:false, } }, {name:'USERNAME',index:'USERNAME', width:100,}, {name:'S_BUSINESSNAME',index:'S_BUSINESSNAME', width:100,}, {name:'A_CREATED_DATE',index:'A_CREATED_DATE', width:100,}, {name:'A_STATUS',index:'A_STATUS', width:100,}, {name:'A_ID',index:'A_ID',hidden:true,key:true}, ], using this code I get ope=del and id default but I want more extra parameters, who knows this help me out.
try this code {name: 'myac', index: '', width: 80, fixed: true, sortable: false, resize: false, formatter: 'actions', formatoptions: { keys: true, delOptions: {recreateForm: true, beforeShowForm: beforeDeleteCallback,url: 'abc.php?action=delete'}, editbutton:false, } },
delOptions allows you to specify any option or callback of delGridRow. So you can use for example delData: { action: "delete" } You should include the value inside of formatoptions.delOptions which you use.
One example that works for me: ... $('#jqGrid').navGrid('#jqGridPager', { edit: true, add: true, del: true, search: false, refresh: false, view: false, position: "left", cloneToTop: false }, { editCaption: "Editar", editData: ... }, { editCaption: "Delete", width: "500", delData: { your_variable: function() { id = $('#jqGrid').jqGrid('getCell', $('#jqGrid').jqGrid('getGridParam', 'selrow'), 'login_id'); return id; }, another_variable: function() { return "something..."; } }, ... } ... 'login_id' is variable that was defined in colModel. 'your_variable' or 'another_variable' is variables that you will take in your php script, for example. ( $_POST["another_variable"] ) That's it.
jQGrid - "jpg1" instead of proper id number
I'm loading local file (I'm parsing csv file into json and then transfer the array to jqGrid). Table generated through jqGrid should allow user to modify, add and delete the data in the grid. Everything seemed to work perfectly until I wanted to add a row to my grid. One of the columns had a parameter key = true which is my id for the rows. When I try to add new row, the grid changes my id into jpg1. The others columns are fine. Below is the code I'm using: $("#jqGrid").jqGrid({ datatype: "local", data: myData, editurl: "clientArray", colModel: [ { label: 'Kod', name: 'Kod', width: 60, editable: true, key: true, sorttype: 'number' }, { label: 'Firma', name: 'Firma', width: 120, editoptions: { size: 40, sopt:['cn'] }, editable: true, sorttype: 'string' }, { label: 'Adres', name: 'Adres', width: 80, editoptions: {size: 40}, editable: true }, { label: 'Miasto', name: 'Miasto', width: 80, editoptions: { size: 40, sopt:['cn'] }, editable: true } ], height: 'auto', autowidth: true, shrinkToFit: false, forceFit: false, autoencode: true, viewrecords: true, caption: "Title", pager: "#jqGridPager", sortable: true, ignoreCase: true, sortname: 'Kod', sortorder: 'asc', rowNum: 5, rowList: [5, 10, 20, "10000:All"], ondblClickRow: function(rowid) { $("#jqGrid").jqGrid('editGridRow', rowid, { editCaption: "The Edit Dialog", zIndex:100, recreateForm: true, closeAfterEdit: true, width: 900, errorTextFormat: function (data) { return 'Error: ' + data.responseText } }); } }); $('#jqGrid').jqGrid('navGrid',"#jqGridPager", { edit: true, add: true, del: true, search: false, refresh: true, view: true, cloneToTop: true}, // options for the Edit Dialog { editCaption: "The Edit Dialog", zIndex:100, recreateForm: true, closeAfterEdit: true, reloadAfterSubmit: true, width: 900, errorTextFormat: function (data) { return 'Error: ' + data.responseText } }, // options for the Add Dialog { width: 900, zIndex:100, closeAfterAdd: true, recreateForm: true, reloadAfterSubmit: true, errorTextFormat: function (data) { return 'Error: ' + data.responseText } }, // options for the Delete Dialog delSettings, // options for the Search Dialog { zIndex:100 }, // options for the View Dialog { width: '100%' }); I'm attaching a screenshot that shows a problem: Photo The data I use is a file parsed into JSON array via Papaparse.js plugin. EDIT: I've added the test data if somebody would like to test the code. var myData = []; myData.push( { Kod: 1.1, Firma: 'Hutchinson', Adres: '5th Avenue', Miasto: 'Wroclaw' }, { Kod: 2.1, Firma: 'BMW', Adres: '6th Avenue', Miasto: 'Warsaw' }); I will be grateful for any help.
If you need the grid only for local editing, you can consider just remove key: true property to solve the problem. It's the way, which I would recommend you. You can include id property in the input data which will be used as value of rowid (id of <tr> elements). Alternatively you can change the block "options for the Add Dialog" to the following // options for the Add Dialog { width: 900, zIndex:100, closeAfterAdd: true, recreateForm: true, reloadAfterSubmit: true, onclickSubmit: function (options, postdata, frmoper) { // save Kod in some other parameter return {myKod: postdata.Kod}; }, afterSubmit: function (jqXHR,postdata, frmoper) { // restore the correct value postdata.Kod = postdata.myKod; // inform jqGrid that it was not an error return [true]; } }, You still don't would be able to change the id of the row in the way. By the way you wrote that you use jqGrid 4.7.1. I want remind you that jqGrid 4.7.0 is the last version which is free. It's the reason why I started free jqGrid project which still free. You can get it here (see readme and wiki). The demo shows an example of the above code fixes using free jqGrid 4.8.
Javascript variable into postdata of jqGrid
Right now I have this postData: { search: function() { return $("#search").val(); },}, I then have jQuery function above the jqGrid function that performs some logic and produces a string variable. Right now I am just taking that variable and setting the value of the search element like this: $("#startSearch").click(function() { $("#search").val(searchVal); $("#grid").trigger("reloadGrid"); }); This works but I was hopping to do this differently. I want to just pass the seachVal variable that my jQuery function produces right into the postdata. I tried it like this but its not working postData: { search: function() { return searchVal; },}, I'm getting an error that says searchVal is not defined. I made sure that the searchVal variable is global but it is still not working. Is this possible or am I just looking at this wrong? Any help would be great. Thanks UPDATE: Here is a stripped down version of the page: <fieldset> <input type='text' id='search' /> <button type='button' id='startSearch'>Search</button> </fieldset> <script type="text/javascript"> $(function(){ $("#startSearch").click(function() { serchVal = 'transID > "5"'; $("#search").val(serchVal); $("#grid").trigger("reloadGrid"); }); $("#list").jqGrid({ url:'data.cfc?method=gridData', datatype: 'json', mtype: 'POST', jsonReader : { root: "rows", page: "currentpage", total: "totalpages", records: "totalrecords", repeatitems: false, id: "0", }, postData: { search: function() { return $("#search").val(); },}, colModel :[ {name:'transid', label:'Trans ID', width:60}, {name:'companyname', label:'Company Name', width:245}, {name:'companycode', label:'Company Code', width:245}, {name:'datasource', label:'Datasource', width:245} ], pager: '#pager', rowList:[10,50,100], rowNum:'10', height:221, sortname: 'transid', sortorder: 'asc', viewrecords: true, gridview: true, caption: 'Get Trans', altRows: false, autowidth: true, forceFit: true, rownumbers: true, scroll: false, sortable: true }); $("#list").jqGrid('navGrid','#pager',{edit:false,add:false,del:false,search:false,view:true}); }); </script> <table id="grid"></table> <div id="pager"></div>
I suppose the problem exist just because you didn't declared the variable serchVal (you means probably searchVal). You can try to modify the code to the following $(function () { var searchVal = ''; $("#startSearch").click(function () { searchVal = 'transID > "5"'; $("#grid").trigger("reloadGrid"); }); $("#list").jqGrid({ url: 'data.cfc?method=gridData', datatype: 'json', mtype: 'POST', jsonReader : { page: "currentpage", total: "totalpages", records: "totalrecords", repeatitems: false, id: "0" }, postData: { search: function () { return searchVal; }}, colModel: [ {name: 'transid', label: 'Trans ID', width: 60}, {name: 'companyname', label: 'Company Name', width: 245}, {name: 'companycode', label: 'Company Code', width: 245}, {name: 'datasource', label: 'Datasource', width: 245} ], pager: '#pager', rowList: [10, 50, 100], rowNum: 10, height: 221, sortname: 'transid', viewrecords: true, gridview: true, caption: 'Get Trans', autowidth: true, rownumbers: true, sortable: true }).jqGrid('navGrid', '#pager', {edit: false, add: false, del: false, search: false, view: true}); }); After that you can remove <input type='text' id='search' />.
Why don't you just wrap your logic in a function function SomeLogic() { return("some logic here!"); } which is going to be called like this: postData: { search: function() { return SomeLogic() } }, so you just have to reload the grid $("#startSearch").click(function() { $("#grid").trigger("reloadGrid"); }); obviously your function SomeLogic can just return searchVal function SomeLogic() { return(searchVal); }
Can't get saveRow aftersavefunc or successFunc to work
I've got some code that, when switching which row is selected, it triggers a save of the previously selected row. The row is being successfully saved without any problem, however the successfunc isn't being called at all - my console.log output never shows up, and the code in this function isn't being run. I also tried specifying the function as the aftersavefunc, but couldn't get that to work either. Seems like a simple syntax problem, but I can't quite get it right. Am I not specifying this function properly? As a side note, I realize that reloading the entire grid after a row save seems like overkill, but in the context of where this particular piece of code is, within the larger structure of my app, this snippet of code is a special case. The full jqGrid code is: var lastSelectedMainGridRowID = 0; var lastSelectedSubGridRowID = 0; var translationsFeed = "/update/translations/ajax/translations_feed.php"; var translationsEdit = "/update/translations/ajax/translations_edit.php"; var translationsSubGridFeed = "ajax/translations_subgrid_feed.php"; var translationsSubGridFeedEdit = "ajax/translations_subgrid_feed_edit.php"; $(document).ready(function () { $("#translationsList").jqGrid({ caption : "Translations", datatype : "xml", url : translationsFeed, editurl : translationsEdit, mtype : "get", pager : "#translationsPager", rowNum : 20, autowidth : true, sortname : "phrase", sortorder : "asc", viewrecords : true, multiselect : false, hidegrid : false, height : 300, altRows : true, rownumbers : true, toolbar : [false], loadComplete: function(data) { jQuery("#translationsList").setSelection (0, true); }, colNames : ["phrase_id", "translation_id", "language_cd", "Phrase", "Translation", "Modified", "Created", "Active"], colModel : [ { name : "phrase_id", index : "phrase_id", sortable : true, search : false, editable: true, edittype : "text", editrules: { edithidden: true }, hidden: true}, { name : "translation_id", index : "translation_id", sortable : false, search : false, editable: true, edittype : "text", editrules: { edithidden: true }, hidden: true}, { name : "language_cd", index : "language_cd", sortable : true, search : true, editable: true, edittype : "text", editrules: { edithidden: true, required : true }, hidden: true }, { name : "Phrase", width:200, index : "phrase", sortable : true, search : true, editable: true, edittype : "text", editrules: { required: true } }, { name : "Translation", width:200, index : "translation", sortable : true, search : true, editable: true, edittype : "text", editrules: { required: false } }, { name : "Modified", width:100, index : "modify_dt", sortable : true, search : true }, { name : "Created", width:100, index : "create_dt", sortable : true, search : true }, { name : "Active", width:20, index : "active", sortable : true, search : true, editable: true, edittype: "checkbox", editoptions: {value:"Yes:No", checked: true} } ], onSelectRow: function(id) { jQuery('#translationsList').jqGrid('saveRow', lastSelectedMainGridRowID); jQuery('#translationsList').jqGrid('editRow', id, true); lastSelectedMainGridRowID = id; }, subGrid: true, subGridRowExpanded: function(subgrid_id, row_id) { var subgrid_table_id; jQuery("#"+subgrid_id).html("<table id='"+subgrid_table_id+"' class='scroll'></table>"); jQuery("#"+subgrid_table_id).jqGrid({ url: translationsSubGridFeed + "?phrase_id=" + row_id, editurl: translationsSubGridFeedEdit, datatype: "xml", colNames: ['phrase_id', 'translation_id', 'language_cd', 'Translations', 'Language', 'Active'], colModel: [ {name:"phrase_id", index:"phrase_id", sortable: false, editable: true, edittype : "text", editrules: { edithidden :true }, hidden: true}, {name:"translation_id", index:"translation_id", sortable: false, editable: true, edittype : "text", editrules: { edithidden :true }, hidden: true}, {name:"language_cd", index:"language_cd", sortable: false, editable: true, edittype : "text", editrules: { edithidden :true }, hidden: true}, {name:"Translation", index:"translation", sortable: true, editable: true, edittype:"text", width:589}, {name:"Language", index:"language_disp", sortable: true, editable: false, width:250}, {name:"Active", index:"active", sortable: true, editable: true, edittype:"checkbox", editoptions:{value:"Yes:No", checked: true}, width:80} ], height: "100%", rowNum:20, sortname: 'language_cd', sortorder: "asc", onSelectRow: function(id) { jQuery("#"+subgrid_table_id).jqGrid('saveRow', lastSelectedSubGridRowID, function(response) { console.log("Data: " + response.responseText); return false; }); jQuery("#"+subgrid_table_id).jqGrid('editRow', id, true); lastSelectedSubGridRowID = id; } }); } }); Perhaps I don't need to use saveRow. In this case, what I'm doing is: When you click on a row, it becomes editable If you then click on a second row, the first row is saved (and no longer selected), and the new second row then becomes editable. Similar to saving a row "onBlur", so to speak.
I don't see the place of code where responseData variable are defined. The code responseData[0] should throw an exception, so the console.log("Data: " + responseData[0]); will not display any data. The line of code should be probably fixed as console.log("Server response: " + result.responseText); UPDATED: Without having the data for the both grid and for example the subgrid corresponds the first row one can't debug the code. Reading is not so effective. If you posted the test data (two XML files) I could try to localize the problem. An important error is that you only declare subgrid_table_id variable, but not assign a value for it. Typically one construct an unique id name subgrid_table_id based on the subgrid_id. For example var subgrid_table_id = subgrid_id+"_t"; instead of var subgrid_table_id; only. Nevertheless some things I find a little suspected: I don't understand why you return return false; from the successfunc. It means that you interpret the server response as an error and the normal actions on successful server response should be interrupted. I would recommend you additionally use errorfunc parameter of saveRow. In my server code the server always return error HTML status code in case of the server error. So I never need use successfunc and use aftersavefunc and errorfunc only. The subgrid has many column which already exist in the corresponding row of the parent grid. The potential problems here are not only spending of additional memory. You don't posted the grid data and so I don't know what values you use as rowids for grids. It is very important to have no id duplicates on the HTML page. So you should be careful in the subject. Why you need ? Probably you can just use extraparam parameter of saveRow and editRow instead of the usage of phrase_id, translation_id and language_cd hidden columns having editable: true, editrules: { edithidden :true }, hidden: true properties?
Passing dynamic params to delete url method in JQGrid
I am using a JQGrid witha json service to list all the database users membership information, so the url of the grid points to my json service and method. Everything is working fine so far, I can add and edit the users and amend data and it saves fine. However the delete of a DB user is another story as the Membership.DeleteUser takes the username as its parameter. The JQGrid only seems to pass editable params back when in add or edit mode. But when you're trying to delete it doesn't seem to allow any params to be returned which I find very odd. I have only just started using JQGrids so I could just be being thick :-). Please can anyone tell me how to accomplish this? I have the username as a column in the JQGrid itself. I have tried various things to date: url: 'misc/myservice.svc/AddEditDeleteGridRow?UserName=' + $('#MyGridTbl').getCell('selrow', 'UserName') in the delete section of the navGrid. I have also tried setting the URL in the select row event too but I found it required a reload to insert it into the grid and when this happens the selected row is lost and so defeats the object. I just need to be able to access/get the username inside the json service in order to pass it to Membership.DeleteUser. I have been searching the internet and can't seem to find anything. Here is the JQGrid I am using. There json service basically just has the GetData which returns JQGridJSONData (json object dataset) and AddEditDeleteGridRow methods in it, both are public. All the column data is being sent to the json service for the add and edit but nothing is being sent for the delete operation. Just to clarify I need the UserName on the server side in the json service. $('#MyGrid').jqGrid({ url: 'Misc/MyjsonService.svc/GetData', editurl: 'Misc/MyjsonService.svc/AddEditDeleteGridRow', datatype: 'json', colNames: ['UserId', 'UserName', 'Email Address', 'Password Last Changed', 'Locked'], colModel: [ { name: 'UserId', index: 'UserId', hidden:true, editable: true, editrules:{edithidden: true}}, { name: 'UserName', index: 'UserName', editable: true, width: 200, sortable: false, editrules: { required: true} }, { name: 'Email Address', index: 'Email', editable: true, width: 500, sortable: false, editrules: { email: true, required: true} }, { name: 'Password Last Changed', index: 'LastPasswordChangedDate', editable: false, width: 200, sortable: false, align: 'center' }, { name: 'Locked', index: 'IsLockedOut', sortable: false, editable: true, edittype: "checkbox", formatter: 'checkbox', align: 'center' } ], rowNum: 20, hidegrid: false, rowList: [20, 40, 60], pager: $('#MyGridPager'), sortname: 'UserName', viewrecords: true, multiselect: false, sortorder: 'asc', height: '400', caption: 'Database Users', shrinkToFit: false, onPaging: function(pgButton) { this.DBUserId = null; }, onSelectRow: function(Id) { if (Id && Id !== this.DBUserId) { this.DBUserSelect(Id); } }, loadComplete: function() { if (this.DBUserId) this.DBUserSelect(this.DBUserId, true); }, gridComplete: function() { var grid = $('#MyGrid'); var body = $('#AvailableDBUsersArea'); if ((grid) && (body)) { grid.setGridWidth(body.width() - 10); //keep the grid at 100% width of it's parent container body.bind('resize', function() { var grid = $('#MyGrid'); var body = $('#AvailableDBUsersArea'); if ((grid) && (body)) { grid.setGridWidth(body.width() - 2); } }); } } }).navGrid('#MyGridPager', { add: true, edit: true, del: true, refresh: false, search: false }, //general options { //Options for the Edit Dialog editCaption: 'Edit User', height: 250, width: 520, modal: true, closeAfterEdit: true, beforeShowForm: function(frm) { $('#UserName').attr('readonly', 'readonly'); }, beforeShowForm: function(frm) { $('#UserId').removeAttr('readonly'); }, beforeShowForm: function(frm) { $('#UserId').attr('readonly', 'readonly'); } }, { //Options for the Add Dialog addCaption: 'Add User', height: 250, width: 520, modal: true, closeAfterAdd: true, beforeShowForm: function(frm) { $('#UserName').removeAttr('readonly'); }, beforeShowForm: function(frm) { $('#UserId').removeAttr('readonly'); }, beforeShowForm: function(frm) { $('#UserId').attr('readonly', 'readonly'); } }, { //Delete options width: 350, caption: 'Delete User', msg: 'Are you sure you want to delete this User?\nThis action is irreversable.' }, {} //Search options );
There are some ways to add additional parameters to the Delete URL. It would be helpful to have the definition of the jqGrid, especially colModel. If you have a hidden column for example use can use hidden: true, editable: true, editrules: { edithidden: false }, hidedlg: true parameters. Then the hidden column would be not seen in the edit dialog, but the value of the column will be send. Another way can you choose if you need modify URL befor sending Delete request. You can define parameter of navGrid (see prmDel paremeter on http://www.trirand.com/jqgridwiki/doku.php?id=wiki:navigator#how_to_use) which can be like following { onclickSubmit: function(rp_ge, postdata) { rp_ge.url = 'misc/myservice.svc/AddEditDeleteGridRow?UserName=' + $('#MyGridTbl').getCell (postdata, 'UserName'); } }