Wiring up a nav menu with Angular routes - angularjs

I'm working with an asp.net mvc4 and Angular JS (started from John Papa's HotTowel.angular.Breeze SPA). I have added a dropdown menu to the sidebar.html, and have also added the appropriate routes to config.route.js.
I find the tricky part is to properly wire-up the dropdown menus to the Angular routes.
This setup is mostly working, except that when I click on the "MR Reports" dropdown menu below, it's right-away firing a route (i.e. when I hover over MR Reports, it shows the link "localhost:49479/index.html#". In other words, the "MR Reports" should be a dropdown menu and NOT trigger a route change until I choose a dropdown menu item.
I'm not sure if the change should be in config.route.js or in the sidebar.html code.
UPDATE:
I'm assuming I can use the Angular ngHref directive, something like ng-href="#{{r.url}}", to dynamically exclude the top-level href tag if there's a sub menu.
Perhaps I can use ng-if="r.config.sub" as a guide as well.
Here is the contents of config.route.js (please note the "sub:" section for the sub-menus):
(function () {
'use strict';
var app = angular.module('app');
// Collect the routes
app.constant('routes', getRoutes());
// Configure the routes and route resolvers
app.config(['$routeProvider', 'routes', routeConfigurator]);
function routeConfigurator($routeProvider, routes) {
routes.forEach(function (r) {
$routeProvider.when(r.url, r.config);
});
$routeProvider.otherwise({ redirectTo: '/' });
}
// Define the routes
function getRoutes() {
return [
{
url: '/',
config: {
templateUrl: 'app/dashboard/dashboard.html',
title: 'dashboard',
settings: {
nav: 1,
content: '<i class="fa fa-dashboard"></i> Dashboard'
}
}
}, {
url: '/admin',
config: {
title: 'admin',
templateUrl: 'app/admin/admin.html',
settings: {
nav: 2,
content: '<i class="fa fa-lock"></i> Admin'
}
}
},
{
url: '/testgrid',
config: {
title: 'grids',
templateUrl: 'app/testgrid/testgrid.html',
settings: {
nav: 3,
content: '<i class="fa fa-globe"></i> TestGrid'
}
}
},
{
config: {
title: 'reports',
templateUrl: 'app/testgrid/testgrid.html',
settings: {
nav: 4,
content: '<i class="fa fa-plus-square "></i> MR Reports <b class="caret"></b>'
},
sub: [
{
url: '/testgrid',
title: 'reports1',
templateUrl: 'app/testgrid/testgrid.html',
settings: {
content: 'TestGrid'
}
},
{
url: '/admin',
title: 'Admin2',
templateUrl: 'app/admin/admin.html',
settings: {
content: 'Admin2'
}
}
]
},
}
];
}
})();
and my sidebar.html is defined as :
<div data-cc-sidebar data-ng-controller="sidebar as vm">
<div class="sidebar-filler"></div>
<div class="sidebar-dropdown">Menu</div>
<div class="sidebar-inner">
<div class="sidebar-widget">
</div>
<ul class="navi">
<li class="nlightblue fade-selection-animation"
ng-class="{dropdown: r.config.sub}"
data-ng-repeat="r in vm.navRoutes">
<a href="#{{r.url}}" data-ng-bind-html="r.config.settings.content" ng-class="{'dropdown-toggle': r.config.sub}" data-ng-class="vm.isCurrent(r)" data-toggle="dropdown" ></a>
<ul ng-if="r.config.sub" class="dropdown-menu">
<li ng-repeat="submenu in r.config.sub">
</li>
</ul>
</li>
</ul>
</div>

