jqGrid ignores first keystroke after showing alert/confirm dialog - javascript

i have a requirement to show a confirmation message before editing a cell. User can either choose to use a auto-calculated value or can enter new value in the Col 2. If user chose to use the auto-calculated value, next cell (Col 3) should be put in edit mode.
I am using code shown below, so when user tabs thru Col 1 to Col 2, it displays a confirmation dialog box. When user clicks Cancel on the dialog box, the focus remains in Col 2 and if user clicks on Ok focus is set to Col 3.
The problem here is that, after closing the dialog box, when i try to type in the textbox, the first keystroke is ignored and nothing happens. However subsequent keystrokes work fine.
Strange thing is that, if i click directly in Col 2, everything works fine (first keystroke is not ignored). Issue happens only when i navigate from Col 1 to Col 2 by pressing tab.
Please help me fix this issue.
$(gridId).jqGrid({
colNames: ["Id", "Name", "Col 1", "Col 2", "Col 3"],
colModel: [
{ name: "Id", index: "Id", hidden: true, key: true, formatter: 'text' },
{ name: "Name", index: "Name", width: '165px', align: 'left', resizable: false, editable: false, classes: 'non-editable', formatter: 'text' },
{ name: "Col1", index: "Col1", width: '60px' },
{ name: "Col2", index: "Col2", width: '60px' },
{ name: "Col3", index: "Col3", width: '60px' }
],
hidegrid: false,
rowNum: 50,
rowList: [10, 20, 50, 100],
scroll: true,
loadonce: true,
sortorder: "asc",
height: 370,
datatype: 'json',
viewrecords: true,
mtype: 'GET',
ignoreCase: true,
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
userdata: "userdata"
},
url: gridUrl,
editurl: '#',
cellEdit: true,
cellsubmit: 'clientArray',
footerrow: true,
multiselect: false,
//autowidth: true,
cmTemplate: {
//Default col model properties, if not using default, override in the colmodel
resizable: false,
edittype: "text", //for checkbox, override in the colmodel
align: "right",
editable: true,
formatter: 'number', //for text, override in the colmodel
formatoptions: { decimalSeparator: ".", thousandsSeparator: "", decimalPlaces: 1, defaultValue: '', align: "right" },
editrules: { number: true} //Setting numeric validation for all columns as all the editable columns are numbers
},
beforeEditCell: function (rowid, cellname, value, iRow, iCol) {
var grid = $(this);
if (prevCellName != cellname && cellname == "Col2") {
var autoCalculated = 123;
var response = confirm("The Col 2 auto-calculated value is " + autoCalculated + ". Would you like to use this value?");
if (response == true) {
setTimeout(function () {
grid.jqGrid('setCell', rowid, "Col2", autoCalculated);
}, 10);
setTimeout(function () {
grid.jqGrid('editCell', iRow, iCol + 1, true);
}, 20);
}
}
prevCellName = cellname;
}
});

Related

how to merge multiple columns into 1 column jqgrid

