I would like to build a flyout tree menu that adds an active
class to elements on hover, and removes it when any of their siblings are hovered.
This way, the menu will stay open when the user mouses away from it.
The flyout menu is recursive because it could be any number of levels deep.
In order to remove a class from siblings, I must have some knowledge of their parent or sibling status. Would prefer to do this with the data structure, but will use DOM traversal if needed.
I have tried:
- Using scope.$parent in the hover handler (but the scope the handler knows about is the directive scope, not the ng-repeat scope)
- Passing the event to the hover handler and calling
$(evt).siblings()
(but angular yells, saying I cannot access the DOM from an expression) - setting a .parent property in the local ng-repeat scope (but the event handler does not have access to these values that the template inherits)
- Using a recursive directive, so every leaf in the tree is another directive. This explodes the browser. (I think because it tries to compile the directive before looking for the exit condition on the loop)
- Adding a controller to every leaf in the tree. This makes the scope tree large, and doesn't provide a clean way to access siblings. It is functional though. See my answer below.
I have no idea how to do this in Angular. To do this in jQuery is so simple: $(e.target).siblings().removeClass('active')
. How can I get this done?
I've made a Plunker to demonstrate the issue with accessing siblings in a recursive ng-repeat: http://plnkr.co/edit/vBYYt6sTvWKN9TXz9SC5?p=preview