AngularJS - Create a dynamic, generic header - angularjs

In my AngularJS application, I'm using a router with an ng-view directive.
Besides it I would like to add a generic header (same for all the views). So I did the following:
<!-- index.html -->
<body ng-app="myApp">
...
<div ng-controller="TopmenuCtrl" class="header">
<div ng-include="template.url"></div>
...
</div>
<div ng-view></div>
</body>
The view is dynamic depending on the session token:
<!-- views/topmenu.html -->
<ul class="nav nav-pills pull-right">
<li class="active"><a ng-href="#">Home</a></li>
<li><a ng-href="#">About</a></li>
<li><a ng-href="#">Contact</a></li>
<li ng-show="token"><a ng-href="#" ng-click="doLogout()">Logout</a></li>
</ul>
And the topmenu controller with the logout method:
// controllers/topmenu.js
$scope.template = {url: 'views/topmenu.html'};
$scope.doLogout = function() {
localStorageService.clearAll();
$window.sessionStorage.token = '';
$location.path('/login');
};
The problem is: When I click on "logout" in the app, the topmenu controller is called and destroy the session but the main one from the router is called too and display an error because the session was destroyed!
The only (not satisfactory) solution I found to prevent this is to add this code in each controllers of the app:
if ($window.sessionStorage.token = '') {
return;
}
Is there a way to execute the header controller but not the main ng-view controller?

I finally found my answer: https://stackoverflow.com/a/11672909/900416.
Now my logout link looks like: <a href ng-click="doLogout()">Logout</a>.

Related

Change class from different controllers in AngularJS

I have my index.html page in which an ng-view is implemented. The same applies to the sidebar, which also linkes to 3 pages (main.html, product.html and customer.html).
I need to change the class of sidebar.html for example when I'm in the customer.html page.
I tried to do it from the customerController but it had no result. As I understand it, because the sidebar.html is controlled by MyController
Can anyone guide me?
Thank you
Here are the relevant parts of the code:
index.html
<html ng-app="appDataBoard">
<body ng-controller="MyController" >
<!-- SIDEBAR-->
<div ng-include="'./template/sidebar.html'" ></div>
<!-- BEGIN CONTENT -->
<div class="page-content-wrapper">
<div class="col-md-12 column sortable">
<div ng-view></div>
</div>
</div>
</body>
</html>
sidebar.html
<div class="page-sidebar-wrapper">
<ul >
<li class="nav-item start open">
</li>
<li class="nav-item ">
</li>
<li ng-class="nav-item">
</li>
</ul>
</div>
<!-- END SIDEBAR -->
routing.js
var dbApp = angular.module('appDataBoard', ['ngRoute','ngMaterial', 'ngMessages', 'material.svgAssetsCache']);
// configure our routes
dbApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/main', {
templateUrl : 'template/main.html',
controller : 'mainController'
})
// route for the about page
.when('/product', {
templateUrl : 'template/product.html',
controller : 'productController'
})
// route for the contact page
.when('/customer', {
templateUrl : 'template/customer.html',
controller : 'customerController'
});
});

Angularjs ng-hide not working with ng-include template

Can anybody help me.
In index.html, I run ng-view, which code corresponds to Routing.js file. The menu calls two pages main.html and product.htm.
main.htm, has included another page called filterApp.html.
I need to hide a page element that is embedded main.html the filterApp.html. I have not succeeded.
If I take the include and put the code directly into main.html works. I read that ng-ng-hide and include not working properly. Is there anything I can do. I need to have it in separate files.
Here is the code of the pages.
Thank you so much
Index.html
<html ng-app="appDataBoard">
<body ng-controller="mainController" >
<ul >
<li class="nav-item start open">
</li>
<li class="nav-item ">
</li>
</ul>
<div class="col-md-12 column sortable">
<div ng-view></div>
</div>
</body>
</html>
Main.html
<div class="jumbotron text-center">
<h1>main Page</h1>
<p>{{ message }}</p>
</div>
<!-- INCLUDE FILTER APPS-->
<div ng-include="'./template/filterApp.html'" ></div>
Product.html
<div class="jumbotron text-center">
<h1>Product Page</h1>
<p>{{ message }}</p>
p ng-hide="hide1">este parrafo se debe borrar</p>
</div>
filterApp.html
<div ng-hide="hselect1" >
<select id="select-1" multiple="multiple" onchange="RecargaSelectBU()" >
</select>
</div>
Routing.js
// create the module and name it dbApp
var dbApp = angular.module('appDataBoard', ['ngRoute']);
// configure our routes
dbApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/main', {
templateUrl : 'template/main.html',
controller : 'mainController'
})
// route for the about page
.when('/product', {
templateUrl : 'template/product.html',
controller : 'productController'
})
});
// create the controller and inject Angular's $scope
dbApp.controller('mainController', function($scope) {
// create a message to display in our view
$scope.message = 'Pagina principal';
$scope.hselect1 = true;
});
dbApp.controller('productController', function($scope) {
$scope.message = 'Pagina de producto.';
$scope.hide1 = true;
});
Check this plunker link. Its working fine for me.
https://embed.plnkr.co/RZDGdnFEq1SmT7F3ncZa/

AngularJS: how to refresh all visible controllers on page after state change? - Navigation after login