I have 5 columns that display different Levels from Level0 to Level4. I hav a requirement to show all these level columns into 1 main columns named Levels, i.e. 1 column name level having 5 sub columns named lv0, lv1... lv4?
I tried solution provided in How to display multiple values in same column in jqgrid
but it is merging the values and hence mismatch of values with the header.
Is there a way to merge columns into 1 columns and not just the values?
below is the colModel and ColNames for the jqgrid:
'detailViewcolNames': [
"Sub Project(s)",
"LV0",
"LV1",
"LV2",
"LV3",
"LV4",
"Status",
"%Comp",
"%Weight",
"Wins",
"Attention",
"Escalation",
"Comments",
"Next Steps"
],
'detailGridcolModel': [{
name: 'name',
width: '15%',
index: 'name',
title: false,
resizable: false,
sortable: false,
formatter: function(cellvalue, options, rowObject) {
var cellHtml = "<span class='gridTitle'>" + cellvalue + "</span>";
return cellHtml;
},
unformat: function(cellvalue, options, rowObject) {
return cellvalue;
},
}, {
name: "Status",
index: 'Status',
width: '5%',
title: false,
resizable: false,
sortable: false,
jsonmap: "from[Subtask].to.Status",
formatter: function(cellvalue, options, rowObject) {
return pathProjectModel.getStatusMapImage(cellvalue, options, rowObject);
}
}, {
name: 'LV0',
width: '5%',
title: false,
resizable: false,
sortable: false,
}, {
name: 'LV1',
width: '5%',
title: false,
resizable: false,
sortable: false,
}, {
name: 'LV2',
width: '5%',
title: false,
resizable: false,
sortable: false,
}, {
name: 'LV3',
width: '5%',
title: false,
resizable: false,
sortable: false,
}, {
name: 'LV4',
width: '5%',
title: false,
resizable: false,
sortable: false,
}, {
name: 'attribute[Percent Complete]',
index: 'attribute[Percent Complete]',
width: '10%',
title: false,
resizable: false,
sortable: false,
jsonmap: "attribute[Percent Complete]",
}, {
name: 'Weight',
index: 'Weight',
width: '10%',
title: false,
resizable: false,
hidden: true,
sortable: false,
jsonmap: "Weight",
}, {
name: "Win",
index: "Win",
width: '15%',
title: false,
resizable: false,
sortable: false,
jsonmap: "Win",
formatter: function(cellvalue, options, rowObject) {
var cellHtml = pathProjectModel.multiValuesFormatter(cellvalue, options, rowObject);
return cellHtml;
}
}, {
name: "Attention",
index: "Attention",
width: '15%',
title: false,
resizable: false,
sortable: false,
formatter: function(cellvalue, options, rowObject) {
var cellHtml = pathProjectModel.multiValuesFormatter(cellvalue, options, rowObject);
return cellHtml;
},
jsonmap: "Attention"
}, {
name: 'Escalation',
index: 'Escalation',
width: '15%',
title: false,
resizable: false,
sortable: false,
formatter: function(cellvalue, options, rowObject) {
var cellHtml = pathProjectModel.multiValuesFormatter(cellvalue, options, rowObject);
return cellHtml;
},
jsonmap: "Escalation"
}, {
name: 'Comments',
index: 'Comments',
width: '15%',
title: false,
resizable: false,
sortable: false,
formatter: function(cellvalue, options, rowObject) {
var cellHtml = pathProjectModel.multiValuesFormatter(cellvalue, options, rowObject);
return cellHtml;
},
jsonmap: "Comments"
}, {
name: 'Next Steps',
index: 'Next Steps',
width: '15%',
title: false,
resizable: false,
sortable: false,
formatter: function(cellvalue, options, rowObject) {
var cellHtml = pathProjectModel.multiValuesFormatter(cellvalue, options, rowObject);
return cellHtml;
},
jsonmap: "Next Steps"
}, ]
below is the Sample data. Here id property contains rowid
responseObj = {
id: "2432.XXXXXXXXXXXXXX",
"name": "project Name",
"Status": "On Track",
"LV0": "100",
"LV1": "90.0",
"LV2": "0.0",
"LV3": "12.0",
"LV4": "",
"attribute[Percent Complete]": "0.0",
"Weight": "30.0",
"Win": [
["fasdfgasdf"]
],
"Attention": [
["sdfasdga"]
],
"Escalation": [
["fedgsdshsdfh"]
],
"Comments": [
["dgdfhdfhdfuiopjnjkn"]
],
"Next Steps": [
["vbmcbvndfgec"]
]
}
If you really need to use old jqGrid 4.6.0 and to use datatype: "local" then you should change the format of input data. It's the way, which I would recommend you. Alternatively you could try to use datatype: "jsonstring" and provide the input data via datastr parameter instead of data. You will have to change jsonmap defined as function to read the input data. In any way you have to fix the values of name properties, which you use.
The name property of jqGrid will be used to generate id attributes of some internal elements. HTML5 don't allow to use spaces in id (see here the statement: "The value must not contain any space characters"). Additionally the name will be used in different CSS selectors and you can have problems in case of usage names, which contains [ or ] (see [Percent Complete]).
You should not use formatter to build the value of "virtual" property from other existing properties. Instead of that you should use jsonmap or "pre-process" the input data to set new property. If you do use custom formatter, then it's strictly recommended to specify unformat callback too.
The practical example is following. Let us you have input data with numeric the properties price and tax any you want to display the corresponding columns and total_price additionally, which build as the sum of price and tax. The recommended way: you should fill total_price once or to use jsonmap defined as function to calculate the sum of price and tax. After that you can use predefined formatter: "currency" to display the value. I think that you should generate one additional column from lv0, lv1... lv4 in exact the same way.
Additionally, I want to remark that the usage of old jqGrid 4.6 now is dangerous, because it's not supported since 2014. To be exact, there are not exist "jqGrid" product at all. There are exist two main forks of the old jqGrid: "free jqGrid", which I develop, and which current version is 4.14.0 and commercial "Guriddo jqGrid JS", which current version is 5.2.1. I strictly recommend you to migrate to one from the currently developed and supported products. I remind you about the problem described in the answer. The version of jqGrid, existing at the time, displayed wrong grid in the new version of Chrome. Google publish new version every 1.5-2 months. It could be that jqGrid 4.6 (and your existing web application) will display wrong grids in the next version of Chrome/Firefox or any other web browser. The only solution of the problem will be migration to another version of jqGrid, with the fixed code. If you continue to use jqGrid 4.6 then you will have to implement the fix yourself. If you would use the current version of "free jqGrid" or "Guriddo jqGrid JS" then the fix will implement developers of the corresponding product and you will need just to download the new version from GitHub.

