ExtJS 4:可编辑网格中的Excel风格键盘导航

pos*_*nal 4 datagrid extjs extjs4

使用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;
                }
            }
        }
    })
],
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于,如果用户开始编辑单元格,然后单击Grid外部的GUI元素,则编辑事件不会将此与正在按下的"Enter"键区分开来.这可以修复吗?

也许我应该尝试实现自定义SelectionModel?如何从这种方法开始?

Egy*_*din 6

这样 ???
使用编辑试时tab,shift + tab,enter,和shift + enter

我做的是覆盖celleditingselection.rowmodel

实际上,我和你有过类似的问题.和@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);
    }
});
Run Code Online (Sandbox Code Playgroud)