I managed to get it working by using a directive navbar and including it in my index.html, but after login, when I make a state change, my navbar does not get updated. If I refresh the page manually, then it reflects the changes.
Is there a better way to do this? Thanks.
index.html
<navbar></navbar>
<div class="container">
<ui-view></ui-view>
</div>
navbar.html
<ul class="nav navbar-nav navbar-right">
<li><a ui-sref="login" ng-hide="navbar.auth">Login</a></li>
<li>Logout</li>
</ul>
What I ended up doing was not using a directive for the navbar and instead just using multiple views for the same state. This automatically reloads all views on state change.
index.html
<div ui-view="nav"></div>
<div class="container">
<ui-view></ui-view>
</div>
And so the first page after login, gets the navbar as a second view, using the same template and controller as any other main state.
pivot.routes.js
routes.$inject = ['$stateProvider'];
export default function routes($stateProvider) {
$stateProvider
.state('pivot', {
url: '/pivot',
views: {
'': {
template: require('./pivot.html'),
controller: 'PivotController as pivot'
},
'nav': {
template: require('../nav/nav.html'),
controller: 'NavController as navbar'
}
}
});
}
Further reading: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

How to navigate from tab to different Page and viceversa in angularJS?

If i am having One page with 2 tabs. and if from 2nd tab i am navigating to different page. then how to come back to that 2nd tab from navigated page? i am using $StateProvider.
Thanks.
Here is the example code and it works well,
index.html
----------------
<html>
<head>
<title>Tabs Directive</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-rc.0/angular.min.js"></script>
<script src="tabController.js"></script>
</head>
<body>
<div class="container">
<section ng-app="myApp" ng-controller="TabController as tab">
<ul class="nav nav-pills">
<li ng-class="{active:tab.isSet(1)}"><a href ng-click="tab.setTab(1)">Tab 1</a></li>
<li ng-class="{active:tab.isSet(2)}"><a href ng-click="tab.setTab(2)">Tab 2</a></li>
<li ng-class="{active:tab.isSet(3)}"><a href ng-click="tab.setTab(3)">Tab 3</a></li>
</ul>
<div ng-show="tab.isSet(1)">
<h4>Tab 1</h4>
</div>
<div ng-show="tab.isSet(2)">
<h4>Tab 2</h4>
</div>
<div ng-show="tab.isSet(3)">
<h4>Tab 3</h4>
</div>
</section>
</div>
</body>
</html>
tabController.js
----------------
var app = angular.module('myApp', []);
app.controller('TabController', function () {
this.tab = 1;
this.setTab = function (tabId) {
this.tab = tabId;
};
this.isSet = function (tabId) {
return this.tab === tabId;
};
});
Thanks Atul :)
but this solution worked for me.
we can have one flag varibale ilke "this.isPageVisited=false" in APPCONTEXT.js file. so that variable will be available throughout the project. so suppose from tab of one page i am going to different page, what i do is i set isPageVisited=true via setter method in visted page . so now to come back to tab page again, we check the variable if its true or not. if it is true we put the "active" class to the tab element.
so that the we can have current tab active from where navigation started.

bind controller on dynamic HTML

I have a HTML page with different sections, which are loaded with AJAX. I have created a controller for each of the sections.
How is possible to bind the controller on a section which has been dynamically added on HTML?
I have found very complicated solutions, which i don't even know if they apply.
I need the most basic, easiest solution, something similiar with ko.applyBindings($dom[0], viewModel) for the ones who worked with KnockoutJs.
Index html
<div class="row" ng-app="app">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked">
<li>
Profile
</li>
</ul>
</div>
<div class="col-xs-9">
<div id="container"><!-- load dynamic HTML here --></div>
</div>
</div>
Dynamic HTML
<div ng-controller="profile">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
Javascript:
var app = angular.module('app', []);
app.controller('profile', function ($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
// load new HTML
// normally this is triggered by a link / button
$(function () {
$.get("/EditProfile/Profile", function (data, status) {
$("#container").html(data);
});
});
Don't use jQuery to embed html to your container. If you use jQuery, AngularJS can't track DOM manipulations and trigger directives. You can use ng-include directive of AngularJS.
In index.html file:
...
<div id="container">
<div ng-include="'/EditProfile/Profile'"></div>
</div>
...
If you want you can make that conditional:
...
<div id="container">
<div ng-if="profilePage" ng-include="'/EditProfile/Profile'"></div>
</div>
...
With that example, if you set profilePage variable to true, profile html will be load and render by ng-include.
For detailed info take a look to ngInclude documentation.
By the way, best practice to include views to your layout by triggering same link clicks is using routers. You can use Angular's ngRoute module or uiRouter as another popular one.
If you use ngRoute module, your index.html looks like that:
<div class="row" ng-app="app">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked">
<li>
Profile
</li>
</ul>
</div>
<div class="col-xs-9">
<div id="container" ng-view><!-- load dynamic HTML here --></div>
</div>
</div>
And with a router configuration like below, profile html will be automatically loaded and rendered by ngRoute inside ngView directive:
angular.module('myapp', []).config(function($routeProvider) {
$routeProvider
.when('/profile', {
templateUrl: '/EditProfile/Profile',
controller: 'ProfileController'
});
});

Resources