AngularJs inject html element in shell from child view from markup - angularjs

I'm new to angular and have been struggling to work out the best angular approach to solving this problem.
I have my shell page which has a place where I would like an element (toolbar) injected for each view.
Each view can have a slightly different toolbar (heading, buttons etc)
I would like to declare this toolbar in markup in the view so that I can bind data to it that the view is already using, and it's easier to maintain.
My understanding is that I could use a view for the injecting, but all the examples I have seen show it being populated from a template referenced in the routing file.
I have seen a directive used for updating the page title which does similar to what I want, https://github.com/apparentlymart/angularjs-viewhead but when I replicated/altered it and tried injecting complex html markup it didn't like it.
What is the recommended angular approach to solving this problem? Am I approaching the problem the wrong way?
Here is a simplified example.
http://plnkr.co/edit/n23vcBAc4tZUqBxnxcaY?p=preview
<!DOCTYPE html>
<html lang="en" data-ng-app="example">
<head>
<meta name="viewport" content="initial-scale=1" />
</head>
<body>
<a ui-sref="view1" class="md-button" >View 1</a>
<a ui-sref="view2" class="md-button" >View 2</a>
<div class="page-contents">
<div class="toolbar">This should be replaced with the toolbar from each page</div>
<div class="content-wrapper">
<div data-ui-view="page"></div>
</div>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<script src="script.js"></script>
</body>
</html>
<div class="view1" style="background-color: yellow;">
<div class="toolbar-1" style="background-color: gray;">Toolbar 1</div>
<h2>View 1</h2>
<div>View contents</div>
</div>
<div class="view2" style="background-color: lightgreen;">
<div class="toolbar-2" style="background-color: gray;">Toolbar 2</div>
<h2>View 2</h2>
<div>View contents</div>
</div>
angular
.module('example', [
'ui.router'
]);
(function () {
'use strict';
angular
.module('example')
.config(configureRoutes);
configureRoutes.$inject = ['$stateProvider', '$urlRouterProvider'];
/* #ngInject */
function configureRoutes($stateProvider, $urlRouterProvider) {
$stateProvider
.state('view1', {
url: '/view1',
views: {
'page': {
templateUrl: 'view1.html',
}
}
})
.state('view2', {
url: '/view2',
views: {
'page': {
templateUrl: 'view2.html'
}
}
})
$urlRouterProvider.otherwise('/view1');
}
})();

The way i solved this was to create a toolbar service and had it populated from the controller. It didn't achieve my original goal of putting it in markup, but it did simplify the implementation.

Related

AngularJS Route does not loading view

