Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

modal: If something within a modal gets itself the focus then that focus is lost after the animations finish. #4903

Closed
arkarkark opened this issue Nov 14, 2015 · 7 comments

Comments

@arkarkark
Copy link
Contributor

If you have directives inside your modal content that selectively get the focus then all that is lost when the modal finishes loading. (this is a regression somewhere between v0.12.1 and v0.14.2).

@icfantv
Copy link
Contributor

icfantv commented Nov 14, 2015

@arkarkark, when you say "selectively gets the focus" do you mean that you are setting the focus programmatically? If so, where does that code live? If not, what is your focus expectation?

The $uibModal.open({...}).rendered is a promise that is executed when the modal is finished rendering. The correct behavior would be to call the focusing code in this block.

Please let us know. Thanks.

@arkarkark
Copy link
Contributor Author

Hi @icfantv thanks for the quick reply.

Let's say my modal is an item picker - if there are no items I want the focus to be on the 'create new item' button but if there are items I want the focus to be on the select where I can choose one.

I can't use autofocus attribute for this. but I can use a focus-when directive that looks at its attribute and if it's true gives the element focus.

That all happens as the modal is rendering, then it finishes as this code I wrapped in an if block steals the focus and gives it to the modal div.

I can imagine many other situations where I'm using components where I can't get the element I want to have focus to have an autofocus attribute, but I can programmatically find it and call focus() on it.

It's interesting that you mention the rendered promise, because even that isn't good enough anymore, because the focus isn't stolen until after the animation promise is resolved which is after the rendered promise is resolved (I was going to submit a PR to fix that too). There's no way outside of the modal to know when the animation promise is finished so even if you have no css animations, you still need to wrap your callback to the rendered promise in a $timeout to get it past the animation promise.

But using the rendered promise (even if it worked properly) or some surfaced animationComplete promise is much more frustrating for someone who only deals with the modal templates - right now they can use directives to say 'this' should have focus if these conditions are met. But if we're forced to use rendered we need to throw some rendered variable on the scope and wait until that becomes true before doing our logic. more watches, more focus flickering (which the comment near the modified code appears to indicate is very bad on mobile w.r.t. on screen keyboards).

@icfantv
Copy link
Contributor

icfantv commented Nov 15, 2015

@arkarkark, I freely admit that animations are not my strong suit, but my cursory searching indicates that there are animation events for which you can listen to determine when the animation has completed.

I'd have to do some more research here but am wondering if this is an impossible-to-solve race condition and whether or not some of these things will happen in a non-deterministic fashion due to browser/computer/network speed.

@arkarkark
Copy link
Contributor Author

I think the short of it is. If something in the modal already has focus, why steal it away?

@icfantv
Copy link
Contributor

icfantv commented Nov 15, 2015

Without looking at our code, I can't say if we are or are not. If we are, we may have a reason (and perhaps it was an unintended side affect of another fix).

@wesleycho
Copy link
Contributor

So we do have logic for handling this particular scenario here

If this is indeed broken, it would be simple to recreate a Plunker - I cannot recreate this based on current master here, it seems to function fine.

Edit: read the prior comments carefully - I think some valid points are brought up.

@wesleycho wesleycho added this to the 1.0.0 milestone Nov 15, 2015
@RosanaRufer
Copy link

It seems to not properly work on Internet Explorer.
The keyboard cursor gets misplaced, it seems to start focusing before the animation is finished. If we disable animation then it is correctly placed. Also, if you move the mouse pointer it sometimes places properly.
I reproduced using your Plunker too:

bug-ie-uib-modal

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants