Angular Routing and Bootstrap Navbar - angularjs

I have problems getting the bootstrap navbar + angular routing to work. I don't understand what is going on since a very similar code on another app is working.
I have the following html in my index.html
<div ng-controller="CoreController as core">
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<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" href="#">myApplication</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li ng-class="core.navHome">Home <span class="sr-only">(current)</span></li>
<li ng-class="core.navStatistic">Statistic</li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
<!-- angular templating -->
<!-- this is where content will be injected -->
<div ng-view></div>
</div>
my app.js:
$routeProvider.when('/', { templateUrl: 'templates/home.html', controller: 'MainController', controllerAs: 'main' });
$routeProvider.when('/statistic', { templateUrl: 'templates/statistic.html', controller: 'StatisticController', controllerAs: 'statistic' });
// Default route
$routeProvider.otherwise({ redirectTo: '/' });
When I hit the statistic link, my URL shows:
http://localhost/myApplication/#!/#statistic
and I get see the home template.
The home button then shows "http://localhost/myApplication/#!/"
Is the #! the reason for this?

Ok after some research I found out that I this code worked for angular < 1.6.
To make the above code work in 1.6 you have to get ridd of the #! by adding this to the config:
$locationProvider.hashPrefix('');
Here is the original Post.

Related

How to separate menu into different view in AngularJS ui-router application?

I have this:
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<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="main">Project name</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li ui-sref-active="active"><a ui-sref="main.tm">Task manager</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li ui-sref-active="active"><a ui-sref="main.settings">Settings</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron" ui-view>
<div class="main-viewer" ></div>
</div>
</div> <!-- /container -->
Here is how states conf:
$stateProvider.state({
name: 'main',
url: '/',
template: mainTemplate
});
$stateProvider.state({
name: 'main.tm',
url: '/tm',
controller: 'tm.list',
template: view
});
$stateProvider.state({
name: 'main.settings',
url: '/settings',
controller: 'settings.ctrl',
template: view
});
$urlRouterProvider.otherwise('/tm');
Summary:
Now I have header (menu) and content block. Dependent on what button user press in menu settings or tm module appears in content block. Both settings and tm module is in separated directories (different modules).
The problem:
Menu html and container for settings and tm block (<div ui-view></div>) are in one HTML file. I want to separate menu into different module (like settings and tm are in separated modules).
What I want:
main module will be like (view pseudocode):
<container for menu>
<container for content>
Menu will be in directory menu and there will be files menu.html and menu.ctrl.js. It will be "injected" to container "container for menu". tm and settings already in correct directories and have their own views and controllers.
Whole code is here.
PS. One of the expected results was:
<menu-component></menu-component>
<div class="container">
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron" ui-view>
<div class="main-viewer">
Welcome page
</div>
</div>
</div> <!-- /container -->
Now menu logic is in the separated controller and view is in the separated html.

Angular.js converting my .html urls to just /something removing .html

I want to convert my angular pages, I am using ng-includes but my pages has .html extensions, I would like have just /mypage
sample:
www.mypage.com/projects.html
I want archive this:
www.mypage.com/projects
html
<!-- header -->
<nav class="navbar navbar-default navbar-fixed-top">
<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>
</button>
<a class="navbar-brand" href="index.html">logo</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>Projects</li>
</ul>
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
<!--/.nav-collapse -->
</div>
</nav>
<!-- header -->
<div>
<div ng-include="'app/pages/projects.html'"></div>
</div>
<footer class="footer">
<div class="container text-center">
footer
</div>
</footer>
js:
var App = angular.module('App', []);
App.controller('ProjectCtrl', function($scope, $http) {
$http.get('app/projects.json')
.then(function(res){
$scope.projects = res.data;
});
});
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/projects', {
templateUrl : 'projects.html',
controller : mainController
});
// use the HTML5 History API
$locationProvider.html5Mode(true);
});
js fiddle: https://jsfiddle.net/3ww49zq7/
how can make it?
thanks.
At the first you will need to use ngRoute and declare it as a dependency in your module
var App = angular.module('App', ['ngRoute']);
Then you can use routeProvider
Second :
You should use the ng-view directive to tell the angular that this div will be used to load the views.
<div ng-view></div>
Third :
You should change your links to the same in the routeprovieder
<li class="active">Home</li>
<li>Projects</li>
should be
<li class="active">Home</li>
<li>Projects</li>
and you should make sure that these links match the case in the routeProvider Object.
You should declare the controller you are using in the routeProvider
here is a plunker to demonstrate :.http://plnkr.co/edit/DrPG9WtLg8abpLQpVj0W?p=preview

how routing connects to the page