Add/edit/delete a row in free jqGrid

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).

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.

jqGrid SetCell and SaveCell blanking out the cell after closing a modal dialog

I have a cell-editable jqgrid with a column that has an edittype of 'button'. When the cell is clicked, the button appears. when the button is clicked, a modal dialog appears allowing the user to select a value from a grid. This is all working fine.
When the user clicks the 'OK' button on the modal dialog after picking a value from the grid, I'd like to set the cell value with the value selected by the user and save the cell.
Instead of setting and saving the cell value, the cell is blanked out. Not sure why.
Here is the relevant jqGrid / modal dialog code:
// global variables
base.selectedCode = null;
base.liaGridSelectedId = null;
base.liaGridSelectedICol = null;
base.liaGridSelectedIRow = null;
$("#liaGrid").jqGrid({
datatype: "local",
data: base.liaGridData,
cellEdit: true,
cellsubmit: 'clientArray',
height: 140,
colNames: ['ID', 'Class Code', 'State', 'Location Type'],
colModel: [
{ name: 'id', index: 'id', width: 90, sorttype: "int", editable: false, hidden: true },
{ name: 'ClassCode', index: 'ClassCode', width: 90, sortable: false, editable: true, edittype: "button",
editoptions: {
dataEvents: [{
type: 'click',
fn: function (e) {
e.preventDefault();
var rowid = $('#liaGrid').jqGrid('getGridParam', 'selrow');
base.liaGridSelectedId = parseInt(rowid);
$('#class-dialog').dialog('option', { width: 100, height: 200, position: 'center', title: 'Pick a Class' });
$('#class-dialog').dialog('open');
return true;
}
}]
}
},
{ name: 'LocationType', index: 'LocationType', width: 90, sortable: false, editable: true, edittype: "select", editoptions: { value: "0:;1:Rural;2:Suburban;3:Urban"} }
],
caption: "Liability Model",
beforeEditCell: function (rowid, cellname, value, iRow, iCol) {
base.liaGridSelectedICol = iCol;
base.liaGridSelectedIRow = iRow;
}
});
var infoDialog = $('#class-dialog').dialog({
autoOpen: false,
modal: true,
show: 'fade',
hide: 'fade',
resizable: true,
buttons: {
"Ok": function () {
if (base.selectedCode != null) {
$("#liaGrid").jqGrid('setCell', base.liaGridSelectedId, 'ClassCode', base.selectedCode);
$("#liaGrid").jqGrid('saveCell', base.liaGridSelectedIRow, base.liaGridSelectedICol);
$(this).dialog("close");
}
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
As seen above, I'm attempting to use jqGrid('setCell') and jqGrid('saveCell') to update and save the contents of the cell. Not sure why this fails to succeed.
I got this to work in case anyone encounters a similar issue. I had to add the afterSaveCell handler to the grid:
afterSaveCell: function (rowid, name, val, iRow, iCol) {
if (base.liaGridSelectedICol == 1) {
$("#liaGrid").jqGrid('setRowData', rowid, { ClassCode: base.selectedCode });
}
}
FYI - base.selectedCode is set in the modal.
Odd thing, this only worked after calling the setCell and saveCell methods. Without these unsuccessful calls to set and save at the cell level, the above handler was not called.
If someone has a more appropriate approach to solving this problem I'd like to hear it.
Thanks

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');
}
}

Categories

Resources