The code which you posted should work. Probably you use it on the wrong place.
The only thing which you should take in the consideration that after the end of the row editing the focus is lost and you can't use arrows to move th the next row. You should use aftersavefunc
parameter of the editRow method to restore the grid focus:
var grid = $('#grid');
grid.jqGrid('editRow',rowid,true,null, null, null, {},function(){
setTimeout(function(){
grid.focus();
},100);
});
The demo is the small modification of the demo from the answer. You can use keyboard to move the row selection and enter to start inline editing and to save the row.
UPDATED: I ask you always to append your original question with additional information instead of full rewriting of the question. Your original question don't contained anything about the usage of multiselect: true
. This case (multiselect: false
) and my first demo could be interesting for other users. So the general practice is to append the original question with "UPDATED:" part or just ask a new question. Currently if somebody will read your question and my answer he/she will wonder: "what a queer answer? Probably the answer not carefully read the question.".
Now about your current problem in case of multiselect: true
. How you know jqGrid 4.0.0 is the first version which has support of keyboard navigation in the grid and treegrid and which has bindKeys
method. The solution is far from be perfect. Many actions can't be done with the keyboard. For example the buttons in the navigation toolbar ("Add", "Edit", "Delete" etc) could be not clicked with respect of keyboard. To use keyboard navigation in the jqGrid many places of jqGrid code are extended with the setting of tabindex
attribute. For example in the line the selected row (<tr>
element) receive the attribute tabindex="0"
, but the line works only in case of multiselect: false
. In the line of bindKeys code will be search (and not found) the attribute tabindex="0"
. So the current implementation of bindKeys
don't work in the multiselect: true
mode.
As I wrote before the full support of multiselect: true
mode can be implemented only with many changes in the jqGrid code. As a workaround I could suggest the following: we can overwrite the code of bindKeys
method only with the changed implementation.
The corresponding demo you can find here. The JavaScript code form the demo is:
$.extend($.fn.jqGrid,{
bindKeys : function( settings ){
'use strict';
var o = $.extend({
onEnter: null,
onSpace: null,
onLeftKey: null,
onRightKey: null,
scrollingRows : true
},settings || {});
return this.each(function(){
var $t = this;
if( !$('body').is('[role]') ){$('body').attr('role','application');}
$t.p.scrollrows = o.scrollingRows;
$($t).keydown(function(event){
var target = $($t).find('tr[tabindex=0]')[0], id, mind, r,
expanded = $t.p.treeReader.expanded_field;
if (!target && $t.p.selrow !== null) {
target = $t.rows.namedItem($t.p.selrow);
}
//check for arrow keys
if(target) {
mind = $t.p._index[target.id];
if(event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40){
// up key
if(event.keyCode === 38 ){
r = target.previousSibling;
id = "";
if(r) {
if($(r).is(":hidden")) {
while(r) {
r = r.previousSibling;
if(!$(r).is(":hidden") && $(r).hasClass('jqgrow')) {id = r.id;break;}
}
} else {
id = r.id;
}
}
if ($.inArray(id,$t.p.selarrrow) === -1) {
$($t).jqGrid('setSelection', id);
} else {
$t.p.selrow = id;
}
}
//if key is down arrow
if(event.keyCode === 40){
r = target.nextSibling;
id ="";
if(r) {
if($(r).is(":hidden")) {
while(r) {
r = r.nextSibling;
if(!$(r).is(":hidden") && $(r).hasClass('jqgrow') ) {id = r.id;break;}
}
} else {
id = r.id;
}
}
if ($.inArray(id,$t.p.selarrrow) === -1) {
$($t).jqGrid('setSelection', id);
} else {
$t.p.selrow = id;
}
}
// left
if(event.keyCode === 37 ){
if($t.p.treeGrid && $t.p.data[mind][expanded]) {
$(target).find("div.treeclick").trigger('click');
}
if($.isFunction(o.onLeftKey)) {
o.onLeftKey.call($t, $t.p.selrow);
}
}
// right
if(event.keyCode === 39 ){
if($t.p.treeGrid && !$t.p.data[mind][expanded]) {
$(target).find("div.treeclick").trigger('click');
}
if($.isFunction(o.onRightKey)) {
o.onRightKey.call($t, $t.p.selrow);
}
}
return false;
}
//check if enter was pressed on a grid or treegrid node
else if( event.keyCode === 13 ){
if($.isFunction(o.onEnter)) {
o.onEnter.call($t, $t.p.selrow);
}
return false;
} else if(event.keyCode === 32) {
if($.isFunction(o.onSpace)) {
o.onSpace.call($t, $t.p.selrow);
}
return false;
}
}
});
});
}
});
and
var grid = $("#list");
...
grid.jqGrid('bindKeys', {
onEnter: function(rowid) {
//alert("You enter a row with id: " + rowid);
editingRowId = rowid; // probably cab be replaced to grid[0].p.selrow
// we use aftersavefunc to restore focus
grid.jqGrid('editRow',rowid,true,null, null, null, {},function(){
setTimeout(function(){
grid.focus();
},100);
});
},
onSpace: function(rowid) {
grid.jqGrid('setSelection', rowid);
}
});
// select one row at the begining and set the focus
grid.jqGrid('setSelection',"1");
grid.focus();
I repeat one more time that I find the code which I posted not perfect. One should make visible which line have focus and make much more things. I wanted only to show which kind of changes and where should be done to allow keyboard navigation for the musliselect grids.
Edit
If multikey:"ctrlKey" is added bindKeys. Code in answer does not work. Also using setFocus in answer code causes focus to jump to another row after editing, so this should removed. There is no way to set focus after editing to current row, mouse clik is always required, jqGrid does not support inline edit using keyboard only.