I am trying to learn angular with a book and some examples, and I have some difficult times trying to understand how the ng-view knows the view to display based on the routing system.
So here is an example:
<!DOCTYPE html>
<html ng-app="maintenance">
<head>
<title>Dive Sites</title>
<link href="./lib/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="./site.css" rel="stylesheet" />
</head>
<body ng-controller="adminCtrl">
<!-- Navigation header -->
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#adminMenu">
<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" href="#">
Younderwater Admin
</a>
<div class="collapse navbar-collapse" id="adminMenu">
<ul class="nav navbar-nav">
<li ng-class="{active: isActive('Locations')}">
Locations
</li>
<li ng-class="{active: isActive('Sites')}">
<a href="#/sites">
Dive Sites
</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Optional title bar -->
<div class="current-spot">
<div class="container-fluid" >
<div class="container">
<div ng-show="view=='locations'">
<h3>Manage the list of diving locations</h3>
</div>
<div ng-show="view=='diveSites'">
<h3>Manage the list of dive sites</h3>
</div>
</div>
</div>
</div>
<!-- View content -->
<div class="main-content">
<div class="container-fluid">
<div class="container">
<div ng-view></div>
</div>
</div>
</div>
<script src="./lib/jquery/jquery.min.js"></script>
<script src="./lib/bootstrap/bootstrap.min.js"></script>
<script src="./lib/angular/angular.min.js"></script>
<script src="./lib/angular/angular-route.min.js"></script>
<script src="maintenance.js"></script>
</body>
</html>
SCRIPT
angular.module('maintenance', ['ngRoute'])
.controller('adminCtrl', AdminCtrl)
.config(function ($routeProvider) {
$routeProvider.when('/locations', {
templateUrl: 'views/locations.html'
});
$routeProvider.when('/sites', {
templateUrl: 'views/sites.html'
});
$routeProvider.otherwise({
templateUrl: 'views/main.html'
});
});
function AdminCtrl($scope) {
}
I need to know if I have the correct way of thinking, watching this example, I would say that the '#' says to use the routing system, in the script we set the routes and the views the app should load based on the url, when I press the because of the # it search based on the routing system and passes the view to the ng-view, I don't know if the processing is correctly thats why I need to understand better how it works, sorry if I don't explained very well :/
Ps: sorry for my bad english
First and foremost, and angular.module('maintenance', ....) must match. I'm referring to the identifier 'maintenance'. Without this, your JS file won't find your HTML file.
From the JS file, you have angular.module('maintenance', ['ngRoute']), ngRoute is an angular directive for routing.
https://docs.angularjs.org/api/ngRoute
The $routeProvider says what page to go to.
http://www.w3schools.com/angular/angular_routing.asp
And templateUrl shows the URL for the page.
https://docs.angularjs.org/guide/directive
http://techfunda.com/howto/505/function-with-templateurl
I'm very sure you have the following html files in your project.
locations.html
sites.html
main.html

How to modify HTML content based on angular controller

I am trying to build a login page and a functionality page using angularjs SPA.
I have following controller:
- LoginController
- PredictionController
And following single page:
- Home.html : Binded to LoginController
- trend.html : Binded to PredictionController
- index.html : Has no controller
I have navigation panel in index.html and I want to modify(add or remove) number of tabs based on login. I don't want to write navigation panel logic in each page as it is reusable. I am unable to figure out way to do this using additional controller because I am using ng-route which I guess won't allow me to use multiple controller for same page.
Here is my html code snippet for index.html:
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<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" href="#/">MyProject</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>Trend</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div ng-app="chartApp">
<div ng-view></div>
</div>
</body>
Here is the code for controller:
var app = angular.module('chartApp', ['ngRoute']);
app.factory('UserVerified', function() {
return
{bool: false};
});
app.config(function ($routeProvider) {
$routeProvider
.when('/',{
templateUrl: 'pages/home.html',
controller: 'LoginController'
})
.when('/Trend', {
templateUrl: 'pages/trend.html',
controller: 'PredictionController'
})
});
app.controller('LoginController', ['$scope', '$http', 'UserVerified', function($scope, $http, UserVerified){
$scope.hasPermission = UserVerified.bool;
$scope.getAuthentication = function(){
console.log($scope.userId, $scope.pwd)
$http.get('/getAuth', {
params: { user_id: $scope.userId, pwd: $scope.pwd }
}).success(function (response){
console.log(response);
UserVerified.bool = response;
$scope.hasPermission = UserVerified.bool;
});
}
}]);
I'm not sure if the information is enough please edit or let me know if i'm missing some information.
I believe you're going to have to move your ng-app directive up to the body, and create a NavigationController which can require your UserVerified factory and help maintain the state of the navigation.
You could add the ng-controller directive to your navbar explicitly, and your router should work the same.
The HTML might look something like this.
<body ng-app="chartApp">
<nav ng-controller="NavigationController" class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<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>
<!-- Only display if $scope.loggedIn -->
<a ng-show="loggedIn" class="navbar-brand" href="#/">MyProject</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>Trend</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div ng-view></div>
</body>
NavigationController
app.controller('NavigationController', function($scope, UserVerified) {
$scope.$watch(function() {
return UserVerified.bool;
}, function(state, oldState) {
$scope.loggedIn = state;
});
});

Logout approach for angularjs?

I have started learning angularjs for two days, there a lot of new concepts that are new to me, i'm building a test project to my final project testing all the new different things so far,
I'm stuck in the logout, i have implement the ng-if directive in the login controller and it works great i have test it the success method of login request, but i want to move my logout html to the navbar which is in the index.html, so i'm not sure where to put my logic to test against the cookie ?
that's my index.html
<div ng-controller="HomeController">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<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" href="/">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active">Register</li>
<li>Login</li>
<li>Articles</li>
<li ng-if ="isAuth" ng-click="LogOut()">LogOut</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>
<div data-ng-view=""></div>
HomeController
app.controller('HomeController', function ($scope, Auth) {
$scope.isAuth = Auth.IsAuth;
});
Auth service
app.service('Auth', function ($cookieStore) {
var auth = function myfunction() {
if ($cookieStore.get('token')) {
return true;
}else{
return false;
}
}
return{
isAuth : auth()
}
});

Resources