Совет, нужна помощь с ExtJS 4: сетка: редактирование ячеек: функция автоматического редактирования - PullRequest
16 голосов
/ 11 августа 2011

Я искал вопросы, связанные с ExtJS, и не нашел никакой ссылки, но если я пропустил это заранее, извините за создание дублирующего вопроса.

Я хотел бы попросить некоторой помощи о том, как сделать сетку ExtJS 4: редактирование ячеек: функция автоматического редактирования - я хочу войти в режим редактирования ячеек, когда нажимаю клавишу (например, нажимая « 123 ”в выделенной ячейке, текст заменяется (если есть) на« 123 »). В настоящий момент вход в режим редактирования ячеек можно выполнить, нажав ENTER или щелкнув мышью.

В качестве базы я использую приведенный Sencha пример: http://dev.sencha.com/deploy/ext-4.0.2a/examples/grid/cell-editing.html

Любые советы, указатели были бы благодарны.

Заранее спасибо! :)

На самом деле я частично решил свою проблему. Нашел способ сделать ячейку редактируемой при нажатии клавиши, поставил параметр конфигурации selectOnFocus для выделения текста в ячейке, теперь мне нужно вставить первый символ (который инициировал режим редактирования) в ячейку.

Это может быть не самое красивое решение, но оно у меня работает :) Вот полный код до сих пор.

var tStore = Ext.create('Ext.data.Store', {
    storeId:'simpsonsStore',
    fields:['name', 'email', 'phone'],
    data:{'items':[
        {"name":"Lisa", "email":"lisa@simpsons.com", "phone":"555-111-1224"},
        {"name":"Bart", "email":"bart@simpsons.com", "phone":"555--222-1234"},
        {"name":"Homer", "email":"home@simpsons.com", "phone":"555-222-1244"},
        {"name":"Marge", "email":"marge@simpsons.com", "phone":"555-222-1254"}
    ]},
    proxy: {
        type: 'memory',
        reader: {
            type: 'json',
            root: 'items'
        }
    }
});

var tCellEdit = Ext.create('Ext.grid.plugin.CellEditing', {
    clicksToEdit: 1
});

var tGrid = Ext.create('Ext.grid.Panel', {
    title: 'Simpsons',
    store: tStore,
    columns: [
        {header: 'Name',  dataIndex: 'name', field: 'textfield'},
        {header: 'Email', dataIndex: 'email', flex:1,
            editor: {
                xtype:'textfield',
                allowBlank:false,
                selectOnFocus: true
            }
        },
        {header: 'Phone', dataIndex: 'phone'}
    ],
    selType: 'cellmodel',
    plugins: [tCellEdit],
    listeners: {
        keypress: {
            element: 'el',
            fn: function(iEvent, iElement) {
                iCode = iEvent.getKey();
                if (iCode != undefined && iCode != iEvent.LEFT && iCode != iEvent.RIGHT && iCode != iEvent.UP && iCode != iEvent.DOWN && iCode != iEvent.ENTER && iCode != iEvent.ESC) {
                    var iView = tGrid.getView();
                    var position = iView.selModel.position;

                    tCellEdit.startEditByPosition(position);
                }
            }
        }
    },
    height: 200,
    width: 400,
    renderTo: Ext.getBody()
});

1 Ответ

9 голосов
/ 12 сентября 2011

Извините за долгую задержку, но давайте просто скажем, что я был в отпуске, сидел на море и потягивал мохито ... думал о жизни, картошке и о том, что мне действительно нужно для предстоящего проекта. Я пришел к выводу об этих пунктах:

  1. Потому что в моей сетке люди будут писать числа. Мне нужно сосредоточиться на входе в режим редактирования, нажимая цифры в текущей ячейке.
  2. Мне нужно нажать цифровую клавишу, чтобы не только активировать режим редактирования, но и вставить его как новое значение (поэтому, нажав 1 на клавиатуре, ячейка переходит в режим редактирования и помещая 1 в качестве нового значения)
  3. Мне нужно позволить магии ESC и ENTER работать как обычно.

В целом, я сделал некоторые изменения в Ext.core.Element (чтобы исправить странную ошибку, которая появляется при использовании IE9 и Firefox 6.0.2 в Windows 7. Для более подробной информации, смотрите комментарии в коде.), Ext.grid.plugin. Редактирование (для входа в режим редактирования нажатием цифровых клавиш) и Ext.Editor (для установки нового значения).

TODO: в режиме редактирования нажатие ENTER не только завершает редактирование, но и перемещает одну ячейку вниз, если она есть (аналогично Excel)

PS. Извините за мой английский ... не совсем мой родной язык, но, надеюсь, это более или менее понятно. Также спасибо за вклад и комментарии! ;)

