how to display dynamic content in a single page using angularjs - html

I am new to AngularJs and for stackoverflow too,hope will get a solution for my problem here. I`m trying to display the details of an experiment(in the same page)based on the name of the experiment which is coming from the URL when the name is clicked(index.html). Here the problem is,when I click an experiment name,it is coming in the URL but not able to fetch its details.Can anyone help me to solve.Here is my code.
//experiments.json
[
{
"sl_no" : "1",
"name" : "BCD adders",
"objective" : "It deals with the desinging of reversible BCD adders."
},
{"sl_no" : "2",
"name" : "Online Banking",
"objective" : "It deals with the online Transactions."}
]
//index.html
<!DOCTYPE html>
<html ng-app="experimentApp">
<head>
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="js/controller.js"></script>
</head>
<body>
<div id="main">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Angular Routing Example</a>
</div>
<br>
<ul class="nav navbar-nav navbar-left">
<div>
<ul ng-controller="ExperimentListCtrl">
<li ng-repeat="experiment in experiments">
<a href="#/{{experiment.name | encodeURI}}">
<strong>{{experiment.sl_no}}. {{experiment.name}}</strong><br>
</a>
</li>
</ul>
<div ng-include="experiment-detail.html"></div>
</div>
</ul>
</div>
</nav>
</div>
</body>
</html>
//controller.js
// create the module and name it experimentApp
var experimentApp = angular.module('experimentApp', ['ngRoute']);
// configure our routes
experimentApp.config(function($routeProvider) {
$routeProvider.
when('/:experimentName', {
templateUrl : 'experiment-detail.html',
controller : 'ExperimentDetailCtrl'
}).
otherwise({
redirectTo: '/'
});
});
experimentApp.factory('experiments', function($http){
function getData(callback){
$http({
method: 'GET',
url: 'experiments.json',
cache: true
}).success(callback);
}
return {
list: getData,
find: function(name, callback){
getData(function(data) {
var experiment= data.filter(function(entry){
return entry.name === name;
})[0];
callback(experiment);
});
}
};
});
experimentApp.controller('ExperimentListCtrl', function ($scope, experiments){
experiments.list(function(experiments) {
$scope.experiments = experiments;
});
});
experimentApp.controller('ExperimentDetailCtrl', function ($scope, $routeParams,
experiments){
experiments.find($routeParams.experimentName, function(experiment) {
$scope.experiment = experiment;
});
});
experimentApp.filter('encodeURI', function(){
return window.encodeURI;
});
//experiment-detail.html
<div>
<strong>{{experiment.sl_no}}. {{experiment.name}}</strong><br>
</br></br>
<strong>Aim :</strong>{{experiment.objective}}
</div>

You need to encode the experiment.name only, so change :
experimentApp.filter('encodeURI', function(){
return window.encodeURI;
});
to :
experimentApp.filter('encodeURI', function(stringToEncode){
return encodeUri(stringToEncode);
});

Related

How do I communicate between sibling controllers?

Here's my code:
<div ng-controller="mainCtrl">
<button ng-click="onclick()"></button>
<button ng-click="onclick()"></button>
<button ng-click="onclick()"></button>
{{display}}
</div>
<div ng-controller="SecondController">{{display}}</div>
<div ng-controller="lastController">{{display}}</div>
I have to get some message in each div when the user clicks on the button.
I've tried the below code:
app.controller('mainCtrl',function($scope,$rootScope){
$scope.OnClick = function (msg) {
$rootScope.$broadcast("firstEvent",{});
}
$scope.$on("firstEvent", function (msg ) {
$scope.display = "hello world";
});
});
app.controller('SecondController',function( $scope){
$scope.$on("firstEvent", function (msg) {
$scope.display = "hello how Are you";
});
});
app.controller('lastController',function($scope) {
$scope.$on("firstEvent", function (msg) {
$scope.display = "this is my Query";
});
});
When the user clicks on each button, it should get data in each div.
How come its only possible with $on, $event and $broadcast?
$broadcast() sends an even downwards from parent to child controllers. The $emit() method, on the other hand, does exactly opposite. It sends an event upwards from the current controller to all of its parent controllers.
This is a simple example of communicating between controllers
angular.module("app", [])
.controller("mainCtrl", [
"$scope", "$rootScope",
function($scope, $rootScope) {
$scope.go = function(msg) {
if (msg == 1) {
$scope.display = "hello firstEvent";
} else if (msg == 2) {
$rootScope.$broadcast("showSomething", {});
} else {
$rootScope.$broadcast("showGoodBye", {});
}
};
}
]).controller("SecondController", [
"$scope", "$rootScope",
function($scope, $rootScope) {
$scope.$on("showSomething", function(msg) {
$scope.display = "hello Something";
});
}
]).controller("ThirdController", [
"$scope", "$rootScope",
function($scope, $rootScope) {
$scope.$on("showGoodBye", function(msg) {
$scope.display = "hello GoodBye";
});
}
]);
<div ng-app="app">
<div ng-controller="mainCtrl">
mainCtrl : {{display}}
<br>
<button ng-click="go(1)"> Show Hello </button>
<button ng-click="go(2)"> Show Something </button>
<button ng-click="go(3)"> Show GoodBye </button>
</div>
<hr>
<div ng-controller="SecondController">
SecondController : {{display}}
<hr>
</div>
<div ng-controller="ThirdController">
SecondController : {{display}}
<hr>
</div>
</div>
A complete Tour
Here is the solution:
I prefer not to use rootScope, you can use intermaeidate service to share data between two controllers
Solution with services:
Here is how service looks:
app.service('StoreService',function(){
var data;
this.save=function(data){
this.data=data;
};
this.getData=function(){
return this.data;
};
});
Using a service without rootScope
Demo without rootScope
Solution with rootScope
var app = angular.module('myApp', []);
app.controller('mainCtrl',function($scope,$rootScope){
$scope.buttonclick = function (msg) {
var object = {
data: msg
}
$rootScope.$broadcast("firstEvent",object);
}
$rootScope.$on("firstEvent", function (event, msg) {
$scope.display = msg.data;
});
})
app.controller('SecondController',function( $scope, $rootScope){
$rootScope.$on("firstEvent", function (event, msg) {
$scope.display = msg.data;
});
})
app.controller('lastController',function( $scope, $rootScope){
$rootScope.$on("firstEvent", function (event, msg) {
$scope.display = msg.data;
});
})
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp">
<div ng-controller="mainCtrl">
<button ng-click="buttonclick('button1')">button1</button>
<button ng-click="buttonclick('button2')">button2</button>
<button ng-click="buttonclick('button3')">button3</button>
<br>
{{display}}
</div>
<div ng-controller="SecondController">{{display}}</div>
<div ng-controller="lastController">{{display}}</div>
</div>
</body>
</html>
Please run the above snippet
Here is a Working DEMO

ng-show does not evaluate expression

I am new to Angularjs and practicing it by doing some tasks. Here I am creating an object in controller and the object values in my web page. But here the ng-show does not evaluate the below expression. But if I create a variable in controller as $scope.ngshow = false; it will work. Please help me why the below code did not worked.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-show = "a.name"> Name {{a.name}} </li>
<li ng-show = "a.id"> Id {{a.id}}</li>
<li ng-show = "a.address"> Address {{a.address}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a = {
'name' : 'false',
'id' : 'true',
'address' : 'false'
};
});
</script>
<p>ng-show didnt accept expressions.</p>
</body>
</html>
Thanks for your valuable time.
You should not use true or false as string
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a = {
'name' : false,
'id' : true,
'address' : false
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-show = "a.name"> Name {{a.name}} </li>
<li ng-show = "a.id"> Id {{a.id}}</li>
<li ng-show = "a.address"> Address {{a.address}}</li>
</ul>
</div>
<script>
</script>
<p>ng-show didnt accept expressions.</p>
well, apperenly it's a version conflict. This version 1.4.8 of angular ng show support value as boolean not string boolean. So you need to remove the quotes around the values
$scope.a = {
'name' : false,
'id' : true,
'address' : false
};
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a = {
'name' : false,
'id' : true,
'address' : false
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-show = "a.name"> Name {{a.name}} </li>
<li ng-show = "a.id"> Id {{a.id}}</li>
<li ng-show = "a.address"> Address {{a.address}}</li>
</ul>
</div>
But if you are using a lower version like 1.2.23 then angular identify string values as boolean if the values are true or false
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a = {
'name' : 'false',
'id' : 'true',
'address' : 'false'
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-show = "a.name"> Name {{a.name}} </li>
<li ng-show = "a.id"> Id {{a.id}}</li>
<li ng-show = "a.address"> Address {{a.address}}</li>
</ul>
</div>
Just remove the single quotes from true and false.If you put quotes on true and false , they are strings.In that case ng-show is checking whether variable is defined or not.In your case, since it have string true/false value, ng-show is considering expression as defined hence true.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-show="a.name"> Name {{a.name}} </li>
<li ng-show="a.id"> Id {{a.id}}</li>
<li ng-show="a.address"> Address {{a.address}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a = {
'name': false,
'id': true,
'address': false
};
});
</script>
<p>ng-show didnt accept expressions.</p>
</body>
</html>

when using routeparams in angular,templateurl not working?

https://plnkr.co/edit/oo05d6H6AxuJGXBAUQvr?p=preview
I have created an array of items and when I click on each item details page will be displayed ,for all the items in the array I have used same details page,can anyone look at my plunker and explain why the templateURL is not working when I click on an item?
var app = angular.module("myApp", ["ngRoute"]);
app.controller('mobileController', function($scope) {
$scope.items = [{
name: 'Iphone',
}, {
name: 'Oneplus'
}, {
name: 'Moto'
}];
});
app.config(function($routeProvider) {
$routeProvider
.when('/item/:itemName', {
templateUrl: 'details.html',
controller: 'ItemCtrl'
});
app.controller('ItemCtrl', ['$scope', '$routeParams',
function($scope, $routeParams) {
$scope.itemName = $routeParams.itemName;
}
]);
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script src="script.js"></script>
<body ng-app="myApp" ng-controller="mobileController">
<h2> Welcome to Mobile Store</h2>
<p>Search:<input type="text" ng-model="test"></p>
<ul>
<li ng-repeat="item in items|filter:test">{{ item.name }}
</li>
</ul>
<div ng-view></div>
</body>
</html>
here is my details page
<!DOCTYPE html>
{{itemName}}
is it because of a mismatch?
.when('/item/:itemName', {
a href="/items/{{item}}"
there's an extra s there
Summary of problems:
Your ItemCtrl is currently defined inside your module's config function. Move it out of there
app.config(function($routeProvider) {
$routeProvider
.when('/item/:itemName', {
templateUrl: 'details.html',
controller: 'ItemCtrl'
});
}); // you were missing this
app.controller('ItemCtrl', ['$scope', '$routeParams',
Your route is /item/:itemName and since you're not using HTML5 mode, you need to create your href attributes with a # prefix. For example
ng-href="#/item/{{item.name}}"
Fixed demo here ~ https://plnkr.co/edit/rKHsBMFcXqJUGp8Blx7Q?p=preview

AngularJS + load multiple pages

I am new in angularjs.
I tried to load multiple page because login page is different design(without left menu, header,footer, nav bar) but other pages are have inculde header, footer, navbar like this.
For example, I have index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="vendor/theme_files/js/jquery.min.js"></script>
</head>
<body class="nav-md" ng-app="myApp" >
<div class="container body">
<div class="main_container">
<!-- left menu -->
<div left-menu></div>
<!-- /left menu -->
<!-- top navigation -->
<div top-navigation></div>
<!-- /top navigation -->
<!-- page content -->
<div class="right_col" role="main" >
<!-- page content -->
<div id="right-content" ng-view=""></div>
<!--<div ng-view=""></div>-->
<!-- footer content -->
<div footer-content></div>
<!-- /footer content -->
<!-- /page content -->
</div>
</div>
</div>
<script src="vendor/angular/angular.js"></script>
<script src="vendor/angular-resource/angular-resource.js"></script>
<script src="vendor/files/angular-route.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
<script src="js/app.js"></script>
</body>
</html>
app.js:
var app = angular.module('myApp', ['ngRoute', 'ngStorage', 'lbServices', 'ui.router']);
app.config(['$routeProvider', '$httpProvider',
function($routeProvider, $httpProvider) {
$routeProvider.when('/login', {
templateUrl : 'views/login.html',
controller : 'userController'
}).when('/register', {
templateUrl : 'views/register.html',
controller : 'userController'
}).when('/offerletter', {
templateUrl : 'views/offerLetter.html',
controller : 'offerLetterController'
}).otherwise({
redirectTo : '/login'
});
$httpProvider.interceptors.push(['$q', '$location', '$localStorage',
function($q, $location, $localStorage) {
return {
'request' : function(config) {
config.headers = config.headers || {};
if ($localStorage.token) {
config.headers.Authorization = $localStorage.token;
}
return config;
},
'responseError' : function(response) {
if (response.status === 401 || response.status === 403) {
$location.path('/signin');
}
return $q.reject(response);
}
};
}]);
}]);
app.directive('leftMenu', function() {
return {
restrict : 'A',
templateUrl : "views/pages/left-menu.html",
replace : true
};
//
});
app.directive('topNavigation', function() {
return {
restrict : 'A',
replace : true,
templateUrl : "views/pages/top-navigation.html",
scope : {
user : '='
}
};
});
app.directive('rightContent', function() {
return {
restrict : 'A',
replace : true,
templateUrl : "views/pages/content.html"
};
});
app.directive('footerContent', function() {
return {
restrict : 'A',
replace : true,
templateUrl : "views/pages/footer.html"
};
});
Now I need login.html which is totally different from index.html (don't need index's header, footer, sidebar) . How to combine login.html?
don't style your page in the index. Keep index.html as just a blank container. then style your login and other pages in their respective html pages. Use the ionic tabs app as an example of how the structure should be done.

Angular factory function not reached.

I'm learning how to use Angularjs with ROR through this tutorial https://thinkster.io/angulartutorial/angular-rails/
I've come to a point where when I'm adding a new function for a service which is supposed to get all posts we have in the db. However When I run the code the page does not load anymore. Or at least the html is not rendered. There is no indication of errors in the elements inspections. However I'm not sure it has to do with the placing of the function in the js file. I'm totally new to js and I still struggle to read the sintax and spot errors in the code. Rubymine has given a clue with and Unreacheble code warning for the o.getAll. If someone could have a look at it and give me any hints it would be great.
Apologies to all the code in one file both html and js. I'm having some issues with the assets pipeline that I mean to get fixed soon.
app.js
Blockquote
angular.module('flapperNews', ['ui.router'])
//Provider
.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
})
$urlRouterProvider.otherwise('home');
}])
//Posts service
.factory('posts', ['$http', function($http){
var o = {
posts: []
};
return o;
o.getAll = function() {
return $http.get('/posts.json').success(function(data){
angular.copy(data, o.posts);
});
};
}])
//Main Controller
.controller('MainCtrl', [
'$scope',
'posts',
function($scope, posts){
$scope.posts = posts.posts;
$scope.addPost = function(){
if(!$scope.title || $scope.title == '') { return; }
$scope.posts.push({
title: $scope.title,
link: $scope.link,
upvotes: 0,
comments: [
{author: 'Joe', body: 'Cool post!', upvotes: 0},
{author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0}
]
});
$scope.title = '';
$scope.link = '';
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}])
//Posts Controller
.controller('PostsCtrl', [
'$scope',
'$stateParams',
'posts',
function($scope, $stateParams, posts){
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function(){
if($scope.body === '') { return; }
$scope.post.comments.push({
body: $scope.body,
author: 'user',
upvotes: 0
});
$scope.body = '';
};}]);
>
and following the application.html.erb
> Blockquote
<html>
<head>
<title>FlapperNews</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="javascripts/app.js"></script>
<script src="javascripts/application.js"></script>
<%= csrf_meta_tags %>
</head>
<body ng-app="flapperNews">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(post)"></span>
{{post.upvotes}}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()"
style="margin-top:30px;">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Title"
ng-model="title">
</div>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Link"
ng-model="link">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
<script type="text/ng-template" id="/posts.html">
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</h3>
</div>
<div ng-repeat="comment in post.comments | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(comment)"></span>
{{comment.upvotes}} - by {{comment.author}}
<span style="font-size:20px; margin-left:10px;">
{{comment.body}}
</span>
</div>
<form ng-submit="addComment()"
style="margin-top:30px;">
<h3>Add a new comment</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Comment"
ng-model="body">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
</body>
</html>
From factory you are returning o before the getAll function so it is unreachable
.factory('posts', ['$http', function($http){
var o = {
posts: []
};
//removed return
o.getAll = function() {
return $http.get('/posts.json').success(function(data){
angular.copy(data, o.posts);
});
};
return o; //at the added return
}])