angularjs accordion list anchor alternate elements - angularjs

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?

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.

Refresh data in Ionic abstract menu

In my application, operations can be performed. When a user performs an operation increases their number of points that are displayed in the menu my problem is that I can not update this result in the menu since when I do a state.reload () reload only the controller that I access but not the From the menu that is the SndController driver. I've tried putting $ ionicConfigProvider.views.swipeBackEnabled (false); But it does not work What can I do? I leave you the code of the menu and the one of app.js. Thank you
<ion-side-menu side="left" ng-controller="NavController">
<ion-content has-header="true" class="menuscroll">
<ul class="list" ng-show="currentState == 'menuconsumidor'">
<h1 class="text-center title">¡Hola {{usuario.nombre}}!</h1>
<div class="resumen-puntos puntosMenu"><i class="icon icoNivel {{claseNiveles}}"></i><span class="txtMenu">Tienes <span class="resaltado">{{usuario.puntos | commaToDecimal}} €</span> acumulados <br/>Tu nivel es <span class="resaltado uppercase">{{usuario.tramo}}</span></span></div>
<a ui-sref="snd.datos" nav-clear class="item datos" ng-click="toggleLeft()"><i class="ion-android-person"></i>Datos personales<i class="ion-chevron-right"></i></a>
<ion-item vinculaciones class="item vinculaciones"><i class="ion-android-people"></i>Vinculaciones<i class="ion-chevron-right"></i></ion-item>
<a ui-sref="snd.niveles({reload: true})" nav-clear class="item niveles" ng-click="toggleLeft()"><i class="ion-ios-star-outline"></i>Niveles y Zonas<i class="ion-chevron-right"></i></a>
<a ui-sref="snd.terminos" nav-clear class="item terminos" ng-click="toggleLeft()"><i class="ion-android-document"></i>Términos y condiciones<i class="ion-chevron-right"></i></a>
<a ui-sref="snd.ayuda" nav-clear class="item ayuda" ng-click="toggleLeft()"><i class="ion-help-circled"></i>Ayuda<i class="ion-chevron-right"></i></a>
<a ui-sref="snd.share" nav-clear class="item comparte" ng-click="toggleLeft()"><i class="ion-android-share-alt"></i>Comparte<i class="ion-chevron-right"></i></a>
<ion-item log-out class="item salir"><i class="ion-android-exit"></i>Salir<i class="ion-chevron-right"></i></ion-item>
</ul>
<ul class="list" ng-show="currentState == 'menucomercio'">
<h1 class="text-center title">¡Hola {{usuario.nombreComercio}} !</h1>
<div class="resumen-puntos puntosMenu"><i class="icon icoNivel {{claseNiveles}}"></i><span class="txtMenu">Este mes has facturado <span class="resaltado">{{usuario.importeFacturadoMesActual | commaToDecimal}} €</span> <br/>Tu nivel es <span class="resaltado uppercase">{{usuario.tramo}}</span></span></div>
<a ui-sref="snd.datoscomercio({reload: true})" nav-clear class="item datos" ng-click="toggleLeft()"><i class="ion-android-person"></i>Datos personales<i class="ion-chevron-right"></i></a>
<a ui-sref="snd.nivelescomercio({reload: true})" nav-clear class="item niveles" ng-click="toggleLeft()"><i class="ion-ios-star-outline"></i>Niveles y Zonas<i class="ion-chevron-right"></i></a>
<a ui-sref="snd.terminoscomercio" nav-clear class="item terminos" ng-click="toggleLeft()"><i class="ion-android-document"></i>Términos y condiciones<i class="ion-chevron-right"></i></a>
<a ui-sref="snd.ayudacomercio" nav-clear class="item ayuda" ng-click="toggleLeft()"><i class="ion-help-circled"></i>Ayuda<i class="ion-chevron-right"></i></a>
<a ui-sref="snd.share" nav-clear class="item comparte" ng-click="toggleLeft()"><i class="ion-android-share-alt"></i>Comparte<i class="ion-chevron-right"></i></a>
<ion-item log-out class="item salir"><i class="ion-android-exit"></i>Salir<i class="ion-chevron-right"></i></ion-item>
</ul>
</ion-content>
</ion-side-menu>
</ion-side-menus>
Snd controller is my menu in my application .
.state('snd', {
url : '/snd',
templateUrl : 'templates/snd-abstract.html',
abstract : true,
cache: false,
controller : 'SndController'
})
.state('snd.home', {
cache: false,
url: '/home',
views: {
'snd': {
templateUrl: 'templates/snd-home.html',
controller : 'SndHomeController'
}
}
})
.state('snd.terminos', {
cache: false,
url: '/terminos',
views: {
'snd': {
templateUrl: 'templates/snd-terminos.html',
controller : 'SndEstaticasController'
}
}
})
.state('snd.ayuda', {
cache: false,
url: '/ayuda',
views: {
'snd': {
templateUrl: 'templates/snd-ayuda.html',
controller : 'SndEstaticasController'
}
}
})
.state('snd.operaciones', {
cache: false,
url: '/operaciones',
views: {
'snd': {
templateUrl: 'templates/snd-operaciones.html',
controller : 'SndOperacionesController'
}
}
})
.state('snd.detalleoperacion', {
url: '/operaciones/:operacionId',
cache: false,
views: {
'snd': {
templateUrl: 'templates/snd-detalle-operacion.html',
controller : 'SndOperacionDetalleController'
}
}
})
.state('snd.nivelescomercio', {
url: '/nivelescomercio',
cache: false,
views: {
'snd': {
templateUrl: 'templates/snd-comercio-niveles.html',
controller : 'SndNivelesComercioController'
}
}
})
.state('snd.ofertascomercio', {
url: '/ofertascomercio',
cache: false,
views: {
'snd': {
templateUrl: 'templates/snd-comercio-ofertas.html',
controller : 'SndOfertasComercioController'
}
}
})
.state('snd.nuevaSedeComercio', {
url: '/nuevaSedeComercio',
cache: false,
views: {
'snd': {
templateUrl: 'templates/snd-comercio-nueva-sede.html',
controller : 'SndNuevaSedeComercio'
}
}
})
I resolved . I push this code in my parent state...
$scope.$on('$ionicView.beforeEnter', function() {
console.log(' reload state before enter children state');
$scope.usuario = UsuarioFactory.getUsuario();
console.log(usuario);
});