My project structure is looks like this:
I tried to make a single page application using this image. When index.html page will launch it will by default load registration.html in ng-view. But when index.html loads it does not load the registration.html as ng-view as expected.
And my files for index.html,main.css and mainAppRouter.js are below:
//mainAppRouter.js
(function () {
var myModule = angular.module('studentInfo', ['ngRoute']);
myModule.config(function ($routeProvider) {
$routeProvider
.when('/registration', {
templateUrl : '../views/registration.html',
controller: 'regController'
})
.otherwise({
redirectTo: '/registration'
});
console.log("checking");
});
myModule.controller('regController', function ($scope) {
$scope.message = 'This is Add new order screen';
console.log("checking");
});
});
/*man.css*/
.studentInfo{
margin-top: 100px;
}
.navbar{
padding: 1em;
}
.navbar-brand {
padding:0;
}
<!--index.html-->
<!DOCTYPE html>
<html data-ng-app="studentInfo">
<head>
<script src="lib/js/angular.min.js"></script>
<script src="lib/js/jquery-3.0.0.min.js"></script>
<script src="lib/js/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/js/angular-route.js"></script>
<script src="app/route/mainAppRouter.js"></script>
<link rel="stylesheet" href="lib/css/bootstrap.css" />
<link rel="stylesheet" href="lib/css/bootstrap-theme.css" />
<link rel="stylesheet" href="app/css/main.css" />
<title>A demo Angular JS app</title>
</head>
<body>
<div class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#"> <span><img src="app/images/people.png"/></span> Student Info </a>
</div>
<ul class="nav nav-pills navbar-right" data-ng-controller="NavbarController">
<li role="presentation">Registration</li>
<li role="presentation">Student Details</li>
</ul>
</div>
</div>
<div class="container">
<div class="col-md-4 col-md-offset-4" data-ng-controller="regController">
<h1>Student Info</h1>
</div>
<div ng-view></div>
</div>
</body>
</html>
All my codes are in this github repo
What should i do to correct my problem?
I think the problem is because you have not specified any controller for your ng-view and also you have to set your base URL correctly.
$routeProvider
.when('/registration', {
templateUrl :'http://localhost/StudentInfo/app/views/registration.html',
controller: 'regController'
})
And remove the controller tag from HTML.Your controller tag was outside the scope of ng-view.
<div class="container">
<div class="col-md-4 col-md-offset-4" >
<h1>Student Info</h1>
</div>
<div ng-view></div>
</div>
And there is a syntax error in your controller as well
myModule.controller('regController', function ($scope){
$scope.message = 'This is Add new order screen';
})
UPDATED ANSWER: Another reason why this does not work is that you are running your example off the file system (using the file:// protocol) and many browsers (Chrome, Opera) restricts XHR calls when using the file:// protocol. AngularJS templates are downloaded via XHR and this, combined with the usage of the file:// protocol results in the error you are getting.
For more details: Couldn't load template using templateUrl in Angularjs

controller alias for index.html page

I have a controller class named "BaseCtrl". This controller class takes care of global functions for the default/root HTML page "index.html". As my understanding of TypeScript (I am a TypeScript newbie), to use a controller for some HTML view, there are 3 things to do:
1) On the HTML view, I don't need to call controller explicitly. That is I don't need to use ng-controller attribute.
2) For 1) to be working, in route class of my application, I need to use a special property like "controllerAs" to specify the controller's alias (e.g controllerAs : "bc".
For example,
$routeProvider
.when("/login", { controller: "LoginCtrl", templateUrl: "app/views/login.html", controllerAs: "lc" });
3) Because $scope is not used, to access all stuffs (methods, properties) of controller class, I have to use the the controller's alias like "bc" from 2). For example, ng-model="bc.FirstName" etc.
My question: I have controller "BaseCtrl" as mentioned above. But this controller is not tied with any route in my application route class (please see my below route class codes). That means I don't have an alias for that controller. So, how can I call or access the controller's stuffs on the default/root "index.html"? Do I have to use "$scope" in the controller class' codes the same as in traditional non-TypeScript codes so that I do not worry about using controller's alias in view? I am using TypeScript for Angular codes.
Thank you for your help.
index.html codes:
<!DOCTYPE html>
<html>
<head>
<title>AngularJS With TypeScript In Visual Studio</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="scripts/angular.js"></script>
<script src="scripts/angular-route.js"></script>
<script src="app/app.js"></script>
<script src="app/Constants/Constants.js"></script>
<script src="app/routes.js"></script>
<script src="app/models/AuthToken.js"></script>
<script src="app/services/SessionSrvc.js"></script>
<script src="app/controllers/BaseCtrl.js"></script>
</head>
<body ng-app="angularWithTs">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">Angular URl-Based routing</a>
</div>
<ul class="nav navbar-nav">
<li>Login</li>
<li>Register</li>
<li>Presidents</li>
<li>Contacts</li>
<li>Logout</li>
</ul>
<ul class="nav navbar-nav pull-right">
<li>
<a disabled><span class="label label-success pull-right" ng-if="bc.loggedIn()">Logged In</span> </a>
</li>
</ul>
</div>
</nav>
<div>
<div ng-view></div>
</div>
</div>
</div>
</div>
</body>
</html>
route class codes:
/// <reference path="../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../scripts/typings/angularjs/angular-route.d.ts"/>
module angularWithTs {
"use strict";
function routes($routeProvider: ng.route.IRouteProvider, $locationProvider: ng.ILocationProvider) {
$routeProvider
.when("/login", { controller: "LoginCtrl", templateUrl: "app/views/login.html", controllerAs: "lc" });
$routeProvider
.when("/logout", { controller: "LogoutCtrl", templateUrl: "app/views/logout.html", controllerAs: "loc" });
$routeProvider.otherwise({ redirectTo: "/" });
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}
routes.$inject = ["$routeProvider", "$locationProvider"];
angular.module("angularWithTs").config(routes);
}
BaseCtrl class codes:
module angularWithTs {
"use strict";
export class BaseCtrl {
static $inject = ["$location", "SessionSrvc"];
_sessionSrvc: SessionSrvc;
_$location: ng.ILocationService; // http://notebookheavy.com/2013/05/22/angularjs-and-typescript/
constructor($location: ng.ILocationService, sessionSrvc: SessionSrvc) {
this._sessionSrvc = sessionSrvc;
this._$location = $location;
}
loggedIn(): boolean {
return this._sessionSrvc.getToken() != "undefined";
}
OnLogoutButtonClicked() : void {
// do some stuffs
}
}
angular.module("angularWithTs").controller("BaseCtrl", BaseCtrl);
}
There is two ways to link controller with partial:
Using route, and you can define controllerAs property in the route object.
By defining ng-controller directive on some element. In this case you still can define alias. Example : <div ng-controller="BaseCtrl as vm">{{vm.name}}</div> So vm here an alias.
Of course case 1 is better practise, especially in case TypeScript usage. But choose which is better fit for your app.

