I have a text input on my page. When it receives focus, a select box appears underneath it. When it loses focus, I want the select box to disappear unless the focus has shifted to the select box. Sounds simple enough but I struck a problem.
I set up the event handlers like so (using coffeescript)
jQuery ->
$('td.description input').focus -> showItemSelector()
$('td.description input').blur -> hideItemSelector()
showItemSelector()
and hideItemSelector()
are defined like so
showItemSelector () ->
$('#item-selector').show()
hideItemSelector () ->
unless $('#item-selector select').is(':focus')
$('#item-selector').hide()
But it doesn't work. The item selector is always hidden after the input loses focus. I did some experimenting and my suspicion was confirmed. The hideItemSelector
function is being executed before focus is shifted to the new element (which makes some sense - the browser presumably takes focus from the first element, triggering my function, before it assigns focus to the next element). The following bit of code demonstrates this;
hideItemSelector = () ->
focus = -> console.log $('select#category').is(':focus')
focus()
setTimeout focus, 1000
This returns false and then true in the console. The delay gives the browser time to shift the focus.
So my question is, how can I do what I want to do without using a setTimeout? If nothing else works then this will have to do, but it seems like a flawed approach.