/**
* Fix for bug with cursor position in editor grid textfield
*
* Bug description: after loading an editor grid which contains a textfield, the cursor / caret is positioned at the
* beginning of text field the first time the editor is activated. Subsequent activations position the caret at the end
* of the text field.
* In my case this behavior is not observed in Opera 11.51 (Windows 7) and IE8, Firefox 6.0.2 (Windows XP), but observed in IE9 and Firefox 6.0.2 (Windows 7)
*
* Current fix helps with IE9 problem, but Firefox 6.0.2 (Windows 7) still putting the cursor / caret at the beginning of text field.
*
* Forum post for ExtJS v3 about same problem and where the fix was found: http://www.sencha.com/forum/showthread.php?88046-OPEN-3.1-Caret-Cursor-Position-in-Editor-Grid-Textfield
*/
Ext.core.Element.prototype.focus = function(defer, /* private */dom) {
    var me = this,
        dom = dom || me.dom;
    try {
        if (Number(defer)) {
            Ext.defer(me.focus, defer, null, [null, dom]);
        } else {
            dom.focus();
            // start override
            dom.value = dom.value;
            dom.focus();
            if (dom.sof) {
                dom.select();
            }
            // end override
        }
    } catch (e) { }
    return me;
};
/**
* END OF ALL FIXES
*/

var tStore = Ext.create('Ext.data.Store', {
    storeId:'simpsonsStore',
    fields:['name', 'email', 'phone'],
    data:{'items':[
        {"name":"Lisa", "email":"lisa@simpsons.com", "phone":"555-111-1224"},
        {"name":"Bart", "email":"bart@simpsons.com", "phone":"555--222-1234"},
        {"name":"Homer", "email":"home@simpsons.com", "phone":"555-222-1244"},
        {"name":"Marge", "email":"marge@simpsons.com", "phone":"555-222-1254"}
    ]},
    proxy: {
        type: 'memory',
        reader: {
            type: 'json',
            root: 'items'
        }
    }
});

Ext.onReady(function() {

    var newValue = '';

    /**
     *  Rewriting class Ext.grid.pluging.Editing to make cell go into edit mode by pressing numeric keys.
     *
     * changed: requirements: Ext.util.KeyNav -> Ext.util.KeyMap
     * changed: accordingly made changes to use Ext.util.KeyMap in initEditTriggers function
     * added: new function onNumberKey for replacing original value with new one and entering cell in edit mode
     *
     * tested only for Cell selection model, too lazy for Row selection model testing :P
     */
    Ext.override(Ext.grid.plugin.Editing, {

        requires: [
            'Ext.grid.column.Column',
            'Ext.util.KeyMap'
        ],

        initEditTriggers: function() {
            var me = this,
                view = me.view,
                clickEvent = me.clicksToEdit === 1 ? 'click' : 'dblclick';

            // Start editing
            me.mon(view, 'cell' + clickEvent, me.startEditByClick, me);
            view.on('render', function() {
                me.keyNav = Ext.create('Ext.util.KeyMap', view.el, [
                    {
                        key: [48, 49, 50, 51, 52, 53, 54, 55, 56, 57],  // 0123456789
                        fn: me.onNumberKey,
                        scope: me
                    }, {
                        key: 13,    // ENTER
                        fn: me.onEnterKey,
                        scope: me
                    }, {
                        key: 27,    // ESC
                        fn: me.onEscKey,
                        scope: me
                    }
                ]);
            }, me, { single: true });
        },

        onNumberKey: function(e) {
            var me = this,
                grid = me.grid,
                selModel = grid.getSelectionModel(),
                record,
                columnHeader = grid.headerCt.getHeaderAtIndex(0);

            // Calculate editing start position from SelectionModel
            // CellSelectionModel
            if (selModel.getCurrentPosition) {
                pos = selModel.getCurrentPosition();
                record = grid.store.getAt(pos.row);
                columnHeader = grid.headerCt.getHeaderAtIndex(pos.column);
            }
            // RowSelectionModel
            else {
                record = selModel.getLastSelected();
            }

            // if current cell have editor, then save numeric key in global variable
            ed = me.getEditor(record, columnHeader);
            if (ed) {
                newValue = String.fromCharCode(e);
            }

            // start cell edit mode
            me.startEdit(record, columnHeader);
        }
});

    Ext.override(Ext.Editor, {
        startEdit : function(el, value) {
            var me = this,
                field = me.field;

            me.completeEdit();
            me.boundEl = Ext.get(el);
            value = Ext.isDefined(value) ? value : me.boundEl.dom.innerHTML;

            if (!me.rendered) {
                me.render(me.parentEl || document.body);
            }

            if (me.fireEvent('beforestartedit', me, me.boundEl, value) !== false) {
                me.startValue = value;
                me.show();
                field.reset();
                field.setValue((newValue != '' ? newValue : value));
                me.realign(true);
                field.focus(false, 10);
                if (field.autoSize) {
                    field.autoSize();
                }
                me.editing = true;

                // reset global newValue
                newValue = '';
            }
        }
    });
    /**
     *  END OF ALL OVERRIDES (thank god!) :)
     */


    var tCellEdit = Ext.create('Ext.grid.plugin.CellEditing', {
        clicksToEdit: 1
    });

    var tGrid = Ext.create('Ext.grid.Panel', {
        title: 'Simpsons',
        store: tStore,
        columns: [
            {header: 'Name',  dataIndex: 'name',
                editor: {
                    xtype: 'textfield',
                    maskRe: /[\d]/
                }
            },
            {header: 'Email', dataIndex: 'email', flex:1,
                editor: {
                    xtype:'textfield'
                }
            },
            {header: 'Phone', dataIndex: 'phone'}
        ],
        selType: 'cellmodel',
        plugins: [tCellEdit],
        height: 200,
        width: 400,
        renderTo: 'testgrid'
    });
});
...