I'm not crazy about my hack, but it ended up working. I used one ng-if to render the href link for non-dropdown menu items, and another ng-if to EXCLUDE the href tag for the dropdowns.
And in the getRoutes() function, I EXCLUDE the url: property at the top-level of the dropdown.
<ul class="navi">
<li class="nlightblue fade-selection-animation"
ng-class="{dropdown: r.config.sub}"
data-ng-repeat="r in vm.navRoutes">
<a ng-if="r.url" href="#{{r.url}}" data-ng-bind-html="r.config.settings.content"
ng-class="{'dropdown-toggle': r.config.sub}"
data-ng-class="vm.isCurrent(r)"
data-toggle="dropdown" ></a>
<a ng-if="r.config.sub" data-ng-bind-html="r.config.settings.content"
ng-class="{'dropdown-toggle': r.config.sub}"
data-ng-class="vm.isCurrent(r)"
data-toggle="dropdown" ></a>
<ul ng-if="r.config.sub" class="dropdown-menu">
<li ng-repeat="submenu in r.config.sub">
</li>
</ul>
</li>
config.route.js function:
function getRoutes() {
return [
{
url: '/',
config: {
templateUrl: 'app/dashboard/dashboard.html',
title: 'dashboard',
settings: {
nav: 1,
content: '<i class="fa fa-dashboard"></i> Dashboard'
}
}
}, {
url: '/admin',
config: {
title: 'admin',
templateUrl: 'app/admin/admin.html',
settings: {
nav: 2,
content: '<i class="fa fa-lock"></i> Admin'
}
}
},
{
url: '/testgrid',
config: {
title: 'grids',
templateUrl: 'app/testgrid/testgrid.html',
settings: {
nav: 3,
content: '<i class="fa fa-globe"></i> TestGrid'
}
}
},
{ // Exclude url: at this top level
config: {
title: 'reports',
settings: {
nav: 4,
content: '<i class="fa fa-plus-square "></i> MR Reports <b class="caret"></b>'
},
sub: [
{
url: '/testgrid',
title: 'reports1',
templateUrl: 'app/testgrid/testgrid.html',
settings: {
content: 'TestGrid'
}
},
{
url: '/admin',
title: 'Admin2',
templateUrl: 'app/admin/admin.html',
settings: {
content: 'Admin2'
}
}
]
},
}
];
}

Related

Angular UI-Router: nested views

