I am using jqgrid in my application. We have functionality to do inline editing and saving.Now editing is working fine but the problem is with focus. When i click on edit button all cells are focused as expected and later i perform modifications and save, now focus from that row won't go off.
Code what I have tried is:
col name and col model code:
colNames: ['Id','Category Name','Category Label','Sort Order','Default','Active','Action'],
colModel: [
{name:'id', hidden : true, key : true},
{name:'CategoryName',index:'1',sortable:false, width: 343, editable: true,
editoptions:{size:"40",maxlength:"40"}
},
{name:'CatLable', index:'2',width:250, editable: true,edittype:"select",
editoptions:{value:"#{contexts.sessionContext.get('categoryLabel')}"}
},
{name:'DispOrder',index:'3',sortable:false, width: 100, align:"center", editable: true, editrules:{number:true},
editoptions:{size:"3",maxlength:"3"}
},
{name:'IsDefault',index:'4',sortable:false,width:60,search:false, resizable: false},
{name:'IsActive',index:'5',sortable:false,width:60,search:false, resizable: false},
{name: 'Action', index: '6', width: 85, sortable: false, formatter: 'actions',
}
}
],
format options code:
{name: 'Action', index: '6', width: 85, sortable: false, formatter: 'actions', formatoptions: {
// we want use [Enter] key to save the row and [Esc] to cancel editing.
url: "#myurl",
keys: true,
"delbutton":false,
onEdit:function(rowid) {
lastsel2 = rowid;
}
}
}
Reload grid code:
gridComplete: function(){
unblockB2BUI();
var recs = parseInt(jQuery("#categoryResults").getGridParam("records"),10);
if (recs == 0) {
jQuery("#logGridWrapper").hide();
jQuery(".noResMsg").show();
}
else {
jQuery(".noResMsg").hide();
jQuery('#logGridWrapper').show();
}
}
Grid for editing:
Grid when try to save the edited values:
Update:
Grid after saving and going to edit one more row:
Someone please suggest me how can I come out of the focus when i click on save icon.
Thanks in advance.
Related
Just putting in a new grid, and everything seems to be working well, except for one thing. Using basic inline, it is sending a new incorrect key value for the column I have set with key: true. This is an auto-increment column in the database, so I just don't want to send any data for this column when ADDING, only for edit or delete is that required.
It is posting a parameter: row_id => jqg3 for the new key column and messing up my server script. So because adding the new row will auto-increment the row_id col, I don't need to send this.
How do I stop the jqGrid from sending this (row_id) index column value when saving a new added row?
free-jqgrid version is 4.14.0
$('#accts').jqGrid({
url:'/phpAJAX/Master/master_grid_v1.php',
editurl:'/phpAJAX/Master/master_grid_v1.php',
height: 'auto',
shrinkToFit: false,
width: 'auto',
datatype: 'xml',
mtype: 'POST',
postData:{
'arg1':'bol_acct'
},
colNames:[
'row_id',
'Customer',
'Trucker',
'Acct Num'
],
colModel:[
{name: 'row_id', hidden: true, key: true},
{name:'Customer', align: "center", editable: true},
{name: 'Trucker', align: "center"},
{name: 'Acct_Num', align: "center"}
],
sortname: 'Customer',
sortorder: 'desc',
viewrecords: true,
gridview: true,
caption: 'Bill of Lading Accounts',
rowNum: 10000,
pager:true
}).jqGrid('inlineNav', {
addParams: {
addRowParams: { extraparam: {'arg1':'bol_acct', 'oper':'add'} }
},
editParams: {
extraparam: {
'arg1':'bol_acct', 'oper':'edit'
}
}
})
One can use serializeSaveData callback of inline editing to modify the data, which will be send during inline editing. You can add serializeSaveData callback via
inlineEditing: {
keys: true,
extraparam: { arg1: "bol_acct" },
serializeSaveData: function (postData) {
var newPostData = $.extend(true, {}, postData);
if (newPostData.oper === "add") {
delete newPostData.id; // delete id parameter
}
return newPostData;
}
}
function deleteRender(row, column, value) {
if (!value) {
return;
}
var status = getUserStatus(value);
var actionText = deleteBlockHtml;
if (!isUserContext()) {
actionText = '<span>Delete</span>';
}
if (status) {
actionText = '<span>Activate<span>';
}
return '<span class="grid-link-render"><a class="delete-grid-row" href="#" id="deleteUser_' + value.trim() + '">' + actionText + '</a></span>';
}
columnList = [
{text: 'Status', datafield: 'status', width: "8%", groupable: true, editable: false},
{text: 'Action', datafield: '_id', cellsrenderer: deleteRender, width: "10%", groupable: true, editable: false, filterable: false, sortable: false, menu: false},
];
I am calling the deleteRender() function on click of my delete button which is present in action.Unfortunately,when i scroll down to bottom it is not getting called in grid.
Can anyone plese help me.Thanks.
Please share some more code. The method in cellsrenderer method takes care of tailoring the html to be rendered into that cell of that column using the bounded data for that column which is called for each row when the grid is being painted.
i don't think deleteRender should contain the column list in there. Also, can you please show where you are defining the delete event that is attached for that 'Delete' link in the action column ?
Or please let me know if i'm missing something.
I am really new to the jqGrid. 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. I tried to resolve my problem using various answers from here like:
Adding new row to jqGrid using modal form on client only
There I have found the example made by Oleg for the 4.7 version of jqGrid and reproduced the same code for my purpose. The result was that I am able to delete row which I added after the grid initialisation but I am unable to delete any other row which was loaded from the array.
Another interesting thing is that I am able to modify the rows loaded from array, the only thing I cannot do with the grid is to delete rows loaded from array. I appreciate any advices.
Here is part of the code with jqGrid:
var delSettings = {
onclickSubmit: function () {
var $this = $(this), p = $this.jqGrid("getGridParam"), newPage = p.page;
if (p.lastpage > 1) {// on the multipage grid reload the grid
if (p.reccount === 1 && newPage === p.lastpage) {
// if after deliting there are no rows on the current page
// which is the last page of the grid
newPage--; // go to the previous page
}
// reload grid to make the row from the next page visable.
setTimeout(function () {
$this.trigger("reloadGrid", [{page: newPage}]);
}, 50);
}
return true;
}
};
$("#jqGrid").jqGrid({
datatype: "local",
data: results.data,
editurl: "clientArray",
colModel: [
{
label: 'Id',
name: 'Id',
width: 60,
editable: true,
key: true,
sorttype: 'number'
},
{
label: 'Company',
name: 'Company',
width: 90,
editoptions: {size: 40},
editable: true,
sorttype: 'string'
},
{
label: 'Address',
name: 'Address',
width: 100,
editoptions: {size: 40},
editable: true
},
{
label: 'City',
name: 'City',
width: 80,
editoptions: {size: 40},
editable: true
}
],
height: '100%',
viewrecords: true,
caption: "Baza klientów Klimatest",
pager: "#jqGridPager",
sortable: true,
ignoreCase: true,
cmTemplate: {editable: true, searchoptions: {clearSearch: true }},
rowNum: 5,
rowList: [5, 10, 20],
});
// toolbar searching
$('#jqGrid').jqGrid('filterToolbar', { defaultSearch: 'cn'});
$('#jqGrid').jqGrid('navGrid',"#jqGridPager",
{ edit: true, add: true, del: true, search: true, refresh: true, view: true},
// options for the Edit Dialog
{
editCaption: "The Edit Dialog",
recreateForm: true,
closeAfterEdit: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Add Dialog
{
closeAfterAdd: true,
recreateForm: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Delete Dialog
delSettings,
// options for the Search Dialog
{
},
// options for the View Dialog
{
});
// add first custom button
$('#jqGrid').navButtonAdd('#jqGridPager',
{
buttonicon: "ui-icon-calculator",
title: "Column chooser",
caption: "Columns",
position: "last",
onClickButton: function() {
// call the column chooser method
jQuery("#jqGrid").jqGrid('columnChooser');
}
});
EDIT
Data source is the result of parsed CSV file via Papaparse.js plugin (array of objects), which looks like this:
Id: "100,1"
Address: "Strefowa 8"
Company: "DSSE Sp. z o.o."
City: "Warsaw"
I edited the code just like Oleg suggested and I'm still able to delete only records which are added via interface of jqGrid.
I don't know if it may help, but when I click delete icon and confirm that I want to delete selected row, that row is no longer highlighted, but still visible. Thanks for feedback.
You have clear error in your code near // options for the View Dialog block. The View option should be included after delete and search options (see the documentation). So your current code don't use delSettings options.
I recommend you additionally to include test data in your next questions, because some problems exist only with some specific format of input data.
UPDATED: The problem is in the data which you use. The value for Id which you use contains comma ("100,1"). It's not allowed for jqGrid. First of all id in HTML should not use characters which have special meaning in CSS. The second problem: delGridRow method uses commas in separator to delete multiple rows at once. So the usage of id="100,1" will follows to attempt to delete tow rows: one row with id=100 and the second one with the id=1. By the way I'm developing now jqGrid in my fork of GitHub. I fixed many restrictions with the usage of special characters in ids. So you will be do able to use id="100,1" and successfully delete the rows if you would use jqGrid from my fork.
I recommend you to use underscore if you need to construct id which consist from multiple numbers: Id: "100_1" instead of Id: "100,1".
I have gone through the solutions given for not working onSelectRow but they could not worked for me.
I have following code :
$("#myActions_gridTable").jqGrid({
datatype:'local',
data: myActionsData,
cellsubmit: 'clientArray',
cellEdit: true,
rowNum: noOfLinesToDisplay,
pager: $("#myActions_pager"),
sortname: 'contract_Name',
viewrecords: true,
sortorder: 'asc',
autoWidth:true,
loadonce: true,
cmTemplate: { title: false },
height:'auto',
scrollrows: true,
colNames:["id","Status"],
colModel:[
{
name:'id',index:'id', jsonmap:'id', width:1,hidden:true,key:true, editable:true
},
{name:'status',index:'status', align:'center', sortable: false,
editable: true,
edittype: "select",
width: 150,
editoptions: {
value: "1:Done;2:Running"
}
}
],
onSelectRow : function(id){
console.log('inside onSelectRow');
if (id && id !== lastsel) {
$('#myActions_gridTable').restoreRow(lastsel);
$('#myActions_gridTable').editRow(id, true);
lastsel = id;
}
}
});
Here OnSelectRow does not get fired, no console.log is printed.
Please help.
You need to define the variable lastsel as
var lastsel;
In the above code you need to do :
var lastsel;
$("#myActions_gridTable").jqGrid({
..............
..............
..............,
onSelectRow : function(id){
console.log('inside onSelectRow');
if (id && id !== lastsel) {
$('#myActions_gridTable').restoreRow(lastsel);
$('#myActions_gridTable').editRow(id, true);
lastsel = id;
}
}
Here is the working JsFiddle Demo
And could get further info here http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events.
One possible problem could be the usage of edittype: "select" without usage of formatter: "select". In any way the property editoptions: { value: "1:Done;2:Running" } seems me very suspected if you don't use formatter: "select".
How looks the input data for the column "status"? Do you use 1 and 2 or "Done" and "Running"? If you want to hold 1 and 2 values in the data, but you want to display the values as "Done" and "Running" then you should use
formatter: "select", edittype: "select", editoptions: {value: "1:Done;2:Running"}
The demo demonstrates it. It uses
var myActionsData = [
{ id: 10, status: 1 },
{ id: 20, status: 2 }
];
as the input.
Alternatively one can use
var myActionsData = [
{ id: 10, status: "Done" },
{ id: 20, status: "Running" }
];
but one should use
edittype: "select", editoptions: {value: "Done:Done;Running:Running"}
in the case. No formatter: "select" are required in the last case: see another demo.
OnSelectrow is not working when cellEdit is true.
You can use onCellSelect instead of OnSelectrow.
At present I'm getting all the cells (with editable:true) in the row editable in which i clicked and not only the clicked the cell. The table is similar to the table in this link: http://www.ok-soft-gmbh.com/jqGrid/ClientsideEditing4.htm. I've gone through the link: http://www.trirand.com/jqgridwiki/doku.php?id=wiki:cell_editing, but didn't help (may be due to my fault in the way i tried) and also tried the answers given in stackoverflow related questions (used the attributes: cellEdit: true, cellsubmit: "clientArray").
Please help me using the above link as reference http://www.ok-soft-gmbh.com/jqGrid/ClientsideEditing4.htm (I think mainly the "onSelectRow", "ondblClickRow" functions need to be updated. i tried onSelectCell etc. but failed! ).
Thanks in advance.
If you need to use cell editing you have to include cellEdit: true in jqGrid definition. If you use local datatype then you should use cellsubmit: "clientArray" additionally. If you want to save data on the remote source you have to implement editing in your server code and specify cellurl option of jqGrid. The documentation describes what jqGrid send to the server on saving of cell.
I'm currently working on an Angular 2 app with Typescript, and I had a different need where I wanted to be able to click a row in the grid, but only have one cell editable. I didn't like the user experience where the user had to click the actual cell to edit it. Instead, clicking the row highlights the row and then makes the one cell editable. Here's a screenshot:
The trick was that I needed to set cellEdit to false on the grid and then set the individual column editable to true when declaring my column model array, and write a change event for the editoptions of the column. I also had to write code for the the onSelectRow event of the grid, to keep track of the current row selected and to restore the previous row selected. A snippet of the Typescript code is below:
private generateGrid() {
let colNames = ['id', 'Name', 'Total', 'Assigned', 'Distributed', 'Remaining', 'Total', 'Assigned', 'Remaining', 'Expiration'];
let self = this;
// declare variable to hold Id of last row selected in the grid
let lastRowId;
let colModel = [
{ name: 'id', key: true, hidden: true },
{ name: 'name' },
{ name: 'purchasedTotalCount', width: 35, align: 'center' },
{ name: 'purchasedAssignedCount', width: 35, align: 'center' },
{ name: 'purchasedDistributedCount', width: 35, align: 'center' },
{ name: 'purchasedRemainingCount', width: 35, align: 'center' },
// receivedTotalCount is the only editable cell;
// the custom change event works in conjunction with the onSelectRow event
// to get row editing to work, but only for this one cell as being editable;
// also note that cellEdit is set to false on the entire grid, otherwise it would
// require that the individual cell is selected in order to edit it, and not just
// anywhere on the row, which is the better user experience
{ name: 'receivedTotalCount',
width: 35,
align: 'center',
editable: true,
edittype: 'text',
editoptions: {
dataEvents: [
{
type: 'change', fn: function(e) {
//TODO: don't allow decimal numbers, or just round down
let count = parseInt(this.value);
if (isNaN(count) || count < 0 || count > 1000) {
alert('Value must be a whole number between 0 and 1000.');
} else {
self.updateLicenses(parseInt(lastRowId), count);
}
}
},
]
}
},
{ name: 'receivedAssignedCount', width: 35, align: 'center' },
{ name: 'receivedRemainingCount', width: 35, align: 'center' },
{ name: 'expirationDate', width: 45, align: 'center', formatter: 'date' }
];
jQuery('#licenseManagerGrid').jqGrid({
data: this.childTenants,
datatype: 'local',
colNames: colNames,
colModel: colModel,
altRows: true,
rowNum: 25,
rowList: [25, 50, 100],
width: 1200,
height: '100%',
viewrecords: true,
emptyrecords: '',
ignoreCase: true,
cellEdit: false, // must be false in order for row select with cell edit to work properly
cellsubmit: 'clientArray',
cellurl: 'clientArray',
editurl: 'clientArray',
pager: '#licenseManagerGridPager',
jsonReader: {
id: 'id',
repeatitems: false
},
// make the selected row editable and restore the previously-selected row back to what it was
onSelectRow: function(rowid, status) {
if (lastRowId === undefined) {
lastRowId = rowid;
}
else {
jQuery('#licenseManagerGrid').restoreRow(lastRowId);
lastRowId = rowid;
}
jQuery('#licenseManagerGrid').editRow(rowid, false);
},
});
}
Additionally, I wanted the escape key to allow the user to abort changes to the cell and then restore the cell to its previous state. This was accomplished with the following Angular 2 code in Typescript:
#Component({
selector: 'license-manager',
template: template,
styles: [style],
host: {
'(document:keydown)': 'handleKeyboardEvents($event)'
}
})
// handle keypress so a row can be restored if user presses Escape
private handleKeyboardEvents(event: KeyboardEvent) {
if (event.keyCode === 27) {
let selRow = jQuery('#licenseManagerGrid').jqGrid('getGridParam', 'selrow');
if (selRow) {
jQuery('#licenseManagerGrid').restoreRow(selRow);
}
}
}