Here is my existing working code. This works fine apart from the fact that if I click outside of the submenu, when it's open, the sub-menu remains open.
class UserTypeDropdown extends React.Component
constructor: (props) ->
super(props)
@state =
display_submenu: false
@propTypes:
selected: React.PropTypes.string.isRequired
submenu_display:->
if @state.display_submenu
'block'
else
'none'
button_class_names:->
classNames(
'select-btn ': true,
'user_role ': @props.selected is 'user',
'admin_role ': @props.selected is 'admin'
)
selected_text:->
if @props.selected == 'user'
'User'
else
'Administrator'
render:->
div {className: 'user-type-dropdown'},
button { className: @button_class_names(), onClick: @_toggleSubmenu },
@selected_text()
ul {className: 'submenu submenu_content access_submenu', style: {display: @submenu_display()}},
li {onClick: @select_admin},
a {},
'Administrator'
li {onClick: @select_user},
a {},
'User'
_toggleSubmenu: =>
@setState display_submenu: !@state.display_submenu
select_admin: =>
@_toggleSubmenu()
actions.setUserRole('admin')
select_user: =>
@_toggleSubmenu()
actions.setUserRole('user')
I want to implement that clicking outside of the submenu when it's open, closes it.
I've read into how to do this in React and I've come across a lot of suggestions that say I should use onFocus and onBlur instead of onClick
This makes sense to me as it means the drop-down should only be open when it's in focus in the browser. So my render function & methods become.
render:->
div {className: 'user-type-dropdown'},
button { className: @button_class_names(), onFocus: @_toggleSubmenu, onBlur: @_toggleSubmenu },
@selected_text()
ul {className: 'submenu submenu_content access_submenu', style: {display: @submenu_display()}},
li {onClick: @select_admin},
a {},
'Administrator'
li {onClick: @select_user},
a {},
'User'
_toggleSubmenu: =>
@setState display_submenu: !@state.display_submenu
select_admin: =>
actions.setUserRole('admin')
select_user: =>
actions.setUserRole('user')
However with onFocus:
and onBlur:
on the button
element,
Now clicking on either of the li
's wont trigger the @select_admin
or @select_user
it just triggers @_toggle_submenu
and the click doesn't seem to propigate / bubble down to the li
element underneath..
From reading the React Event Documentation and This Focus and hotkeys guide I can see that the events should bubble down but for me they simply aren't.
I'm new to the React Coffescript/JS world so forgive any incorrect naming conventions.
I think my understanding must be flawed because I can't find an answer anywhere to this problem.
Any help would be greatly appreciated.
Your issue is: as soon as you click an item, the onBlur event fires first. This causes a re-render (because you do setState
). And therefore your onClick event is never run.
The way to solve this (with onFocus and onBlur), is to rearrange your HTML setup:
<button>
is already OK)<li>
is OK)That way your Main menu item does not lose focus if you click one of the sub-items.
You can find a simple (HTML and javascript only) JSBIN example here.