I have two col layout with header and footer. Header has page navigation (GetStarted, Component). Of the 2 columns, one is for sidenav and other is for main content.
When "GetStarted" nav is active, sidenav is populated with respective links (overview, examples)
When "Component" nav is active, sidenav is populated with respective links (checkbox, alert)
Upon clicking "Overview" link area is populated with its data
<ul class="nav nav-tabs">
<li role="presentation" class="active">Default</li>
<li role="presentation">Disabled</li>
</ul>
<section class="content__main__tab__content col-xs-12 col-sm-12 col-md-12 col-lg-12">
<form id="checkbox--default">
<div class="input__checkbox--default" id="checkbox--default">
<!-- <div class="form-group"> -->
<fieldset>
<legend>Default</legend>
<label for="gi-checkbox">Checkbox Label
<div class="checkbox-input-wrapper group__input-wrapper">
<input type="checkbox" class="checkbox" id="gi-checkbox">
</div>
</label>
</fieldset>
<!-- </div> -->
</div>
</form>
</section>
Main content has 2 nav tabs for checbox states (default & disable). By clicking the "default" its content must be displayed and same goes for disabled. I'm new to angular and I kinda got first level nested view working. But couldn't the whole thing working. here is the code sample
index.html
<body ng-app="mendouiApp" id="mendo__home" data-spy="scroll" data-target=".scrollspy">
<nav class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" ui-sref="home"><img src="images/gi-logo.png" alt="logo"/></a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a ui-sref="home">Get Started</a></li>
<li><a ui-sref="components">Components</a></li>
</ul>
</div><!-- /.nav-collapse -->
</div><!-- /.container -->
</nav><!-- /.navbar -->
<div class="wrapper" ui-view></div> <!--/.container-->
component.html
<div class="content__wrapper">
<div class="row">
<div class="content__secondary content__secondary--l scrollspy">
<ul id="sidenav-fixed-l" class="nav hidden-xs hidden-sm affix-top" data-spy="affix">
<li>
<h5>COMPONENTS</h5>
</li>
<li ng-repeat="item in componentsList">
<a ui-sref="{{item.link}}" ng-cloak>{{item.name}}</a>
</li>
</ul>
</div>
<div ui-view></div>
</div> <!--/.row-->
</div> <!--/.content-wraper-->
app.js
(function(){
var mendouiApp = angular.module('mendouiApp', ['ui.router', 'ui.router.stateHelper']);
mendouiApp.constant('COMPONENTS_LIST', {
name: 'sidenav',
templateUrl: '../components/components.list.html',
abstract: true,
children: [{
name: 'alerts',
url: '/alerts',
templateUrl: '../components/alerts/alerts.html'
}]
});
mendouiApp.config(function($stateHelperProvider, $urlRouterProvider, $locationProvider, $urlMatcherFactoryProvider, COMPONENTS_LIST) {
$urlMatcherFactoryProvider.strictMode(false);
$urlRouterProvider.otherwise('/home');
$locationProvider.hashPrefix('!');
$stateHelperProvider
.state('home', {
url: '/home',
templateUrl: '../gettingstarted.html',
controller: 'getStartedController'
})
.state('layouts', {
url: '/layouts',
templateUrl: '../layouts.html'
})
.state('screenpatterns', {
url: '/screenpatterns',
templateUrl: '../screenpatterns.html'
})
.state('yogi', {
url: '/yogi',
templateUrl: '../yogi.html'
})
.state('components', {
url: '/components',
templateUrl: '../components.html',
controller: 'componentsController'
})
.state(COMPONENTS_LIST, {
keepOriginalNames: true
})
.state('components.button', {
url: '/button',
templateUrl: '../components/button/button.html'
}) .state('components.checkbox', {
url: '/checkbox',
templateUrl: '../components/checkbox/checkbox.html'
})
.state('components.forms', {
url: '/forms',
deepStateRedirect: true,
sticky: true,
views: {
'': { templateUrl: '..forms.html' },
'inline#components.forms': {
templateUrl: '../components/forms/form-inline/forminline.html'
},
'default#components.forms': {
templateUrl: '../components/forms/form-default/formdefault.html'
},
'multicolumn#components.forms': {
templateUrl: '../components/forms/form-multicolumn/formmulticolumn.html'
}
}
});
// use the HTML5 History API
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
mendouiApp.controller('componentsController', ['$scope', '$state', 'sideNavService', function($scope, $state, sideNavService, COMPONENTS_LIST){
$scope.componentsList = sideNavService.components;
$scope.componentsnav = COMPONENTS_LIST.children;
$scope.go = function(tab) {
$state.go(tab.name);
}
}]);
mendouiApp.controller('getStartedController', ['$scope', '$state', 'sideNavService', 'fixedSideNavService', function($scope, $state, sideNavService, fixedSideNavService ){
$scope.getstartedList = sideNavService.getstarted;
}]);
/*** This is for the external url reference ***/
mendouiApp.run(function($rootScope, $state, $stateParams, $window, fixedSideNavService, copyToClipBoardService) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams, $state, $stateParams) {
if (toState.external) {
event.preventDefault();
$window.open(toState.url, '_self');
}
});
$rootScope.$on('$viewContentLoaded', function(event){
fixedSideNavService.fixedsidenav();
copyToClipBoardService.copytoclipboard();
});
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$state.transitionTo('home');
});
})();
service.js
angular.module('mendouiApp').service('sideNavService', function() {
return {
"getstarted" : [
{
"name" : "Overview",
"link" : "home.overview"
}
{
"name" : "Summary",
"link" : "home.overview"
}
],
"components" : [
{
"name" : "Alerts",
"link" :"components.alert"
},
{
"name" : "Button",
"link" :"components.button"
},
{
"name" : "Button Groups",
"link" :"components.buttongroup"
},
{
"name" : "Button Icons",
"link" :"components.buttonicons"
},
{
"name" : "Checkbox",
"link" :"components.checkbox"
},
{
"name" : "Datepicker",
"link" :"components.datepicker"
},
{
"name" : "Forms",
"link" : "components.forms"
}
]
};
});
Your question was a bit messy, but after a while playing with I could understand I made this fiddle: http://jsfiddle.net/canastro/c4kt2myc/2/ I hope it works as you were expecting.
The main thing to focus on here is:
.state("root.components.button", {
url: '/components/button',
views: {
'main#': {
template: `
<div>
<a ui-sref="root.components.button.default">default</a>
<a ui-sref="root.components.button.disabled">disabled</a>
<div ui-view="buttonsContent"></div>
</div>
`
}
}
})
.state("root.components.button.default", {
url: '/components/button/default',
views: {
'buttonsContent#root.components.button': {
template: 'root.components.button.default'
}
}
})
.state("root.components.button.disabled", {
url: '/components/button/disabled',
views: {
'buttonsContent#root.components.button': {
template: 'root.components.button.disabled'
}
}
})
In the first level you have a abstract route so you can always have your basic layout present.
Then in the Started / Components routes, you load content into the main and side ui-views.
In all of the Started and Component child routes you just override the main views.
And finally, in the last level you need to say you want to fill the content of a ui-view created in the previous state, by doing something like VIEWNAME#STATENAME.

