You are hereBlogs / rahul's blog / Navigation between Editable cells of an ExtJs GridPanel
Navigation between Editable cells of an ExtJs GridPanel
I use ExtJs GridPanel extensively both for displaying tabular information as well as for data entry. Data entry with GridPanel is mostly a pain in the neck due to navigation issues between cells.
You can use Tab/Shift+Tab for moving between adjacent cells. This works fine in ExtJs 3.x, but has issues in ExtJs 2.x and earlier. Moreover, you need to use mouse for moving between rows, and adding new rows.
So, I created a plugin for making such navigation easy. Tab/Arrow keys mostly are handled by the ExtJs framework. This plugin uses Ctrl+Arrow keys for navigation.
- Ctrl + Left takes you to the left cell. If you are on the first cell of the row, it takes you to the last cell of previous row.
- Ctrl + Right takes you to the right cell. If you are on the last cell of the row, it takes you to the first cell of the next row. If you are already on the last cell of the last row, it add a new row to the GridPanel, and starts editing the first cell of the new row.
- Ctrl + Up takes you to the row above the current row.
- Ctrl + Down takes you to the row below to the current row.
Without further discussion, here's the javascript for the plugin.
Rahul.ux.EditableGridPanel = function(config) {
Ext.apply(this, config);
};
// plugin code
Ext.extend(Rahul.ux.EditableGridPanel, Ext.util.Observable, {
init: function(grid) {
Ext.apply(grid, {
onRender: grid.onRender.createSequence(function(ct, position) {
var columns = this.colModel.config;
for (i = 0; i < columns.length; i++) {
if (columns[i].editor) {
columns[i].editor.addListener('specialkey', this.gridEditorCtrlArrowKey, this);
}
}
}), // end of function onRender
gridEditorCtrlArrowKey: function(combo, el) {
if (el.keyCode == el.RIGHT || el.keyCode == el.LEFT || el.keyCode == el.UP || el.keyCode == el.DOWN) {
//Make sure Ctrl is pressed to avoid shifting of focus just on the Right or Left arrow key.
if (!el.ctrlKey)
return;
// } else if (el.keyCode == el.TAB) {
// if (el.shiftKey)
// return;
} else
return;
var grd = this;
var row = grd.activeEditor.row;
var col = grd.activeEditor.col;
var totalCols = grd.colModel.config.length;
var totalRows = grd.view.getRows().length;
switch (el.keyCode) {
case el.TAB:
case el.RIGHT:
var next = this.nextEditableCell(row, col);
if (next.isNew)
this.addEditableRow(grd, next.col);
else
grd.startEditing(next.row, next.col);
break;
case el.LEFT:
var prev = this.previousEditableCell(row, col);
if (prev.move)
grd.startEditing(prev.row, prev.col);
break;
case el.UP:
if (row != 0)
grd.startEditing(row - 1, col);
break;
case el.DOWN:
if (row != totalRows - 1)
grd.startEditing(row + 1, col);
break;
}
el.stopEvent();
}, // end of function gridEditorCtrlArrowKey
addEditableRow: function(grd, focusCol) {
var rowIndex = grd.addRecord();
grd.getView().focusRow(rowIndex);
grd.startEditing(rowIndex, focusCol);
},
nextEditableCell: function(row, col) {
var next = {};
for (i = col + 1; i < this.colModel.config.length; i++) {
if (!this.colModel.config[i].hidden) {
next.col = i;
break;
}
}
if (next.col != undefined) {
next.row = row;
next.isNew = false;
} else {
for (i = 0; i < this.colModel.config.length; i++) {
if (!this.colModel.config[i].hidden) {
next.col = i;
break;
}
}
next.row = row + 1;
next.isNew = true;
}
return (next);
},
previousEditableCell: function(row, col) {
var prev = {};
for (i = col - 1; i >= 0; i--) {
if (!this.colModel.config[i].hidden) {
prev.col = i;
break;
}
}
if (prev.col != undefined) {
prev.row = row;
prev.move = true;
} else if (row > 0) {
for (i = this.colModel.config.length - 1; i >= 0; i--) {
if (!this.colModel.config[i].hidden) {
prev.col = i;
prev.row = row - 1;
prev.move = true;
break;
}
}
} else {
prev.row = row;
prev.col = col;
prev.move = false;
}
return (prev);
}
});
} // end of function init
}); // end of extendNext, if you are using Coolite 0.8.x or earlier, you can use the following server control, that would enable you to embed the above plugin in the <Plugins> inner property of <ext:GridPanel> in markup:
<ToolboxItem(False)> _ <InstanceOf(ClassName:="EditableGridPanel")> _ Public Class EditableGridPanel Inherits Plugin End Class
If you are using Ext.Net 1.x or later, use the following:
[ToolboxItem(false)]
public class EditableGridPanel:Ext.Net.Plugin
{
public override string InstanceOf
{
get
{
return "EditableGridPanel";
}
}
}Be sure to include the js file containing the above script in the page also.
The above scrip is flexible enough to automatically ignore columns that do not have an editor attached to them, or hidden columns.







Hei Rahul,
This looks interesting....
I have some questions:
1.
I don't see how you use Ext.extend(superclass, overrides), with only 2 arguments. You pass in 3 arguments, and don't use the return value. Is that doing the same?
2.
How to use this? I'm not a Coolite or Ext.Net user... I tried var myEditGrid = new Rahul.ux.EditableGridPanel({...}), but that doesn't work. Not surprisingly, because your EditableGridPanel extends from Observable, not from EditorGridPanel. Should I first create a standard EditorGridPanel and pass that into your EditableGridPanel constructor? How?
Many thanks...
Martijn
Hi Martijn, Ext.extend allows a 2 argument and a 3 argument call (Check the docs for Ext.extend here: http://dev.sencha.com/deploy/dev/docs/#prop-Ext.Button-template?class=Ext).
Now EditableGridPanel is a plugin for GridPanel, so you would specify it as a plugin in the configuration of GridPanel, something like:
var grd = new Ext.grid.GridPanel ({ .... plugins: new Rahul.ux.EditableGridPanel({}) .... });Please note that this plugin has nothing to do with EditorGridPanel. EditorGridPanel is a GridPanel extension that was released after I published this plugin, so there's a little confusion in naming. As said, this is a plugin that allows you to navigate between GridPanel cells using Ctrl+Arrows keys and would work on GridPanel or any of its extended classes.
Hi Rahul,
Thanks, that clarifies a lot. learning every day!
Martijn
Dear Rahul:
In this implementation, the used method addRecord (at line 067) is not part of the standard ExtJs3.4 's editorGridPanel. So is a customized method?
Regards.
Hi fausto, to start with, this Extension has nothing to do with the editorGridPanel of ExtJs (please read my comment above). Well yes, that's a custom method I have added to GridPanel that adds a record to its store.
Hi Rahul, congratulations for your plugin, but I have a problem when I holding the key UP or DOWN + CTRL, the focus of the next cell is lost !!
Any idea?
thanks
I using EXTJS 3.4 and GridEditor component.
Hi Toni, when you click Ctrl + Up or Ctrl + Down key combination, the focus goes to the cell in the same column as the current one above or below the current row respectively (if it exists). If its not behaving like this, it might be some conflict with the GridEditor component. Can you please post a working example somewhere demonstrating the issue so I can have a look?
Post new comment