Skip to main content

Search and Top Navigation

#8192 closed bug (notabug)

Opened March 13, 2012 08:19PM UTC

Closed April 04, 2012 01:26AM UTC

Last modified April 04, 2012 08:11PM UTC

IE Focus error when element is hidden

Reported by: dkonopacki Owned by:
Priority: minor Milestone: 1.9.0
Component: ui.datepicker Version: 1.8.18
Keywords: Cc:
Blocked by: Blocking:

When a UI element or its parent is set to visibility:hidden, IE is throwing:

Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus.

Specifically, if attempting to create a Datepicker instance on an input[type="text] field whose parent is set to hidden, JQuery UI core does a .is(':visible') check on the element itself, which is returning the hidden object and causing IE to error. Please see this JSFiddle test case:

The Datepicker target element is hidden because its parent DIV element is hidden, but .datepicker('show') still triggers .focus().

The offending line, though, occurs in UI.Core, Line 8512. Try/catch should be used, as it is the most backwards compatible option for IE.

Please see the following for further details:

Attachments (0)
Change History (7)

Changed April 04, 2012 01:26AM UTC by scottgonzalez comment:1

component: ui.coreui.datepicker
resolution: → invalid
status: newclosed

You shouldn't be calling show on a datepicker that's attached to an element which cannot receive focus.

Changed April 04, 2012 02:41AM UTC by dkonopacki comment:2

While I agree that datepicker should not receive an execution for "show" on an element that is hidden, I disagree that the defect is invalid. There should still be a check for visibility on the element and ancestor elements. UI.Core already does this, so there's little reason why Datepicker should not do it for consistency.

Changed April 04, 2012 02:46AM UTC by scottgonzalez comment:3

What specifically are you referring to when you say UI.Core already does this?

Changed April 04, 2012 05:26AM UTC by dkonopacki comment:4

In the definition for the focusable function (jquery.ui.core), part of the check to test whether or not an element can receive focus is to check its visibility. Line 184 contains the comment, "the element and all of its ancestors must be visible". It would seem inconsistent that in the core there would be a test for visibility on the called element and all ancestors, but in datepicker the test for an element about to receive focus is simply "is this element visible". There doesn't seem to be a plausible reason why one function should have an ancestor check, but another does not. Especially since datepicker does check for some sort visibility before trying to call focus.

Additionally, if the code is not modified I would argue that the defect still stands as "valid" because the documentation is incorrect. Nowhere does the datepicker docs state that a form field using datepicker is required to be visible. In our use case, a different action other than focusing on the element to which datepicker was attached caused the datepicker to display. Additional confusion was caused by the fact that only IE manifested the problem. If calling "show" requires the element to be visible, though I'm doubtful since the code partially supports checking for visibility before setting focus, then it might be best to clearly state this.

Changed April 04, 2012 11:57AM UTC by scottgonzalez comment:5

The focusable selector is not related to actually setting focus (other than you might use it to determine which element to automatically focus in some scenarios).


Changed April 04, 2012 08:02PM UTC by dkonopacki comment:6

And why is "show" on datepicker actually setting focus on the element? Shouldn't that be at least configurable? I feel that saying "focusable selector is not related to actually setting focus" is an irrelevant argument, as there isn't any specific reason for calling focus on the attached element. When "show" executes, a div is appended to the body that is independent of the element associated with the plugin. I'm missing the justification for even executing focus on the bound element.

Further, the comments you reference only apply insofar as dismissing the use of try/catch. Based upon the argument presented, I can agree with that. But, reply #4 of that same thread should be the one referenced. If the point of calling "show" was specifically execute a focus() command, I could agree with your last statement. But the intended purpose is to "[c]all up a previously attached date picker". The problem still resides with the plugin - either the code is wrong and should check for visibility on all ancestors before calling focus, calling focus shouldn't happen at all or be configurable, or the documentation needs to change to reflect the fact that "show" can only be called from a datepicker bound element that is visible.

Changed April 04, 2012 08:11PM UTC by scottgonzalez comment:7

I added a note to the documentation.

The input gets focus because users are allowed to type a date.