Как добавить дополнительные ключи в ключную карту ExtJS itemselector?

#extjs #extjs7

#extjs #extjs7

Вопрос:

Есть ли решение для расширения ключевой карты ItemSelector? Я хотел бы добавить ключную строку (например, PageUp и PageDown KeyEvent в itemselector), которая при нажатии буквы «A-Z» приведет меня к элементу, который начинается с нажатой буквы, и выберите его.

Ответ №1:

Для этого вы можете использовать следующее переопределение (пример скрипки). Он не будет корректно работать при перезагрузке view sore. И вам нужно будет определить поле записи поиска записи. В случае сложных шаблонов просмотра вы можете удалить жестко запрограммированную функцию поиска и использовать ее в качестве настройки.

 Ext.define('overrides.view.NavigationModel', {
    override: 'Ext.view.NavigationModel',
    searchRecordField: false,
    
    initKeyNav: function (view) {
        var me = this;

        // Drive the KeyNav off the View's itemkeydown event so that beforeitemkeydown listeners may veto.
        // By default KeyNav uses defaultEventAction: 'stopEvent', and this is required for movement keys
        // which by default affect scrolling.
        var keyNavConfig = {
            target: view,
            ignoreInputFields: true,
            eventName: 'itemkeydown',
            defaultEventAction: 'stopEvent',
            processEvent: me.processViewEvent,
            up: me.onKeyUp,
            down: me.onKeyDown,
            right: me.onKeyRight,
            left: me.onKeyLeft,
            pageDown: me.onKeyPageDown,
            pageUp: me.onKeyPageUp,
            home: me.onKeyHome,
            end: me.onKeyEnd,
            space: me.onKeySpace,
            enter: me.onKeyEnter,
            A: {
                ctrl: true,
                // Need a separate function because we don't want the key
                // events passed on to selectAll (causes event suppression).
                handler: me.onSelectAllKeyPress
            },
            F: me.onAlphabetKeyPress,
            scope: me
        };

        if(this.view.searchRecordField) {
            keyNavConfig = Ext.Object.merge(keyNavConfig, this.getAdditionalKeyNav());
        }
        me.keyNav = new Ext.util.KeyNav(keyNavConfig);
    },
    
    getAdditionalKeyNav: function() {
        var keyNav = {};
        this.view.getStore().each(function(record) {
            var firstLetter = record.get(this.view.searchRecordField)[0].toUpperCase();
            if(!keyNav[firstLetter]) {
                keyNav[firstLetter] = this.onAlphabetKeyPress
            }
        }, this);
        return keyNav;
    },
    
    onAlphabetKeyPress: function(keyEvent) {
        const key = keyEvent.event.key;
        var foundRecordIndex = this.view.getStore().findBy(function(record) {
            return record.get('title').toLowerCase().indexOf(key) === 0;
        }, this);
        if(foundRecordIndex > -1) {
            this.setPosition(foundRecordIndex, keyEvent);
        }
    }
});

Ext.application({
    name: 'Fiddle',

    launch: function () {
        Ext.define('ListItem', {
            extend: 'Ext.data.Model',
            fields: [{
                name: 'src',
                type: 'string'
            }, {
                name: 'caption',
                type: 'string'
            }]
        });

        Ext.create('Ext.data.Store', {
            id: 'ListItemsStore',
            model: 'ListItem',
            data: [{
                title: "One"
            }, {
                title: "Two"
            }, {
                title: "Three"
            }, {
                title: "Four"
            }, {
                title: "Three"
            }, ]
        });

        var imageTpl = new Ext.XTemplate(
            '<tpl for=".">',
            '<div style="margin-bottom: 10px;" class="thumb-wrap">',
            '<span>{title}</span>',
            '</div>',
            '</tpl>'
        );

        Ext.create('Ext.view.View', {
            store: Ext.data.StoreManager.lookup('ListItemsStore'),
            tpl: imageTpl,
            itemSelector: 'div.thumb-wrap',
            emptyText: 'No images available',
            // Search Record Field
            searchRecordField: 'title',
            renderTo: Ext.getBody()
        });
    }
});