angularjs accordion list anchor alternate elements

I have an accordion list populated as follows:
<ion-list>
<div ng-repeat="day in days"><br>
<div class="item item-icon-left" ng-click="toggleGroup(day)" ng-class="{active: isGroupShown(day)}">
<i class="icon icon-accessory" ng-class="isGroupShown(day) ? 'ion-minus' : 'ion-plus'"></i>
{{day.name}}
</div>
<a class="item item-icon-left item-accordion" ng-show="isGroupShown(day)" ng-repeat="exercise in day.exercises" type="item-text-wrap"
href="#/tab/plan/{{exercise.id}}">
{{exercise.name}}
<!-- Trial LED -->
<span style="float:right;"><i ng-show="{{exercise.watchedToday}}==true" class="ion-checkmark-round"></i></span>
</a>
</div>
</ion-list>
This populates list as follows:
Route which handles this is:
.state('tab.exercise', {
url: '/plan/:exerciseId',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
},
views: {
'tab-plan': {
templateUrl: '/templates/video.html',
controller: 'videoCtrl'
}
},
cache: false
})
However I have few other routes like:
.state('tab.wordschatz', {
url: '/plan/12', <= notice here (this can be 8/9/10/11/12)
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
},
views: {
'tab-plan': {
templateUrl: '/templates/wortschatz.html',
controller: 'wortschatzCtrl',
data: {
css: '/css/wortschatz.css'
}
}
},
cache: false
})
I basically want to navigate to different pages on alternate accordion elements clicks. How can I have separate anchor links for alternate elements?

AngularJs active navigation item Issue

I have in view :
<ul class="nav nav-pills" ng-controller="MenuItemCtrl as vm">
<li ng-repeat="item in names" class="col-lg-2 col-md-2 col-sm-12 col-xs-12" ng-click="select($index)" ng-class="{active: $index == selected}">
<a ng-show="{{item.up===true}}" href="#{{item.link}}">{{item.name}}</a>
</li>
</ul>
and controller like this:
$scope.names = [{
name: "Main",
slug: "main",
active: true,
up:true,
inFooter:false,
link: "/"
}, {
name: "Pets",
slug: "pets",
active: false,
up:true,
link: "/pets"
}, {
name: "LDAdoption",
slug: "ldAdoption",
active: false,
inFooter:false,
up:true,
link: "/ldAdoption"
},{
name: "Impressum",
slug: "impressum",
active: false,
up:false,
inFooter:true,
link: "/impressum"
}, {
name: "Be a volunteer",
slug: "volunteer",
active: false,
inFooter:true,
up:false,
link: "/volunteer"
}, {
name: "Contact",
slug: "contact",
active: false,
up:true,
inFooter:true,
link: "/contact"
}];
$scope.selected = 0;
$scope.select= function(item) {
$scope.selected = item;
};
$scope.isActive = function(item) {
return $scope.selected === item;
};
I can't understand why active state doesn't keeping if I refresh my page. I work with ng-route and everything it's ok , just active state work wrong. Can you help me, please? Thanks!
On startup of your controller, you should fetch current route somehow and select a particular item basing on this route.
For example, you can add slug field to your routes:
$routeProvider.
when('/pets', {
templateUrl: '...',
controller: /*...*/,
slug: 'pets'
}) /* ... */;
And then read it in your controller:
function yourController($scope, $routeParams) {
/*...*/
var selectedSlug = $routeParams.slug;
if (selectedSlug) {
$scope.selected = /* find item by selected slug */
}
}
Add 'slug' to routeParams
$routeProvider.
when('/pageUrl/:slug', {
templateUrl: viewUrl,
controller: someController
});
In Controller
.controller('someController', function ($scope, $routeParams, $location) {
if ($routeParams.slug) {
$scope.selected = $routeParams.slug
}
$scope.select= function(slug) {
$location.path('/pageUrl/' + slug);
};
})
In view:
<ul class="nav nav-pills" ng-controller="MenuItemCtrl as vm">
<li ng-repeat="item in names" class="col-lg-2 col-md-2 col-sm-12 col-xs-12" ng-click="select(item.slug)" ng-show="{{item.up===true}}" ng-class="{active: item.slug == selected}">
{{item.name}}
</li>
</ul>