AngularJS + Angular UI Router: templateUrl return Blank Page

I'm just starting learning the angularjs and I want to use it for creating a ui template. I want to make a static HEADER and FOOTER and the only thing that will be dynamic is the CONTENT. My issue is that my It returns me a blank web page.
Thanks in advance guys.
index.html
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<meta charset="utf-8">
<title>UI-Router</title>
<link rel="stylesheet" href="">
<!-- START LOAD VENDORS -->
<script src="js/jquery/jquery.min.js"></script>
<script src="js/angular/angular.min.js"></script>
<script src="js/angular/angular-ui-router.min.js"></script>
<!-- END LOAD VENDORS -->
<!-- START LOAD SOURCE CODE -->
<script src="js/app.js"></script>
<!-- END LOAD SOURCE CODE -->
</head>
<body ui-view>
</body>
</html>
app.js
var app = angular.module('app', ['ui.router'])
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('index',{
abstract: true,
url: '/index',
templateUrl: 'view/app.html'
})
}])
view/header.html
<ul>
<li>US</li>
<li>626.205.3838</li>
<li>cert#abkrescue.com</li>
<li>Search</li>
</ul>
<ul>
<li>Facebook</li>
<li>Twitter</li>
<li>Instagram</li>
<li>LinkedIn</li>
</ul>
view/footer.html
<div>
<span>name here</span>
<span>partner</span>
<span>subscribe</span>
<ul>
<h3>get to know us</h3>
<li>blog</li>
<li>stories</li>
<li>staff</li>
</ul>
<ul>
<h3>connect</h3>
<li>contact</li>
<li>help</li>
<li>request</li>
</ul>
<ul>
<h3>resource</h3>
<li>download</li>
<li>financial</li>
<li>donors</li>
</ul>
<ul>
<h3>get involved</h3>
<li>volunteer</li>
<li>partnership</li>
<li>donate</li>
</ul>
</div>
view/app.html
<div data-ng-include=" 'view/header.html' "></div>
<div data-ng-include=" 'view/footer.html' "></div>
You cannot transition to an abstract state
i've created a working plnkr here: https://plnkr.co/edit/yRazozMjTM99tCKFFmIl?p=preview
$stateProvider
.state('index',{
url: '/',
templateUrl: 'view/app.html'
})
Try using the ui-view element directive. And make sure you are referring the template correctly
<body>
<ui-view></ui-view>
</body>
The correct way to do this is to have separate ui-view directives for your header, content and the footer.
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<title>UI-Router</title>
<link rel="stylesheet" href="">
<!-- START LOAD VENDORS -->
<script src="js/jquery/jquery.min.js"></script>
<script src="js/angular/angular.min.js"></script>
<script src="js/angular/angular-ui-router.min.js"></script>
<!-- END LOAD VENDORS -->
<!-- START LOAD SOURCE CODE -->
<script src="js/app.js"></script>
<!-- END LOAD SOURCE CODE -->
</head>
<body>
<div ui-view="header">
<div ui-view="content">
<div ui-view="footer">
</body>
</html>
Define the template for each ui-view in the state config function and remove the abstract: true option. More on it here: what is the purpose of use abstract state?
app.js
var app = angular.module('app', ['ui.router'])
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('index',{
url: '/index',
views: {
'header': {
templateUrl: 'view/header.html'
},
'content': {
templateUrl: 'view/app.html'
},
'footer': {
templateUrl: 'view/footer.html'
}
}
})
}])
Also wrap your header.html code in a div tag.
header.html
<div>
<ul>
<li>US</li>
<li>626.205.3838</li>
<li>cert#abkrescue.com</li>
<li>Search</li>
</ul>
<ul>
<li>Facebook</li>
<li>Twitter</li>
<li>Instagram</li>
<li>LinkedIn</li>
</ul>
</div>
Now the header and footer will remain fixed and you can change your content based on states by adding other state like this:
.state('index.two',{
url: '/index/two',
views: {
'content#': {
templateUrl: 'view/two.html'
}
}
})

how to add routing in angularjs app?

