AngularJS multilevel dropdown menu for a menu structure generated from a recursive directive
This is what I use and it has a lot of extra functionality that is pretty sweet.See the usage $scope.menu
and what happens when you expand the dropdown - you can put in headers, dividers, and even attach click functions. Note that you can nest as many ul
as you want, and though toggle does work, it's useless since clicking to open a submenu will hide its parent. As far as I know, you would need to create your own javascript handler or custom css using hovers if you want deeper nesting in the menu.
<nav> <div menu="menu"></div> <!-- the element here doesn't matter --></nav>
js:
var app = angular.module('myApp', ['ui.bootstrap']);app.directive('menu', function() { return { restrict: 'A', scope: { menu: '=menu', cls: '=ngClass' }, replace: true, template: '<ul><li ng-repeat="item in menu" menu-item="item"></li></ul>', link: function(scope, element, attrs) { element.addClass(attrs.class); element.addClass(scope.cls); } };});app.directive('menuItem', function($compile) { return { restrict: 'A', replace: true, scope: { item: '=menuItem' }, template: '<li active-link><a href={{item.href}}>{{item.title}}</a></li>', link: function (scope, element, attrs) { if (scope.item.header) { element.addClass('nav-header'); element.text(scope.item.header); } if (scope.item.divider) { element.addClass('divider'); element.empty(); } if (scope.item.submenu) { element.addClass('dropdown'); var text = element.children('a').text(); element.empty(); var $a = $('<a class="dropdown-toggle">'+text+'</a>'); element.append($a); var $submenu = $('<div menu="item.submenu" class="dropdown-menu"></div>'); element.append($submenu); } if (scope.item.click) { element.find('a').attr('ng-click', 'item.click()'); } $compile(element.contents())(scope); } };});app.controller('myCtrl', function($scope) { $scope.menu = [ { "title": "Home", "href": "#" }, { "title": "About", "href": "about" }, { "title": "History", "href": "about/history" }, { "title": "Contact", "href": "contact" }, { "title": "Other things - in a list. (Click here)", "submenu": [ { "header": "Sample Header" }, { "title": "Some Link", "href": "some/place" }, { "title": "Another Link", "href": "some/other/place" }, { "divider": "true" }, { "header": "Header 2" }, { "title": "Again...a link.", "href": "errrr" }, { "title": "Nest Parent", "submenu": [ { "title": "nested again", "href": "nested/again" }, { "title": "me too", "href": "sample/place" } ] } ] } ];});
Update for nested dropdown:
.dropdown-menu .dropdown-menu { margin: 0; left: 100%; top: -5px;}.dropdown-menu li:hover .dropdown-menu { display: block;}