最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Programmatically tab to next control in Ext JS - Stack Overflow

programmeradmin1浏览0评论

I've written a wrapper UX control in Ext JS 2.x around Ext.Form.DateField to handle keypresses slightly differently. In particular, when the calendar is on display, I want the Tab key to select the highlighted date and move to the next form field.

I've got the key handler working – it selects the highlighted date and closes the calendar – but I can't get it to tab to the next field.

Do I have to work out what the next field is from the tab order and try to set its focus? That seems rather convoluted. Or can I fire some event to get my control to tab to the next field automatically (i.e. capture the Tab keypress in the calendar and process it, as I am doing, but then forward it to the underlying date field)?


Edit: In summary, is there an Ext (or, at least cross-platform) way to fire a keyboard event at a particular form field?

I've written a wrapper UX control in Ext JS 2.x around Ext.Form.DateField to handle keypresses slightly differently. In particular, when the calendar is on display, I want the Tab key to select the highlighted date and move to the next form field.

I've got the key handler working – it selects the highlighted date and closes the calendar – but I can't get it to tab to the next field.

Do I have to work out what the next field is from the tab order and try to set its focus? That seems rather convoluted. Or can I fire some event to get my control to tab to the next field automatically (i.e. capture the Tab keypress in the calendar and process it, as I am doing, but then forward it to the underlying date field)?


Edit: In summary, is there an Ext (or, at least cross-platform) way to fire a keyboard event at a particular form field?

Share Improve this question edited Jan 7, 2018 at 6:34 Dmitry Pashkevich 13.5k10 gold badges58 silver badges75 bronze badges asked Oct 21, 2012 at 9:59 Matthew StrawbridgeMatthew Strawbridge 20.6k10 gold badges79 silver badges96 bronze badges 4
  • you can use dispatchEvent(), this may be related: stackoverflow./questions/596481/… – pckill Commented Oct 21, 2012 at 11:22
  • @pckill That's certainly interesting, although from the ments it sounds as if it only works on certain browsers. Is there a more "Exty" way to achieve the same thing? – Matthew Strawbridge Commented Oct 21, 2012 at 11:29
  • I haven't worked with ExtJS, but if you know what is the next form field, couldn't you use a method like .focus() or .select() on it when pressing the Tab key? It would be easier to help you if you could provide some code that you used already. – micnic Commented Oct 26, 2012 at 13:36
  • @micnic I know the field that should be tabbed away from, but not the next one (since the datefield is a ponent that can be embedded in any page). I could probably work out the next field manually, but it would be difficult to get it to work with custom tab orders. I'd rather just get the original text field to handle the tab in the normal way. But I'm having problems trapping the message in the calendar panel but getting it subsequently processed by the textbox control related to it. – Matthew Strawbridge Commented Oct 26, 2012 at 19:35
Add a ment  | 

1 Answer 1

Reset to default 6 +50

Approach I. Just don't do event.preventDefault() in your keypress/keyup event handler so you don't block the browser from performing the default action, i.e. tab-navigation. This example works:

Ext.create('Ext.form.Panel', {
    title: 'Contact Info',
    width: 300,
    renderTo: Ext.getBody(),
    items: [{
        xtype: 'textfield',
        name: 'name',
        fieldLabel: 'Name',
        listeners: {
            specialkey: function(me, e) {
                if (e.getKey() == e.TAB) {
                        console.log('Tab key pressed!');
                        // do whatever you want here just don't do e.preventDefault() or e.stopEvent() if you want the browser tab to next control
                    }
            }
        }
    }, {
        xtype: 'textfield',
        name: 'email',
        fieldLabel: 'Email Address',
    }]
});

I tried it in Ext 4 but all the essential methods should be available since Ext 2. If you still experience issues please share some of your code.

Getting out of the way and letting the browser do its stuff natively is usually the best and the most robust solution...


Approach II. If you have a plicated ponent with multiple elements, you can still achieve the case of Approach I. by forcing the focus on the main input element (usually a text field) while simulating focusing items inside a popup element with CSS (a KeyNav/KeyMap in the main input element would be handy here). You just basically catch all the cases where the user may set the focus on a popup (like clicking on it) and snap the focus back to your main element.

This would still ensure the natural tab order of html elements, even if some of them are not Components. I believe that's the best way to go and worth struggling to achieve most of the time.

That's the way ponents like ComboBox and DatePicker work (as you can see the latter just always sets focus to the main element after the vaule is updated. The focus logic of a ComboBox is a bit more plicated. Take a look at the source code links if you're confused about how to implement it in your ponent, very insightful.


Approach III. Last resort. If you still need to just programmatically focus another (neighbour) field, that's relatively easy to do. Code for Ext 2.3 (didn't test it though, I was using the docs):

var formPanel,  // containing form panel
    currentField, // the field you need to navigate away from

    fields,
    currentFieldIdx,
    nextField;

fields = formPanel.getForm().items;
currentFieldIdx = fields.indexOf(currentField);

if(currentFieldIdx > -1) {
    nextField = fields.itemAt(currentFieldIdx + 1);
    nextField && nextField.focus();
}

P.S. You can artificially fire the Tab key press via dispatchEvent() but it will not trigger the tab-navigation action due to security reasons.

发布评论

评论列表(0)

  1. 暂无评论