I am new to angularjs ,i make a sample app with custom directives now i add routing as well but it doesn't working.When i start project index file is loaded in browser that is working fine but when i click on nav bar links then about and contact page is not displayed it's remains on index.html.
here is my index.html:
<html ng-app="myApp">
<head>
<title>Reddit New World News (Task)</title>
<link href='http://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
<script src="angular/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-route.min.js"></script>
<script src="myApp.js"></script>
<script src="myAppCtrl.js"></script>
<script src="headerDirective.js"></script>
<script src="searchDirective.js"></script>
<script src="myDataDirective.js"></script>
<!-- start menu -->
</head>
<body>
<div header-table></div>
<div class="content" ng-controller = "myAppCtrl">
<div class="container" >
<div ng-view></div>
</div>
</div>
</body>
</html>
myAppCtrl:
// TODO: Wrap in anonymous function
(function () {
var myApp = angular.module('myApp', ['ngRoute']);
// configure our routes
myApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'code/index.html',
controller : 'myAppCtrl'
})
// route for the about page
.when('/about', {
templateUrl : 'code/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'code/contact.html',
controller : 'contactController'
});
});
// TODO: min-safe with bracket notation
myApp.controller('myAppCtrl', ['$scope', '$http', function($scope, $http) {
$scope.sortType = '';
$scope.sortReverse = true;
// TODO: Keep lines short - it's easier to read
$http.get("https://www.reddit.com/r/worldnews/new.json")
.success(function (response) {
$scope.stories = response.data.children;
});
}]);
myAppCtrl.controller('aboutController',function(){
// create a message to display in our view
$scope.message = 'Everyone come and see how good I look!';
});
myAppCtrl.controller('contactController', function($scope) {
$scope.message = 'Contact us! JK. This is just a demo.';
});
})();
headerDirective.html:
<div class="top-header"></div>
<div class="container">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="header">
<h1>Reddit</h1>
</div>
<div class="header-right">
<h2>World's Latest News</h2>
</div>
<div>
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</div>
</nav>
<div class="clearfix"></div>
</div>
any guide thanks.
Like some people allready mentioned, you should deffinitly read the docs and probably watch some tutorials. I'm trying to see what you are doing, but it's not clear to me.
But I think I see where it goes wrong in your thoughts:
You have 3 'templates' index.html, about.html and contact.html. In your config You use them in your routing. By watching your files my guess is that you are expecting that, depending on the route, these html-files will be loaded. Just like when redirecting to that page.
What you should do is make a index.html with the html You use on every page. this can be the <head></head> only, but can also contain your header with navigation and footer. Then you use <ng-view></ng-view> or <div ng-view></div> where you want the templates to load in your page. These templates don't need to contain the parts you allready defined in your index.html. You have only the content in it.
So, a simple example:
index.html
<html>
<head>
//loading your scripts etc.
</head>
<body>
<ng-view></ng-view>
</body>
</html>
Than, instead of creating a template called index.html, you make a template home.html with the content:
<div class="container">
<h1>My Home</h1>
</div>
Now the contentpart from your home.html will load in your index.html where you define de ng-view.
An other thing I noticed is the path you define in templateUrl. You define the location as code/about.html. You have to give it the path from your index.html (the main html) In your case that will just be templateUrl: 'about.html'.
I would suggest putting the different files in different folders. So, one for your templates, one for your js-files (probably a js-folder with another folder in it for your js-file with directives etc.).
I hope this will help you on your way. But deffinitly read the docs and watch some tutorials. It will help you a lot.

ui-serf attribute is automatic rename in angular js

I write simple code for understanding ui-router of angular js but code is working properly but my partial html code is automatic renaming, i am unable to undertable why it happing
Html code is <a ui-sref="state1.list">Show List</a>
and browser code is <a ui-sref="state.list" class="ng-scope">Show List</a> due to rename the state1 to state my another partial view is not calling and give error.
Please take a look
<!--index.html-->
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>Angular UI Router Test </title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
</head>
<body>
<a ui-sref="state1"> State 1</a>
<div ui-view></div>
<script>
var module = angular.module('myApp', ['ui.router']);
module.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/state1');
$stateProvider
.state('state1', {
url: '/state1',
templateUrl: 'partials/state1.html'
})
.state('state1.list', {
url: '/list',
templateUrl: 'partials/state1.list.html',
controller: function ($scope) {
$scope.items = ["A", "List", "Of", "Items"];
}
});
}]);
</script>
</body>
</html>
<!--state1.html-->
<h1>State 1</h1>
<hr />
<a ui-sref="state1.list">Show List</a>
<div ui-view></div>
<!--state1.list.html-->
<h3>List of State 1 Items</h3>
<ul>
<li ng-repeat="item in items">{{ item }}</li>
</ul>
what i am missing?
I would say, you are most likely not observing the proper element. I created working plunker here, and it shows, that this:
<a ui-sref="state1.list">Show List</a>
is generated as this
<a ui-sref="state1.list" class="ng-scope" href="#/state1/list">Show List</a>
As we can see no change from state1.list into state.list
The biggest change made? - used are up to date angular and UI-Router versions
Check it here, and maybe try to reset it to the "wrong state described above"

Resources