Question

Using ExtJS 4 I would like to create a grid into which the user will enter a long list of numbers. I would like the user to be able to finish editing one cell by pressing "Enter" and then automatically move to the cell below and start editing.

Ext.grid.plugin.CellEditing seems to work well for the purpose of editing, but I can't find a way to detect and handle the keyUp event.

I tried approaching the matter using the "edit" event with this code:

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;
                }
            }
        }
    })
],

The problem with this approach is that if the user starts editing the cell, then clicks on a GUI element outside of the Grid, the edit event does not distinguish this from the "Enter" key being pressed. Can this be fixed?

Perhaps I should be trying to implement a custom SelectionModel instead? How does one go about starting with that approach?

Was it helpful?

Solution

something like this ???
when editing try using tab, shift + tab, enter, and shift + enter

what i did is override the cellediting and selection.rowmodel

actually, i have had a similar question with you. and @Lionel Chan help me solve it.
and my solution above is base on his idea.

Note : only work with Extjs 4.0.7


EDIT (if my jsfiddle broken, here's the override)

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);
    }
});

OTHER TIPS

Starting with the suggestion of "Warung Nasi 49", I Wrote this override:

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);

This override allow both TAB and ENTER navigation (forward/backward via SHIFT).

When the last cell of row is reached, the firt editable cell of the next row is focused.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top