Skip to content

Instantly share code, notes, and snippets.

@bettysteger
Last active August 29, 2015 14:04
Show Gist options
  • Save bettysteger/a21a4151ac69935543b7 to your computer and use it in GitHub Desktop.
Save bettysteger/a21a4151ac69935543b7 to your computer and use it in GitHub Desktop.
Recursive Menu Directive
/**
* Menu with clickable items (no hover)
* Recursive Menu Directive (needs $compile)
* @see http://stackoverflow.com/questions/19962872/recursive-menu-directive
* @example
* <menu menu="[{ title: 'Home'}, { title: 'Projects', submenu: [{ title: 'Project1' }] }]"></menu>
*/
app.directive('menu', ['$compile', '$document', '$timeout', function ($compile, $document, $timeout) {
'use strict';
/**
* Hides all sub menus except the current clicked item
* @param {Object} scope current scope with menu array
* @param {Object} clickedItem
*/
var hideSubMenus = function(scope, clickedItem) {
angular.forEach(scope.menu, function(item, key) {
if(item.submenu && item.showSubMenu && item !== clickedItem) {
$timeout(function() {
item.showSubMenu = false;
});
}
});
};
return {
restrict: 'E',
replace: true,
scope: {
css: '@class',
menu: '='
},
template: '<ul ng-class="css">'+
'<li ng-repeat="item in menu" '+
'ng-click="toggleSubMenu(this)" ng-class="{showSubMenu:item.showSubMenu}">'+
'<a href="" ng-href="{{item.submenu ? \'\' : item.path}}">'+
'{{item.title}}'+
'<i ng-if="item.submenu" class="fa fa-angle-right"></i>'+
'</a>'+
'<menu ng-if="item.showSubMenu" menu="item.submenu"></menu>'+
'</li>'+
'</ul>',
compile: function (tElement) {
var contents = tElement.contents().remove();
var compiled;
// need to use pre and post return functions
// @see http://docs.angularjs.org/api/ng.$compile
return {
pre: function preLink(scope, iElement) {
scope.toggleSubMenu = function(s) {
if(!s.item.submenu) { return; }
hideSubMenus(scope, s.item);
s.item.showSubMenu = !s.item.showSubMenu;
};
// hide all submenus if click is elsewhere
$document.bind('click', function(event){
var isClickedMenuElementChild = iElement.find(event.target).length > 0;
if (isClickedMenuElementChild) { return; }
hideSubMenus(scope);
});
},
post: function postLink(scope, iElement) {
if(!compiled) {
compiled = $compile(contents);
}
compiled(scope,function(clone) {
iElement.append(clone);
});
}
};
}
};
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment