使用ExtJS 4我想创建一个网格,用户将在其中输入一长串数字。我希望用户能够通过按“Enter”完成一个单元格的编辑,然后自动移动到下面的单元格并开始编辑。
Ext.grid.plugin.CellEditing似乎很适合编辑,但我找不到检测和处理keyUp事件的方法。
我尝试使用此代码的“编辑”事件来处理此事:
selType: 'cellmodel',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1,
listeners: {
edit: function (editor, e, eOpts) {
// If the event is fired by pressing "Enter", the column and row associated with event will
// be the same as the currently selected row and column
if (e.grid.selModel.position.column == e.colIdx && e.grid.selModel.position.row == e.rowIdx){
// Check if we are in the final row
if (e.rowIdx+1 == e.grid.getStore().getTotalCount()){
return true;
}
editor.startEditByPosition({row: e.rowIdx+1, column: e.colIdx});
return false;
}
}
}
})
],
这种方法的问题在于,如果用户开始编辑单元格,然后单击网格外部的GUI元素,则编辑事件不会将此与正在按下的“Enter”键区分开来。这可以解决吗?
也许我应该尝试实现自定义SelectionModel?如何从这种方法开始呢?
答案 0 :(得分:6)
tab
,shift + tab
,enter
和shift + enter
我所做的是覆盖cellediting
和selection.rowmodel
实际上,我和你有过类似的question。和@Lionel Chan帮我解决了。
我的解决方案基于他的想法。
注意:仅适用于Extjs 4.0.7
编辑(如果我的jsfiddle坏了,这里是覆盖)
Ext.override(Ext.grid.plugin.CellEditing,{
onSpecialKey: function(ed, field, e) {
var grid = this.grid,sm;
if (e.getKey() === e.TAB) {
e.stopEvent();
sm = grid.getSelectionModel();
if (sm.onEditorTab)sm.onEditorTab(this, e);
}else if(e.getKey() === e.ENTER){
e.stopEvent();
sm = grid.getSelectionModel();
if (sm.onEditorEnter)sm.onEditorEnter(this, e);
}
}
});
Ext.override(Ext.selection.RowModel, {
lastId:null,
onEditorTab: function(ep, e) {
var me = this,
view = me.view,
record = ep.getActiveRecord(),
header = ep.getActiveColumn(),
position = view.getPosition(record, header),
direction = e.shiftKey ? 'left' : 'right',
newPosition = view.walkCells(position, direction, e, false),
newId=newPosition.row,
grid=view.up('gridpanel');
if (me.lastId!=newId && me.lastId!=null){
deltaX = me.lastId<newId? -Infinity : Infinity;
header=grid.headerCt.getHeaderAtIndex(newPosition.column);
if(header){
while(!header.getEditor()){
newPosition= view.walkCells(newPosition,direction, e, false);
header=grid.headerCt.getHeaderAtIndex(newPosition.column);
}
}
}else{
deltaX = ep.context.column.width * (direction== 'right' ? 1 : -1);
}
grid.scrollByDeltaX(deltaX);
me.lastId=newPosition.row;
Ext.defer(function(){
if (newPosition)ep.startEditByPosition(newPosition);
else ep.completeEdit();
}, 100);
},
onEditorEnter:function(ep,e){
var me = this,
view = me.view,
record = ep.getActiveRecord(),
header = ep.getActiveColumn(),
position = view.getPosition(record, header),
direction = e.shiftKey ? 'up' : 'down',
newPosition = view.walkCells(position, direction, e, false),
newId=newPosition.row,
grid=view.up('gridpanel');
deltaY=20 * (direction== 'down' ? 1 : -1);
grid.scrollByDeltaY(deltaY);
me.lastId=newPosition.row;
Ext.defer(function(){
if (newPosition)ep.startEditByPosition(newPosition);
else ep.completeEdit();
}, 100);
}
});
答案 1 :(得分:1)
从&#34; Warung Nasi 49 &#34;的建议开始, 我写了这个覆盖:
Ext.define('Override.Ext.grid.plugin.CellEditing',
{
override: 'Ext.grid.plugin.CellEditing',
onSpecialKey: function (ed, field, e) {
var grid = this.grid,
nbCols = grid.columns.length - 1, //start from 0
nbRows = grid.getStore().getTotalCount() - 1, //start from 0
currentCol = this.context.colIdx,
currentRow = this.context.rowIdx;
//forward
if (!e.shiftKey && (e.getKey() === e.ENTER || e.getKey() === e.TAB)) {
e.stopEvent();
//Detect next editable cell
do {
if (this.startEdit(currentRow, currentCol + 1))
break;
else {
currentCol++;
if (currentCol >= nbCols) {
currentRow++;
currentCol = -1;
}
}
} while (currentRow <= nbRows);
}
//backward
if (e.shiftKey && (e.getKey() === e.ENTER || e.getKey() === e.TAB)) {
e.stopEvent();
//Detect previous editable cell
do {
if (this.startEdit(currentRow, currentCol - 1))
break;
else {
currentCol--;
if (currentCol < 0) {
currentRow--;
currentCol = nbCols+1;
}
}
} while (currentRow >=0);
}
}
},
null);
此覆盖允许TAB和ENTER导航(通过SHIFT向前/向后)。
当到达行的最后一个单元格时,下一行的第一个单元格将被聚焦。