Closing dropdown from child element causes Ember to skip child element action
See original GitHub issueNot sure if it is a good place to ask this question it maybe not this plugin’s fault.
So here is the deal: I have dropdown content yielded to parent element and I want that when user click on any link in that content, dropdown would be closed. I do this by first registering dropdown with my component:
<div class="{{dropdownWrapperClass}}">
{{#basic-dropdown registerAPI=(action 'registerDropdown') as |dropdown|}}
{{#dropdown.trigger}}Trigger{{/dropdown.trigger}}
{{#dropdown.content renderInPlace=true}}
<ul class="{{dropdownMenuClass}}" {{action 'mouseDown' on='click'}}>
{{yield}}
</ul>
{{/dropdown.content}}
{{/basic-dropdown}}
</div>
Then when mouseDown
action is called, I check if e.target
is a link or button, here is component code:
mouseDown: function(e) {
const $target = Ember.$(e.target);
const ul = $target.parents(`.${this.get('dropdownMenuClass')}`)[0];
if ($target.is('button, a:link') && ul) {
this.get('dropdown').actions.close();
}
return false;
},
actions: {
registerDropdown: function(dropdown) {
this.set('dropdown', dropdown);
},
}
When I do this, dropdown gets closed but the action that was assigned on the link does not get executed.
Now there is a workaround for this problem:
Ember.$(ul).css('opacity', '0'); // Hide the dropdown.content so the action will seem immediate to user
Ember.run.later(() => {
Ember.$(ul).css('opacity', '1');
self.get('dropdown').actions.close(); // Now really close it
}, 100);
However I don’t like solutions based on some magic timeouts.
I dug into the code of previous plugin that I’ve used: rl-dropdown, looks like they’ve toggled display: none/block css property to control visibility of dropdown.content which worked fine.
I think that this use case is quite common, you do need to close dropdown when child of content is clicked, so there are couple of things I would like to suggest:
- It would be nice to add similar functionality that rl-dropdown has, that will allow users of plugin pass selector which will cause dropdown to close on matching elements, basically:
{{#dropdown.content closeOnClickClick='.button'}}
- If there is no way to add close event to the end of Ember event call chain (I don’t know any) then I think we are stuck with current solution. Unless you think that it is possible to change the way dropdown is closed right now by manipulating visibility instead not rendering content at all.
Issue Analytics
- State:
- Created 7 years ago
- Comments:5 (3 by maintainers)
When I did something similar, I did it by yielding the dropdown API and using it inside my links.
Then where I use my wrapper:
If you want to hide this logic you can encapsulate this link in a contextual component, which is a fantastic technique:
and then
I find this last approach very elegant.
Thanks for the suggestion, you’re right I’ll just pass
dropdown
. I’ve triedEmber.run.next
andEmber.schedule
but it didn’t help. Anyway I don’t think it is really related to the plugin, so I’ll close the issue now, thanks for the help! However it might be good idea to add my example to the documentation you’re working on, I imagine some people would have similar problem.