Angular 1.6 NestedRoute (Single Page Application) - angularjs

I am trying to have single page application in agularjs 1.6 using ngRoute.My code is as follows.
Angular Code
let mainAngularModule = angular.module("acc-management", ['ngMaterial','ngRoute']);
mainAngularModule.config(routeConfig);
routeConfig.$inject = ['$routeProvider'];
function routeConfig($routeProvider, $locationProvider) {
$routeProvider
.when('/Personaldata', {
templateUrl: 'PersonalPreference.html',
controller: 'PersondataController as personController'
})
.when('/UserData', {
templateUrl: 'UserDefinedElement.html',
controller: 'accountController as accController'
})
}
class AccountController {
static $inject = ["$scope"];
constructor(private $scope) {
debugger;
}
}
mainAngularModule.controller("accountController", AccountController);
mainAngularModule.controller("PersondataController", PersonalPreferencesController);
class PersondataController {
public scope: Object = {
title: "Personal Preferences"
}
}
class UserData {
}
HTML
<div layout="row" layout-xs="column">
<div flex="18">
<md-subheader class="md-no-sticky">User Preferences</md-subheader>
<md-list-item href="#/PersonalPreferences">
<span>Personal Preferences</span>
</md-list-item>
<md-list href="#/UserData">
<span>User Data</span>
</md-list>
</md-sidenav>
</div>
<div flex>
<md-content layout-padding>
<div ng-view></div>
</md-content>
</div>
</div>
My code is working fine for routing.In Userdata I have submenu's Address,Qualifications.I am not getting how should i write angular route code for it(nested routing).Below is my html code.
HTML
<div layout="row" layout-xs="column">
<div flex="18">
<md-list-item href="#/">
<span>Address</span>
</md-list-item>
<md-list href="#/">
<span>Qualifications</span>
</md-list>
</div>
</div>

Related

How to use ui-view on RenderBody() in angularjs

I have this mark-up html with the #RenderBody():
<div layout="column" class="relative" layout-fill role="main">
<md-toolbar class="md-hue-2">
<div class="md-toolbar-tools">
<md-button class="md-icon-button" aria-label="Settings" ng-disabled="true">
<md-icon md-svg-icon="navigation:menu"></md-icon>
</md-button>
<md-button ui-sref="dashboard">Dashboard</md-button>
<md-button ui-sref="home">Home</md-button>
</div>
</md-toolbar>
<md-content layout-fill md-padding>
<div id="main-content" ui-view="">
#RenderBody()
</div>
</md-content>
</div>
and the js here:
app.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/Home/Index');
$stateProvider
.state('home', {
url: '/Home/Index',
templateUrl: '/Home/Index' // corresponds to an MVC partial route
})
.state('dashboard', {
url: 'Home/Dashboard',
templateUrl: '/Home/Dashboard' // corresponds to an MVC partial route
})
});
The result is its own view inside a view. I cant figure it out.
Here is the output:
I see this problem in few of my apps.
Your layout is loading twice.
All you need to do is "make your layout null" while rendering from uiroute as below.
Add this on top of your Index.cshtml page
#{
Layout = null;
}
Or load ui-view out side the content div
<md-content layout-fill md-padding>
<div id="main-content">
#RenderBody()
</div>
</md-content>
<ui-view></ui-view>
Or you could use viewContentLoaded that is triggered after DOM is loaded when using uirouter in angular as below:
//trigger events after DOM content load
$scope.$watch("$viewContentLoaded",
function() {
if (document.getElementsByTagName("header").length === 2) {
document.getElementsByTagName("header")[1].remove();
}
if (document.getElementsByTagName("footer").length === 2) {
document.getElementsByTagName("footer")[1].remove();
}
});

ng-click not responding when HTML added by JavaScript

ng-click is not working as it should. I tried looking at documentation and tutorials but couldn't find the reason.
I have a JavaScript variable storing html template. which by using
document.getElementById('someId').innerHTML = emptypage;
where emptypage is a JavaScript variable, is implemented inside a div with id=someId.
My Code:
var emptypage=` <md-toolbar `+ this.createID() +` class="md-accent
soopsObject" ng-app="vdApp">
<span class="example-spacer ng-controller="vdNav">
<md-sidenav class="md-sidenav-left" md-component-id="left" md-
disable-backdrop md-whiteframe="4">
<md-content layout-margin>
<p>
About
</p>
<p>
Contact
</p>
<md-button ng-click="toggleLeft()" class="md-accent">
Close
</md-button>
</md-content>
</md-sidenav>
<div>
<md-button ng-click="toggleLeft()">
<md-icon>menu</md-icon> Menu
</md-button>
</div>
</span>
</md-toolbar>`;
My Controller:
var nav=angular.module("vdApp", []);
nav.controller("vdNav", function($scope, $mdSidenav) {
alert("inside leftToggle");
$scope.toggleLeft = buildToggler('left');
function buildToggler(componentId){
return function(){
$mdSidenav(componentId).toggle();
};
}
});
Even alert isn't working.
What am I doing wrong? Any help or suggestion is appreciated.