Multiple views, UI-route issue

Im facing an issue while using(Multiple views, UI-route) widget wise implementation. I have two widgets(named upper and lower widget); in which both the widget have table content showing some details . While I click on the content in upper widgets, it shows a tabular content in that widgets itself but the data under lower widget is missing. Actually we want to display both the widget content without reflecting any issues while clicking on single widget content. Also I’m here by listed out the code which I used on.
Here is my code
code herehttp://plnkr.co/edit/1yczuGbjK5yBOzjzWpk5?p=preview
1:-index page
<div ui-view="mj" style="padding-top: 80px;"></div>
<div ui-view="mj1" style="padding-top: 80px;"></div>
2:-app.js
angular.module('uiRouterSample', [
'uiRouterSample.contacts',
'ui.router'
])
.config(
[ '$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.otherwise('/');
$stateProvider
.state("home", {
url: "/",
views: {
'mj': {
templateUrl: 'tabtable.html'
},
'mj1': {
templateUrl: 'tabtable1.html'
}}
})
}
]
);
3 :-first widget -tabtable.html
<table>
<tr>
<td><a ui-sref="contacts.tab1">1</a></td>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
</tr>
</table>
4 :-2nd widget -tabtable1.html
<table>
<tr>
<td><a ui-sref="contactsmj.tab1mj">1</a></td>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
</tr>
</table>
5:loading widget data -contacts.js
angular.module('uiRouterSample.contacts', [
'ui.router'
])
.config(
[ '$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('contacts', {
abstract: true,
url: '/contacts',
views: {
'mj': {
templateUrl: 'contacts.html',
}
}
}).state('contacts.tab1', {
url: '/tab1',
views: {
'cjtab': {
templateUrl: 'contacts.detail.html'
}
}
})
.state('contacts.tab2', {
url: '/tab2',
views: {
'cjtab': {
templateUrl: 'contacts.detail2.html'
}
}
}).state('contacts.tab3', {
url: '/tab3',
views: {
'cjtab': {
templateUrl: 'contacts.detail3.html'
}
}
}).state('contactsmj', {
abstract: true,
url: '/contactsmj',
views: {
'mj1': {
templateUrl: 'contactsmj.html',
}
}
})
.state('contactsmj.tab2mj', {
url: '/tab2mj',
views: {
'mjtab': {
templateUrl: 'contacts.detail2.html'
}
}
}).state('contactsmj.tab3mj', {
url: '/tab3mj',
views: {
'mjtab': {
templateUrl: 'contacts.detail3.html'
}
}
}).state('contactsmj.tab1mj', {
url: '/tab1mj',
views: {
'mjtab': {
templateUrl: 'contacts.detail.html'
}
}
});
}
]
);
6:-click on corresponding link -1 st widget Content page will be loaded
<div>
<div>
<div>
widget 2 Tabs
<ul>
<li><a ui-sref="contactsmj.tab1mj">widget 2-Tab 1</li>
<li><a ui-sref="contactsmj.tab2mj">widget 2-Tab 2</li>
<li><a ui-sref="contactsmj.tab3mj">widget 2-Tab 3</li>
</ul>
</div>
</div>
<div ui-view="mjtab"></div>
</div>
7:-click on corresponding link -2 nd widget Content page will be loaded
<div>
<div>
<div>
widget 2 Tabs
<ul>
<li><a ui-sref="contactsmj.tab1mj">widget 2-Tab 1</li>
<li><a ui-sref="contactsmj.tab2mj">widget 2-Tab 2</li>
<li><a ui-sref="contactsmj.tab3mj">widget 2-Tab 3</li>
</ul>
</div>
</div>
<div ui-view="mjtab"></div>
</div>
Problem - When you are changing route, your view is getting updated and in the new view you are only mapping either of the named view, because of which the other view is being lost.
There are few possible solution to your problem.
You have to update your parent state(s) in contacts.js. Like
.state('contacts', {
abstract: true,
url: '/contacts',
views: {
'mj': {
templateUrl: 'contacts.html'
},
'mj1': {
templateUrl: 'tabtable1.html'
}
}
Do not change route, simply bind the clicks and get the template, compile it and do the DOM manipulation - not recommended.
There is a solution proposed for parallel views at "https://stackoverflow.com/a/23840379/1132354"

Angular.js Strange Behavior - Button must be clicked twice for drop down menu

In angular.js, I have a button that gives a drop down menu. The issue I am having is, consistently, I have to click on the button twice for drop down menu to appear. The first time I click on the button, I see it light up...so a click registers. But, I have to click on it a second time for the drop down menu to show. What is causing this?
directive:
angular.module('main.vips')
.directive('actionButton', ['ActionButtonService', function(ActionButtonService) {
openAddVipModal = function() {
return $modal.open({
templateUrl: 'vips/addvip.html',
controller: 'AddVipCtrl',
size: 'lg',
windowClass: 'modal-fullscreen vip-modal'
});
}
return {
templateUrl: 'vips/directives/actionButton.html',
restrict: "AE",
replace: true,
transclude: false,
scope: {
'label': "#?",
'icon': "#?",
'type': "#?",
'actions': "=?"
},
link: function(scope, element, attrs) {
scope.actions = ActionButtonService[attrs.type];
}
}
}]);
Service:
angular.module('main.vips')
.factory('ActionButtonService', function() {
var actions = {};
actions.loadbalancer = [
{
label: "Create New VIP",
fn: function() {
return openAddVipModal();
},
icon: "glyphicon glyphicon-plus"
}, {
label: "Add Existing VIP",
icon: "glyphicon glyphicon-search"
}, {
divider: true
}, {
label: "Activate Selected",
icon: "glyphicon glyphicon-play"
}, {
label: "Suspend Selected",
icon: "glyphicon glyphicon-pause"
}, {
divider: true
}
];
actions.vip = [
{
label: "Create New Node",
icon: "glyphicon glyphicon-plus"
}, {
label: "Add Existing Node",
icon: "glyphicon glyphicon-search"
}
];
actions.node = [
{
label: "Edit Node",
icon: "glyphicon glyphicon-plus"
}, {
label: "Node Stuff",
icon: "glyphicon glyphicon-search"
}, {
divider: true
}
];
return actions;
});
Template:
<div class="btn-group action-button-icon" dropdown>
<button type="button" class="btn dropdown-toggle"
ng-class="{'btn-primary page-button': type == 'page',
'btn-primary btn-xs': type == 'vip',
'btn-info btn-xs': type == 'node'}"
id="vip-actions"
data-toggle="dropdown">
<span class="{{ icon }}"></span> {{ label }}
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="vip-actions">
<li role="presentation" ng-repeat="action in actions" ng-class="{'divider' : action.hasOwnProperty('divider')}">
<a ng-if="action.hasOwnProperty('label')" role="menuitem" tabindex="-1"
>
<span class="{{ action.icon }}"></span>
{{ action.label }}
</a>
</li>
</ul>
</div>
html:
<div action-button type="loadbalancer" label="Actions" icon="glyphicon glyphicon-cog" actions="actions.loadbalancer" class="pull-right"></div>
Are you using Angular-UI and have included the Bootstrap JS file in your project? We had this exact same thing happen and found that if you include the Bootstrap JS file in your project it somehow introduces this. We solved it by removing the Bootstrap JS file from the project and let Angular-UI handle things.

Resources