0

I feel like I understand focus():

  • When trying to focus on a form element, like input, it "just works", so long as the document is ready.
  • When trying to focus on a non-form element, like div, you must add a tabindex attribute.
    • tabindex adds the ability to tab to an element in precedence order (higher number the better), 0 and up. However, there's a special value, -1, that explicitly removes the element from the tab order.
  • When calling focus programmatically, do so within a setTimeout.
    • Be sure to make a setTimeout value large enough that it waits for display animations to finish, but not so late that the user has time to do other things, like click or type elsewhere.

Pretty simple, really, right? But no. It just doesn't work for me.

My specific use-case is that I have a key-nav-enabled widget that, if you hit the right key, opens a pop-over modal widget. It works great. But I can't get that modal widget to take focus. That modal widget that has no form inputs (just some text and a close link). I've added keydown/up/press events to the modal widget, I've added tabindex to various nodes and tried to focus them, but the original widget still gets the keyboard events.

DOM-wise, the modal widget, despite being new'd up within the keynav widget, is attached to the DOM at the body level, so it's not like the keyboard events are bubbling up through my modal dialog and should be stopPropagation'd, it's never getting those events.

What this means is that if you hit another key before you click in the modal widget, it opens a different modal dialog underneath the first modal dialog!

I really hope I'm missing something about focusing divs, because I have several pieces of functionality I'd like to implement that just aren't working due to (I believe) focus requests simply being ignored.

Help! What am I missing?

inanutshellus
  • 9,683
  • 9
  • 53
  • 71
  • Can you just keep a modalOpen variable? – Zack Argyle Jul 14 '14 at 04:09
  • @Gabriel Can you have look at this [link](http://stackoverflow.com/questions/6291585/jquery-ui-modal-dialog-set-focus-on-first-form-element). Though it is related to **jquery** , the concepts discussed there might help you to solve the issue. Hope it helps. – frank Jul 14 '14 at 10:42
  • @Gabriel. What I understood from the post is that, the focus should be initialized only when the modal dialog is visible. If you apply the focus before the modal dialog is visible it won't work, since there is no such element available to be focussed. This happens if you call the focus method on an event in the main window, which gets fired before the modal window is made visible. So there should be some method ( like show(), modalvisible() ) on the modal dialog that would be called after the modal dialog is visible. This shud enable to add the focus method inside n get the focus on the modal – frank Jul 14 '14 at 11:16
  • I have this scenario very often (with modal dialogs) and have no problems with setting the focus to the whole domNode of the widget. Just make sure you have tabIndex="0" set in the template and as per Franks's suggestion, make sure you set the focus after the domNode is placed in body and made visible. Additionally, though not relevant to your problem, use role="dialog" for accessibility. – belzebu Jul 15 '14 at 02:35

1 Answers1

0

In the specific case I was sleuthing out, I effectively had a typo.

I was doing this, which wasn't working:

 setTimeout(lang.hitch(this, this.domNode.focus), 100);

But this worked:

 setTimeout(function() { this.domNode.focus() }, 100);

That said, I've had a number of issues with focus that regularly make me dread ever having to use it programmatically.

Hopefully though, the list of tips in the question will be helpful to someone.

inanutshellus
  • 9,683
  • 9
  • 53
  • 71