Method binding is not working in Angular

I am trying to attached a controller scope method in a directive but when i click in directive button that linked method is not called. Please review code. There is side-nav directive in which i have attached method with select parameter. but when button is clicked method is not called.
index.html
<div class="container" layout="row" flex ng-controller="userController as vm" ng-init="vm.loadUsers()">
<md-sidenav md-is-locked-open="true" class="md-whiteframe-1dp">
<side-nav users="vm.users" select="vm.selectUser(user)"></side-nav>
</md-sidenav>
<md-content id="content" flex>
<user-detail selected="vm.selected" share="vm.share()"></user-detail>
</md-content>
</div>
userController.js
app.controller("userController", ['$scope', 'userService', '$mdBottomSheet', function ($scope, userService, $mdBottomSheet) {
var self=this;
self.users = [];
this.name = "manish";
self.loadUsers = function () {
userService
.loadAllUsers()
.then(function (users) {
self.users = users;
self.selected = users[0];
userService.selectedUser = self.selected;
});
}
self.selectUser = function (user) {
self.selected = user;
userService.selectedUser = self.selected;
}
}]);
directives.js
app.directive("sideNav", function () {
return {
restrict :'AE',
templateUrl: './views/sidenav.html',
scope : {
select : '&',
users : '='
}
}
});
./views/sidenav.html
<md-list>
<md-list-item ng-repeat="user in users">
<md-button ng-click="select({user:user)">
<md-icon md-svg-icon="{{user.avatar}}" class="avatar"></md-icon>
{{user.name}}
</md-button>
</md-list-item>
</md-list>
Try doing it like this:
index.html
<side-nav users="vm.users" select="vm.selectUser"></side-nav>
./views/sidenav.html
<md-button ng-click="select()(user)">

Error with viewing an ionic HTML page after routing through Angular JS

I wrote a code for for my app, when a I click on the toggle to reach the second page, the url changes it took me there but nothing is appeared, just a blank page no more,
here is the app.js code
angular.module("BloodDonationApp", [
"ionic",
])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
if (window.cordova && window.cordova.plugins && window.cordova.plugins.keyboard) {
cordova.plugins.keyboard.hidekeyboardAccessoryBar(true);
}
if (window.statusBar) {
//org.apache.cordova.statusbar required
statusbar.styleDefault();
}
});
})
//****************ROUTES***************//
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
abstarct: true,
url: "/home",
templateUrl: "templates/home.html"
})
.state('home.feeds', {
url: "/feeds",
views: {
"tab-feeds": {
templateUrl: "templates/feeds.html"
}
}
})
.state('home.settings', {
url: "/settings",
views: {
"tab-settings": {
templateUrl: "templates/settings.html"
}
}
})
.state('requestDetails', {
url: "/RequestDetails/:id",
view: {
"mainContent": {
templateUrl: "templates/requestDetails.html"
}
}
})
.state('requestDetails.ClientRegister', {
url: "/Client-Register/:id",
view: {
"mainContent": {
templateUrl: "templates/ClientRegister.html"
}
}
});
//if name of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/home/feeds');
})
and here is the html code of the feeds page:
<ion-view ng-controller="FeedsCtrl as vm">
<ion-content class="has-header">
<div class="card" ng-repeat="requests in vm.feeds">
<div class="item item divider" ng-click="toggleGroup(requests)"
ng-class="{active: isGroupShown(requests)}">
<div class="row row-bottom">
<div class="col">
{{requests.type}}
</div>
<div class="col">
{{requests.unitNb}} Units
</div>
</div>
</div>
<div class="item-accordion"
ng-show="isGroupShown(requests)" ng-click="goToDetails()">
<div class="row">
<div class="col-top">
Since 7 s{{requests.Date}}
</div>
<div class="col col-center col-50 col-offset-8">
<br/>{{requests.HospName}}
<br/>
{{requests.Hosplocation}}
</div>
<div class="col col-bottom">
<a class="item item-icon-right">
<div class="row">
<i class="ion-icon ion-pinpoint "></i>
</div>
<div class="row">
{{requests.HospDistance}}4km
</div>
</a>
</div>
</div>
</div>
</div>
</ion-content>
</ion-view>
and the controller for feeds:
(function () {
'use strict';
angular.module('BloodDonationApp')
.controller('FeedsCtrl', ['BloodDonationApi', '$scope', '$state', FeedsCtrl]);
function FeedsCtrl(BloodDonationApi, $scope, $state) {
var vm = this;
//start Data Binding functions//
var data = BloodDonationApi.getRequests();
console.log(data);
vm.feeds = data;
//end Data Binding//
//start Accordion function//
$scope.toggleGroup = function (requests) {
if ($scope.isGroupShown(requests)) {
$scope.shownGroup = null;
} else {
$scope.shownGroup = requests;
}
}
$scope.isGroupShown = function (requests) {
return $scope.shownGroup === requests;
}
$scope.goToDetails = function() {
$state.go('requestDetails', {id : 5});
}
//end Accordion function//
};
})();
but the request details is not appeared after clicking on the toggle its just give a blanck page, the html code :
<ion-view ng-controller="RequestDetailsCtrl as vm">
<ion-content class="has-header">
<div class="card">
<div class="item">
<div class="row">
<div class="col">
{{requests.type}}
</div>
<div class="col">
{{requests.unitNb}} Units
</div>
</div>
<div class="row">
<div class="col">
{{requests.HospName}}
</div>
<div class="col">
{{requests.Hosplocation}}
</div>
<div class="col">
4 Km Away
</div>
</div>
<button class="button button-block button-positive">
Yes, I donate <i class="ion-icon ion-thumbsup"></i>
</button>
<label>
4/5 <i class="ion-icon ion-battery-half"></i>
</label>
<div class="title">
<h3>
Last time I'd donated was since<br /> 4 months
<i class="ion-icon ion-checkmark-round"></i>
</h3>
</div>
</div>
</div>
</ion-content>
</ion-view>
the controller:
(function () {
'use strict';
angular.module('BloodDonationApp')
.controller('RequestDetailsCtrl', ['BloodDonationApi', '$stateParams', '$scope', RequestDetailsCtrl]);
function RequestDetailsCtrl(BloodDonationApi, $stateParams, $scope) {
var vm = this;
var data = BloodDonationApi.getRequests();
console.log(data);
vm.requestDetails = data;
console.log("$stateParams", $stateParams.id);
//end Data Binding//
// Get you request
};
})();
am sure that there is an error with the view code, but m not figuring it out, if anybody can help me plz.
You are inside a nested state when you are tying to load requestDetails so change your state to :
.state('requestDetails', {...})
.state('home.requestDetails', {
url: "/feeds/:id",
views: {
'tab-feeds' :{
templateUrl: "templates/requestDetails.html"
}
}
})
and your method to:
$scope.goToDetails = function() {
$state.go('home.requestDetails', {id : 5});
}
and It's working !
I've fork your git so updated working version is here if you want to pull

