Question

i have a gridpanel with cellediting plugin, and with a lot of grid header
(at least make the grid shown it horizontal scrollbar)...
here is the DEMO...

there is a bug in my grid, try to edit one of the collumn, and then press tab key to navigate to header15.. the grid didn't scroll to where i am editing,...
is it a bug?? a have looking for this at their forum, but no luck..

so, how to fix it??
how to make my grid scroll to the active editor??

from docs, there is a method scrollByDeltaX,
but how to know the delta from active editor??

Was it helpful?

Solution

Cut it short, try demo first :)

(Too free, and wanted your bounty, please award me!)

Funny that my answer works just nice on 4.0.7, but it doesn't work on 4.0.2a! Out of no clue, I checked the source of 4.0.2a, and shockingly saw this:

In src/panel/Table.js (4.0.2a)

/**
 * Scrolls the TablePanel by deltaY
 * @param {Number} deltaY
 */
scrollByDeltaY: function(deltaY) {
    var verticalScroller = this.getVerticalScroller();

    if (verticalScroller) {
        verticalScroller.scrollByDeltaY(deltaY);
    }
},

/**
 * Scrolls the TablePanel by deltaX
 * @param {Number} deltaY
 */
scrollByDeltaX: function(deltaX) {
    var horizontalScroller = this.getVerticalScroller();

    if (horizontalScroller) {
        horizontalScroller.scrollByDeltaX(deltaX);
    }
},

Noticed anything? Checkout the function scrollByDeltaX! It's coded wrongly (fixed in 4.0.7)!!! And this will obviously wouldn't have any visual feedback. It is asking the vertical scrollbar to do a deltaX scrolling. How can it be?

Anyway, to fix this problem is rather easy, in case you do not want to upgrade to 4.0.7. Afaik 4.0.7 has tons of bugs inherited from 4.0.6, and it breaks my project with that freaking masking issue.

Below is my working answer, and I hope you'll appreciate it. Basically I have modified the onEditorTab method and created an event hook, so your grid can hook onto it, and do the scrollByDeltaX when tabbing is triggered.

I'm not too sure how to do a scroll left most/right most, so a funny Infinity has been used in my code out of laziness.

Here is the example: DEMO (Remember to try out SHIFT+TAB too)

/**
 * Customized Row Selection Model which will
 * fires "editortab" event when an tabbing occurs
 */
Ext.define('NS.RowModel', {
    extend: 'Ext.selection.RowModel',

    //False to wrap to next row when you tab
    //to the end of a row
    preventWrap: false,

    initComponent: function() {
        /**
         * @event editortab
         * Fires when editor is tabbed
         * @param {RowModel} rowModel this rowmodel
         * @param {Editor} edt The editor
         * @param {string} dir The direction of the tab (left or right)
         * @param {Event} e The event object
         */
        this.addEvents('editortab');
        this.callParent();
    },

    //memorizing which is the last context
    lastEditorContext: null,

    onEditorTab: function(edt, e) {

        //Part of this code is from the original onEditorTab in
        //src/selection/RowModel.js line 416
        var me = this,
            view = me.views[0],
            record = edt.getActiveRecord(),
            header = edt.getActiveColumn(),
            position = view.getPosition(record, header),
            direction = e.shiftKey ? 'left' : 'right',
            newPosition  = view.walkCells(position, direction, e, this.preventWrap);

        //we store the last context, so we know whether the 
        //context has changed or not
        me.lastEditorContext = edt.context;

        //if there is new position, edit; else, complete the edit.
        if (newPosition) {
            edt.startEditByPosition(newPosition);
        }else{
            edt.completeEdit();
        }

        //If context doesn't change, we try to walk
        //to the next one until we find a new edit box (context changed)
        while (me.lastEditorContext === edt.context && newPosition) {
            newPosition = view.walkCells(newPosition, direction, e, this.preventWrap);
            if (newPosition) {
                edt.startEditByPosition(newPosition);
            }
        }

        //Fires the event
        this.fireEvent('editortab', this, edt, direction, e);
    }
});

/**
 * Customized Editor Grid to support tabbing
 */
Ext.define('NS.EditorGrid', {
    extend: 'Ext.grid.Panel',
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            plugins: [Ext.create('Ext.grid.plugin.CellEditing', {
                clicksToEdit: 1
            })],

            selModel: Ext.create('NS.RowModel', {
                listeners: {
                    editortab: {
                        fn: me.onEditorTab,
                        scope: me
                    }
                }
            })
        });

        me.callParent();
    },

    onEditorTab: function(sel, edt, dir, e) {

        var lastRow = sel.lastEditorContext.rowIdx,
            newRow = edt.context.rowIdx,
            deltaX = 0;

        //Let's calculate deltaX first

        //if row changed, we reset the cells to the left most or right most
        if (lastRow != newRow) {
            deltaX = lastRow < newRow ? -Infinity : Infinity;
        }else{
            //else, do deltax :)
            deltaX = edt.context.column.width * (dir == 'right' ? 1 : -1);
        }


        //If you are using 4.0.2a, use this. They have typo in
        //src/panel/Table.js, line 1133
        var horizontalScroller = this.getHorizontalScroller();
        if (horizontalScroller) horizontalScroller.scrollByDeltaX(deltaX);


        //But if you are running 4.0.7, this is fine. Use this:
        //this.scrollByDeltaX(deltaX);
    }
});

//-------------------------------------------------
//Everything below remains :)

Ext.onReady(function() {

    var storeSr=Ext.create('Ext.data.ArrayStore', {
        fields: ["KD_SR","NM_SR"]
    });

    //load data
    var tmpd=[];
    for (i=1;i<=15;i++){
        tmpd.push([i,"nm "+i]);
    }
    storeSr.loadData(tmpd);

    //create column
    col=[]
    col.push({header: "Kode", dataIndex: 'KD_SR'});
    for (j=1;j<=15;j++){
        col.push({
            header: "Header"+j,
            width:100,
            dataIndex: 'NM_SR',
            editor:{xtype:"textfield"}
        });
    }

    var gridSr = Ext.create('NS.EditorGrid', {
        height: 200,
        width: 500,
        store: storeSr,
        columns: col
    });

    //create window
    var winEditSR=Ext.create("Ext.Window",{
        title:"Sub Rayon",
        autoWidth : true,
        autoHeight : true,
        autoShow:true,
        border : false,
        modal : true,
        items : [gridSr]
    }); 
});

I still wondering if there might be a better solution... perhaps using column (header)'s x to determine scroller's scrollLeft, but that will be pretty jerky...

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