Nested Views and States Not showing

In my app I have the root state named "app":
.state('app', {
abstract: true,
views: {
'app': {
templateUrl: 'prebuilt/views/pages/index.html',
controller: 'MainController'
}
}
})
and its child "app.pages"
.state('app.pages', {
abstract: true,
views: {
'custom#app': {
templateUrl: 'prebuilt/views/templates/custom-styles.html'
},
'header#app': {
templateUrl: 'prebuilt/views/layout/header.html'
},
'topBar#app': {
templateUrl: 'prebuilt/views/layout/topbar.html'
},
'sideBar#app': {
templateUrl: 'prebuilt/views/layout/sidebar.html'
},
'infoBar#app': {
templateUrl: 'prebuilt/views/layout/infobar.html'
},
'contentSide#app': {
templateUrl: 'prebuilt/views/layout/contentside.html'
}
}
})
And grand child "app.pages.dashboard"
.state('app.pages.dashboard', {
url: '/',
views: {
'content#app.pages': {
templateUrl: 'prebuilt/views/index.html',
controller: 'DashboardController'
}
},
resolve: {
loadCalendar: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load([
'prebuilt/bower_components/fullcalendar/fullcalendar.js',
]);
}]
}
})
Now app loads an html view, inside that view are nested views which are/should be loaded when i navigate to "app.pages".
Now up to this point everything works just fine, however now I want to load a page in the content body of "app.pages", I've tried several times but the view never gets loaded:
This is a simplified version of my app.php:
<html>
<head></head>
<body>
<div ui-view="app"></div>
</body>
</html>
This is a simplified version of my index.html:
<div ui-view="header"></div>
<nav ui-view="topBar"></nav>
<div id="wrapper">
<div>
<di ui-view="sideBar">
</div>
<div>
<div>
<div>
<div class="col-md-9" ui-view="content">
</div>
<div class="col-md-3" ui-view="contentSide">
</div>
</div> <!--wrap -->
</div>
<footer>
<div class="clearfix">
<ul class="list-unstyled list-inline pull-left">
<li>© 2015</li>
</ul>
<button><i class="fa fa-angle-up"></i></button>
</div>
</footer>
</div>
</div>
</div>
<div ui-view="infoBar"></div>
One issue is incorrect absolute naming here:
// NOT correct
.state('app.pages.dashboard', {
url: '/',
views: {
// here is incorrect absolute name
'content#app.pages': {
templateUrl: 'prebuilt/views/index.html',
controller: 'DashboardController'
}
},
...
Because this is part of index.html, which is part of state 'app'
...
<div class="col-md-9" ui-view="content">
...
So the proper naming is just '...#app'
.state('app.pages.dashboard', {
url: '/',
views: {
// CORRECT
'content#app': {

How to ng-hide login button after successful login Ionic?

I have started sideMenu app in ionic and tried some implementation. Initially, ionicModal is used to show login so i change it with ion-list item like;
<ion-side-menu side="left" >
<ion-header-bar class="bar-stable bar-dark">
<a ng-click="redirectToWeb()" > <h1 class="title">NerdApp</h1></a>
</ion-header-bar>
<ion-content >
<ion-list class="BGcolorDG">
<ion-item nav-clear menu-close class="BGcolorDG item item-icon-left item-content-modified" href="#/app/login" ng-show="control.showLogin" > <!--ng-click="login()" -->
<i class="icon ion-locked"></i> <span>Login</span>
</ion-item>
<ion-item nav-clear menu-close href="#/app/search" class="item item-icon-left BGcolorDG item-content-modified">
<i class="icon ion-search"></i><span>Search</span>
</ion-item>
<ion-item nav-clear menu-close href="#/app/browse" class="item item-icon-left BGcolorDG item-content-modified">
<i class="icon ion-ios-browsers"></i><span>Browse</span>
</ion-item>
<ion-item nav-clear menu-close href="#/app/playlists" class="item item-icon-left BGcolorDG item-content-modified">
<i class="icon ion-music-note"></i> <span>Playlists</span>
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
and provide routeState as
state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.login', {
url: "/login",
views: {
'menuContent': {
templateUrl: "templates/login.html",
controller: "LoginCtrl"
}
}
})
.state('app.home', {
url: "/home",
views: {
'menuContent': {
templateUrl: "templates/home.html",
controller: "HomeCtrl"
}
}
})
And default route to home controller.
$urlRouterProvider.otherwise('/app/home');
the app controller is as
.controller('AppCtrl', function($scope,$timeout,$location,$rootScope) {
$scope.control = {
showLogin:true
};
if($rootScope.showLogin != undefined && $rootScope.showLogin == false){
$scope.control.showLogin = false;
}
})
Inside loginControl i am checking and redirecting it back to home controller as
$scope.login = function() {
if ($scope.loginData.username == 'hassaan' && $scope.loginData.password == 'khan') {
$rootScope.showLogin = false;
// $location.path('#/app');
$state.go('app.home');
}else{
alert('Incorrect credentials');
}
}
i have tried both $location.path and $state.go and what its doing is redirecting to home page but 'not showing the sidemenu' and when i inspect in browser it showing sidemenu hidden.
The flow images of test app is as
Try use $rootScope
pass it to AppCtrl
.controller('AppCtrl', function (...., $rootScope) {
// and then
$rootScope.control = {
showProfile: false
};
after success authentication - make it true
$rootScope.control = {
showProfile: true
};
now it should work as you expected
Don't use $rootscop if you dont need to.
You can send variables to other controllers with the router from angular using params.
.state('menu.employeeInfo', {
url: '/employeeInfo',
views: {
'side-menu21': {
templateUrl: 'templates/employeeInfo.html',
controller: 'employeeInfoCtrl'
}
},
params: {
appointmentObj: null,
subassignmentObj: null
}
})
You can then pass these vars in the following manner.
$scope.gotoAppointment = function (Appointment, Subassignment) {
$state.go('menu.employeeInfo', { appointmentObj: Appointment, subassignmentObj: Subassignment }, { reload: true });
}

Wiring up a nav menu with Angular routes

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'
}
}
]
},
}
];
}

Resources