How to add active class inside header navigation directive inside a controller?

Since my app has a navigation menu repeated in several pages, I made a directive for it. Now, the .active class isn't applied to current page anymore. Do I need to put the controller inside the directive?
Though not elegant, here's my code so far. Thanks.
page.html
<div class="app-container">
<div class="header clearfix">
<div ng-controller="NavmenuCtrl">
<nav-menu></nav-menu>
</div><!-- END NavmenuCtrl -->
</div><!-- /header -->
<div class="container"></div>
</div><!-- /app-container -->
navmenu directive
'use strict';
var app = angular.module('tempApp');
app.controller('NavmenuCtrl', function ($scope, $route) {
$scope.navMenuState = function($scope) {
$scope.navState = $route.current.navState;
};
});
app.directive('navMenu', function($route) {
return {
scope: {},
restrict: 'E',
replace: true,
templateUrl: 'views/partials/navmenu.html',
link: function navMenuState(scope, element, attrs, controller){
// Watch for the $location
scope.$watch(function() {
// do I need a scope.$watch?
}
};
});
navmenu.html partial
<div>
<div class="nav-container">
<ul class="navbar">
<li class="col-xs-5" ng-class="{ active:route.current.navState === 'pg1Active' }">
<a href="/#/pg1/">
<img src="images/icon1.png" class="center-block">
</a>
</li>
<li class="col-xs-5" ng-class="{ active:route.current.navState === 'pg2Active' }">
<a href="/#/pg2">
<img src="images/icon2.png" class="center-block">
</a>
</li>
</ul><!-- /.navbar -->
<div class="overflow-menu pull-right dropdown" ng-controller="NavDropdownCtrl">
<a class="dropdown-toggle">
<img ng-src="images/icon3.png">
</a>
<ul class="dropdown-menu">
<li ng-repeat="name in MenuItems">
<h4>
<a ng-href="#/{{ name | lowercase }}/">
{{name}}
</a>
</h4>
</li>
</ul>
</div><!-- /.overflow-menu -->
</div><!-- /.nav-container -->
</div>
app.js
'use strict';
angular.module('tempApp', [
...
])
.config(function ($routeProvider) {
$routeProvider
.when('/pg1/', {
templateUrl: 'views/pg1.html',
controller: 'MainCtrl',
navState: 'pg1Active'
})
.when('/pg2/',
{
templateUrl: 'views/pg2.html',
controller: 'MainCtrl',
navState: 'pg2Active'
})
I also found these related links:
Behavior of controller inside directives
AngularJS - Handle repeated fragments like Header and Footer
http://coder1.com/articles/angularjs-managing-active-nav-elements
You need to inject the $location service into your directive and check for routes there.

Resources