I'm creating an application that has two boxes. On the left div it will display a list of clickable links, once clicked it will display that links information on the div to the right. I've managed to get my data to hide and show when the link is clicked but only within the same div. What's the best appraoch when it comes to doing this with Angular?
<div class="row" ng-controller="faqController">
<div class="col-md-6">
<div class="col-md-12">
<div class="guide-section">
<h1>Select a Topic</h1>
<ul ng-repeat="faq in faqs">
<li>{{ faq.title }}</li>
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="guide-section">
<div ng-repeat="faq in faqs">
<h1>{{ faq.title }}</h1>
<p>{{ faq.info }}</p>
</div>
</div>
</div>
</div>
Angular:
var myApp = angular.module('supportApp', ['ngRoute', 'ngResource']);
myApp.controller('faqController', ['$scope', '$http', function($scope, $http) {
$scope.showData = true;
$http.get('data/faq.json').
success(function(data, status, headers, config) {
$scope.faqs = data;
//console.log(data);
}).
error(function(data, status, headers, config) {
//Complete error fallback
});
}]);
you should add to your second div ng-show='showdata' - another option would be to show if $scope.showFaq is populated, which would eliminate dealing with another variable
Also, you ng-repeat should be in your li not ul - ng-repeat should be on the element you want to repeat (unlike most for loops in other languages)
Once you populate the $scope.faqs, the list will show with the links.
Once you click the selected faq, it is used to populate the $scope.showFaq and $scope.showData is set to true...
// main.js
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.showData = false;
$scope.showHide = function(faq) {
$scope.showData = true;
$scope.showFaq = faq;
};
$scope.faqs = [
{'title': 'title 1', 'info': 'info 1'},
{'title': 'title 2', 'info': 'info 2'}
];
});
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8" />
<title>Custom Plunker</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="col-md-6">
<div class="col-md-12">
<div class="guide-section">
<h1>Select a Topic</h1>
<ul>
<li ng-repeat="faq in faqs"><a ng-click="showHide(faq)">{{ faq.title }}</a></li>
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="guide-section" ng-show="showData">
<h1>{{ showFaq.title }}</h1>
<p>{{ showFaq.info }}</p>
</div>
</div>
</body>
</html>
Related
Here's my code:
controller.js
angular.module('myApp',['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show all the polls
.state('polls', {
url: '/polls',
templateUrl: 'views/polls.html',
controller: 'pollsController'
})
// show new polls
.state('new', {
url: '/polls/add',
templateUrl: 'views/newPoll.html',
controller: 'newController'
});
$urlRouterProvider.otherwise('/polls');
})
.controller('pollsController', function($scope,$http) {
$http.get('/polls').then(function(data, status, headers, config) {
$scope.result = data;
}).catch(function(data) {
$scope.result = data;
});
})
.controller('newController',function($scope,$http) {
$http.get('/polls/add').then(function(data,status,headers,config) {
$scope.result = data;
}).catch(function(data) {
$scope.result = data;
});
});
index.html
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<!-- <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootswatch/3.1.1/darkly/bootstrap.min.css"> -->
<link rel="stylesheet" type="text/css" href="views/css/style.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
<script type="text/javascript" src="controller.js"></script>
</head>
<body ng-app="myApp">
<div id="topheader">
<h1>myApp</h1>
</div>
<div class="topnav" id="topnavigation">
<a ui-sref-active="active" ui-sref="new">Add poll</a>
<a ui-sref-active="active" ui-sref="polls">All polls</a>
</div>
<div class="container">
<div ui-view></div>
</div>
</body>
</html>
polls.html
<div class="content">
<h2>View your polls!</h2>
<div class="allPolls" ng-repeat="item in result.data.polls">
<li> {{item.title}}
</li>
</div>
</div>
newPoll.html
<div class="content">
<form>
Title: <br><input type="text" name="title"><br>
Options (add line break between options): <br>
<textarea type="text" name="options">
</textarea>
<br>
<button type="button">Create new poll</button>
</form>
</div>
So now when I press the "Add poll"-button from the polls-page the page loads a page where is only the topnavigation-bar. When I press the "Add poll"-button again, the page loads the form from newPoll.html.
The url changes on the first click so everything should be working on the first click?
I have an array of jsons that have this structure:
[{
'playlist_name': 'abced',
'playlist_id': 123
}, {
'playlist_name': 'abcde',
'playlist_id': 123
}]
I want to insert this jsons in this div:
<div class="horizontal-tile" ng-repeat="todo in todos">
<div class="tile-left" style='min-height:100px;width:100px;'>
<div class="background-image-holder">
<img alt="image" class="background-image" src="img/project-single-1.jpg">
</div>
</div>
<div class="tile-right bg-secondary" style='min-height:100px;width: calc(100% - 100px);'>
<div class="description" style="padding:10px;">
<h4 class="mb8">{{ todo.playlist_name }}</h4>
</div>
</div>
</div>
And i iterate over the todo in todos that i get in this scope
Todos.get(12175507942)
.success(function(data) {
$scope.todos = data;
});
I get the data fine, however i can't seem to get the value playlist_name.
I print the data and i get this.
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]
with, each object being:
$$hashKey:"005"
playlist_id:"0DAlm2gb8DrtyRSXEKw07h"
playlist_name:"Rocola On The Go"
__proto__:Object
the code for the Todos.get
angular.module('todoService', [])
// super simple service
// each function returns a promise object
.factory('Todos', ['$http',function($http) {
return {
get : function(id) {
return $http.post('/api/getPlaylists',{"id":id});
},
create : function(todoData) {
return $http.post('/api/todos', todoData);
},
delete : function(id) {
return $http.delete('/api/todos/' + id);
}
}
}]);
I show the controllers code:
angular.module('todoController', [])
// inject the Todo service factory into our controller
.controller('mainController', ['$scope','$http','Todos', function($scope, $http, Todos) {
$scope.formData = {};
$scope.loading = true;
// GET =====================================================================
// when landing on the page, get all todos and show them
// use the service to get all the todos
Todos.get(12175507942)
.success(function(data) {
console.log(data);
$scope.todos = data;
$scope.loading = false;
});
// CREATE ==================================================================
// when submitting the add form, send the text to the node API
$scope.createTodo = function() {
// validate the formData to make sure that something is there
// if form is empty, nothing will happen
if ($scope.formData.text != undefined) {
$scope.loading = true;
// call the create function from our service (returns a promise object)
Todos.create($scope.formData)
// if successful creation, call our get function to get all the new todos
.success(function(data) {
$scope.loading = false;
$scope.formData = {}; // clear the form so our user is ready to enter another
$scope.todos = data; // assign our new list of todos
});
}
};
// DELETE ==================================================================
// delete a todo after checking it
$scope.deleteTodo = function(id) {
$scope.loading = true;
Todos.delete(id)
// if successful creation, call our get function to get all the new todos
.success(function(data) {
$scope.loading = false;
$scope.todos = data; // assign our new list of todos
});
};
}]);
And i will show the view page:
<!doctype html>
<!-- ASSIGN OUR ANGULAR MODULE -->
<html ng-app="scotchTodo">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Optimize mobile viewport -->
<title>Node/Angular Todo App</title>
<!-- load bootstrap -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.css" rel="stylesheet" type="text/css" media="all" />
<link href="css/theme.css" rel="stylesheet" type="text/css" media="all" />
<link href="css/custom.css" rel="stylesheet" type="text/css" media="all" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
<link href='http://fonts.googleapis.com/css?family=Lato:300,400%7CRaleway:100,400,300,500,600,700%7COpen+Sans:400,500,600' rel='stylesheet' type='text/css'>
<!-- SPELLS -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<!-- load angular -->
<script src="js/controllers/main.js"></script>
<!-- load up our controller -->
<script src="js/services/todos.js"></script>
<!-- load our todo service -->
<script src="js/core.js"></script>
<!-- load our main application -->
</head>
<!-- SET THE CONTROLLER -->
<body ng-controller="mainController">
<div class="main-container">
<section>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 col-sm-10 col-sm-offset-1 text-center">
<h4 class="uppercase mb16">Tus Playlists<br></h4>
<p class="lead mb80"><br></p>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-sm-offset-1 col-md-offset-2 col-md-8">
<div class="horizontal-tile" ng-repeat="todo in todos">
<div class="tile-left" style='min-height:100px;width:100px;'>
<div class="background-image-holder">
<img alt="image" class="background-image" src="img/project-single-1.jpg">
</div>
</div>
<div class="tile-right bg-secondary" style='min-height:100px;width: calc(100% - 100px);'>
<div class="description" style="padding:10px;">
<h4 class="mb8">{{ todo.playlist_name }}</h4>
</div>
</div>
</div>
<p class="text-center" ng-show="loading">
<span class="fa fa-spinner fa-spin fa-3x"></span>
</p>
</div>
</div>
</div>
</section>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/parallax.js"></script>
<script src="js/scripts.js"></script>
</body>
</html>
and here is the core.js
angular.module('scotchTodo', ['todoController', 'todoService']);
Your code is working fine as per the code given in OP.
DEMO
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.todos = [{
'playlist_name': 'abced',
'playlist_id': 123
}, {
'playlist_name': 'abcde',
'playlist_id': 123
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="horizontal-tile" ng-repeat="todo in todos">
<div class="tile-left" style='min-height:100px;width:100px;'>
<div class="background-image-holder">
<img alt="image" class="background-image" src="img/project-single-1.jpg">
</div>
</div>
<div class="tile-right bg-secondary" style='min-height:100px;width: calc(100% - 100px);'>
<div class="description" style="padding:10px;">
<h4 class="mb8">{{ todo.playlist_name }}</h4>
</div>
</div>
</div>
</div>
I am creating a small web app where I will show a chart of the top 10 popular TV shows. Then, When I go to the browser and inspect I get an error:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.6/$injector/unpr?p0=showProvider%20%3C-%20show%20%3C-%20MainController
<!doctype html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="css/main.css" rel="stylesheet" />
<!-- Angular JS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<body ng-app="Top10App">
<div class="header">
<div class="container">
10
</div>
</div>
<div class="main" ng-controller="MainController">
<div class="container">
<div class="content">
<!--TODO: Loop through shows and display each one with this HTML-->
<!--ng-repeat="show in shows" -->
<div>
<div class="rank">{{$index + 1}}</div>
<h2 class="series"> {{ index.series }}</h2>
<p class="genre">{{ index.genre }} </p>
<p class="run-start"> {{ index.run_start }}</p>
<p class="description"> {{ index.description }} </p>
</div>
</div>
</div>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/MainController.js"></script>
<!-- Services -->
<script src="js/services/show.js"></script>
</body>
</html>
Javascript
MainController.js
app.controller('MainController', ['$scope', 'show', function ($scope, show) {
show.success(function(data) {
$scope.show = data;
});
}]);
show.js
app.factory('Top10App', ['$http', function($http){
return $http.get('shows.json')
.success(function(data){
return data;
})
.error(function(err){
return err;
});
}]);
You're defining your service name as 'Top10App', so that's the way you should access it, not by the file name.
['$scope', 'Top10App', function ($scope, Top10App) { ...
Top10App.success(...
First, do you created the module? You should has something like:
// app.js
angular.module('app', []);
// maincontroller.js
angular.module('app').controller('myController, ...', [.......]);
// factory.js
angular.module('app').factory(...)
You are trying to inject show as a dependency for your controller, but it doesn't look like that is defined anywhere. That's why your error is telling you that it's an unknown provider.
I'm guessing you're trying to use your Top10App factory, so you need to inject it as such
app.controller('MainController', ['$scope', 'Top10App', function ($scope, Top10App) {
Top10App.success(...)
}
I'm a newbie to Angular and working on a project but I'm having an issue with displaying info in two different pages.
I have a browse page that displays profiles
I also have a homepage where I want to display the contents of the browse page plus other miscellaneous information.
To do that I created a component(browsePage)
Then I added the component to the home.view.html
<browse-page></browse-page>
but the profiles don't show up.
In my browse page the profiles do show up.
My code:
app.config.js
$routeProvider
.when('/home', {
RouteData: {
bodyStyle: {
//'background': 'url(../images/bg-7.jpg)repeat'
'background-color': 'white'
}
},
controller: 'HomeController',
templateUrl: 'home/home.view.html',
controllerAs: 'vm'
})
.when('/browse', {
RouteData: {
bodyStyle: {
//'background': 'url(../images/bg-10.jpg)repeat'
'background-color': 'white'
}
},
controller: 'BrowseController',
templateUrl: 'browse/browse.view.html',
controllerAs: 'vm'
})
home.controller.js
angular.module("mango").controller("HomeController", HomeController);
function HomeController() {
}
angular.module('mango').controller('ExampleController', ['$cookies', function($cookies) {
}]);
home.view.html
This is the home page<br>
Miscellaneous info goes here
<browse-page></browse-page>
Miscellaneous info goes here<br>
end of home page
browse.component.js
console.log("In browse.component.js");
angular.module("mango").component("browsePage",{
templateUrl:"browse/browse.view.html",
controller:BrowseController
});
browse.controller.js
angular.module("mango").controller("BrowseController", BrowseController);
BrowseController.$inject = ["$rootScope","$location","AuthenticationService","$http"];
function BrowseController($rootScope, $location, AuthenticationService, $http){
var vm = this;
$http.get('browse_profiles.json').success(function(data){
vm.data = data;
console.log("data==>");
console.log(data);
});
}
browse.view.html
<br><br>
<!-- Page Content -->
<div class="container">
<!-- Jumbotron Header -->
<header class="jumbotron hero-spacer" >
<form ng-submit="submit()" ng-controller="ExampleController">
Enter text and hit enter:
<input type="text" ng-model="text" name="text" />
<input type="submit" id="submit" value="Submit" />
</form>
</header>
<hr>
<!-- Page Features -->
<div class="row text-center">
<img id="mySpinner" src="/images/loader.gif" ng-show="loading" />
{{alpine}}
<div class="col-md-3 col-sm-6 hero-feature" ng-repeat="profile in vm.data">
<div class="thumbnail">
<img src="{{profile.thumbnail}}" alt="">
<div class="caption">
<div class="username-status">
<span class="username pull-left"><a ng-href="#/profile/{{profile.username}}">{{profile.username}}</a></span>
<p ng-class-odd="'circle odd'" ng-class-even="'circle even'"></p>
</div>
</div>
</div>
</div>
</div>
<!-- /.row -->
<hr>
<!-- Footer -->
<footer>
<div class="row">
<div class="col-lg-12">
<p>Copyright © Your Website 2014</p>
</div>
</div>
</footer>
</div>
End of browse view.
<br><br>
index.html
<!doctype html>
<html lang="en" ng-app="mango">
<head>
<meta charset="utf-8">
<title>Mango</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="app.config.js"></script>
<script src="login/route-data.js"></script>
<script src="navigation_menu/navigation_menu.config.js"></script>
<script src="browse/browse.controller.js"></script>
<script src="browse/browse.component.js"></script>
<script src="home/home.controller.js"></script>
<script src="profile/profile.controller.js"></script>
<script src="settings/settings.controller.js"></script>
<script src="login/login.controller.js"></script>
<script src="login/app-services/authentication.service.js"></script>
<script src="login/app-services/flash.service.js"></script>
<script src="login/app-services/user.service.local-storage.js"></script>
</head>
<body ng-style="RouteData.get('bodyStyle')" ng-cloak>
<navigationmenu ng-if="location.path() !== '/login'"></navigationmenu>
<ng-view autoscroll></ng-view>
</body>
</html>
I'm not getting any errors in the console.You can ignore the GET error.
What do I need to do to fix my problem?
I'm starting to think th
Thanks in advanced.
I think in your component, you haven't specified controllerAs, when you goto /browse, your browseView.html is getting the controller instance as vm, but when browseView.html is loaded through component,it is not getting the controller instance, as it is not getting instantiated like it is done, in routeProvider.
Try doing,
angular.module("mango").component("browsePage",{
templateUrl:"browse/browse.view.html",
controller:BrowseController,
controllerAs: 'vm'
});
Hope, this solves the issue.
Why I'm not able to console output $scope values ? I'm trying to extract user assigned values from the pages and retrieve in controller. Eventually i would like to pass this to service so multiple controllers can access these data.
HTML
<!DOCTYPE html>
<html lang="en-us" ng-app="myApp">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta charset="UTF-8">
<link rel="stylesheet" href="css/bootstrap.min.css" />
<!-- CDN lib files -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.0/ui-bootstrap-tpls.min.js"></script>
<!-- custom angular script -->
<script src="js/app.js"></script>
</head>
<body>
<div class="container">
<div ng-controller="mainController">
<h1>Hello world!</h1>
<label> Please enter something</label>
<input textarea ng-model="name"></input>
<h4> This is what you entered : {{ name }} </h4>
<h4 style=color:red> now filtering: {{ lower() }}</h4>
</div>
</div>
</body>
</html>
APP.JS
var myApp = angular.module('myApp', []);
myApp.controller('mainController', ['$scope', '$filter', function($scope, $filter) {
$scope.name = 'Test ';
$scope.lower = function(){
return $filter('lowercase')($scope.name);
}
$scope.name = $scope.lower();
console.log($scope.name);
console.log($scope.lower());
}]);
Console will output values upon initializing but not after user make changes.
You need to watch the scope variable:
$scope.$watch('name', function() {
console.log($scope.name);
});
More information: https://stackoverflow.com/a/15113029/5787736
Just a more "functional" version. Everyone is right, you are logging the observable, not what was observed. What you want is for console.log to be called on each change to $scope, not called once (as you have it now).
$scope.$watch("name", console.log);
You're logging only from the constructor. If you want to log each time something changes, consider a watch:
$scope.$watch("name", function() {
console.log($scope.name);
}
Why would you expect a controller to be rerendered when a scope variable changes? You can use scope watchers or input event listeners to listen for changes.
Here's an example with a watcher:
var myApp = angular.module('myApp', []);
myApp.controller('mainController', ['$scope', '$filter', function($scope, $filter) {
$scope.name = 'Test ';
$scope.lower = function(){
return $filter('lowercase')($scope.name);
}
$scope.name = $scope.lower();
console.log($scope.name);
console.log($scope.lower());
$scope.$watch('name', function() {
console.log($scope.name);
console.log($scope.lower());
});
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" class="container">
<div ng-controller="mainController">
<h1>Hello world!</h1>
<label>Please enter something</label>
<input textarea ng-model="name" />
<h4> This is what you entered : {{ name }} </h4>
<h4 style=color:red> now filtering: {{ lower() }}</h4>
</div>
</div>