Using AngularJS, I need to create a directive that loops through an array and displays the relevant information:
Here is my code so far but for some reason it is now working.
Kindly help. What is being displayed is the text below as plain text. Obviously the images are not being loaded as well.
info.title
info.developer
info.price | currency
Here are the files used.
appInfo.html - the template to be used by the directive for each element
<img class="icon" ng-src="{{ info.icon }}">
<h2 class="title">{{ info.title }}</h2>
<p class="developer">{{ info.developer }}</p>
<p class="price">{{ info.price | currency }}</p>
appInfo.js - directive
app.directive('appInfo', function() {
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: 'appInfo.html'
};
});
app.js - module
var app = angular.module('AppMarketApp', []);
controller - repeated elements to test
app.controller('MainController', ['$scope', function($scope) {
$scope.apps =
[
{
icon: 'img/move.jpg',
title: 'MOVE',
developer: 'MOVE, Inc.',
price: 0.99
},
{
icon: 'img/shutterbugg.jpg',
title: 'Shutterbugg',
developer: 'Chico Dusty',
price: 2.99
},
{
icon: 'img/move.jpg',
title: 'MOVE',
developer: 'MOVE, Inc.',
price: 0.99
},
{
icon: 'img/shutterbugg.jpg',
title: 'Shutterbugg',
developer: 'Chico Dusty',
price: 2.99
}
];
}]);
index.html
<!doctype html>
<html>
<head>
<link href="https://s3.amazonaws.com/codecademy-content/projects/bootstrap.min.css" rel="stylesheet" />
<link href="css/main.css" rel="stylesheet" />
<!-- Include the AngularJS library -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
</head>
<body ng-app="AppMarketApp">
<div class="header">
<div class="container">
<h1>App Market</h1>
</div>
</div>
<div class="main" ng-controller="MainController">
<div class="container">
<div class="card" ng-repeat="a in apps">
<app-info info="{{a}}"></app-info>
</div>
</div>
</div>
<!-- Modules -->
<script src="app.js"></script>
<!-- Controllers -->
<script src="MainController.js"></script>
<!-- Directives -->
<script src="appInfo.js"></script>
</body>
</html>
Thanks in advance.
You should do
<div class="card" ng-repeat="a in apps">
<app-info info="a"></app-info>
</div>
Attributes that already expect expressions don't need curly braces.
Related
I am an Angularjs beginner and I am trying to make a data driven accordion. I do not wish to use angular-ui. I followed the tutorial for collapse Bootstrap 3 and I came up with this code, but I am stuck with trying to make it data driven.
HTML:
<div class="my-page__my-list-acc" ng-
if="field.fieldAccordions">
<div id="accordion_{{ $index }}">
<div class="panel my-panel-overrides">
<a class="my-panel-heading" data-toggle="collapse" data-parent="#accordion_{{ $index }}" data-target="#collapse1">
{{field.fieldAccordionHeader }} </a>
<div id="collapse1" class="collapse in">
{{ field.fieldAccordionItem }}
</div>
</div>
</div>
</div>
JS:
fieldAccordions: [{
fieldAccordionHeader: 'text',
fieldAccordionItem: 'text',
}],
},{
fieldAccordions: [{
fieldAccordionHeader: 'text',
fieldAccordionItem: 'text',
}],
},{
I am having trouble linking the different parts of the accordion with the html. The program finds fieldAccordions and creates the panel, but it does not get to the fieldAccordionHeader and fieldAccordionItem sections.
Also, the second issue I am having is that if I create different fieldAccordions items, clicking on every one would simply close/open the original fieldAccordions field.
Some help would be appreciated. I am aware that this is probably straight forward, but it would help me understand it better. A plunkr would be ideal!
From what I understand of your question, you are trying to render accordions from an array of objects each representing an individual accordion. If that's the case, I would place the accordion inside and ng-repeat, like this:
var app = angular.module('accordions', []);
app.controller('MainCtrl', function($scope) {
$scope.fieldAccordions = [{
fieldAccordionHeader: 'Header 1',
fieldAccordionItems: [{
desc: 'Item 1 - A'
}, {
desc: 'Item 1 - B'
}]
}, {
fieldAccordionHeader: 'Header 2',
fieldAccordionItems: [{
desc: 'Item 2'
}]
}, {
fieldAccordionHeader: 'Header 3',
fieldAccordionItems: [{
desc: 'Item 3'
}]
}];
});
<!DOCTYPE html>
<html ng-app="accordions">
<head>
<meta charset="utf-8" />
<title>AngularJS Accordions</title>
<link data-require="bootstrap-css#3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script data-require="jquery#3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body ng-controller="MainCtrl">
<div class="panel-group" id="accordion">
<div class="panel panel-default" ng-repeat="field in fieldAccordions track by $index">
<div class="panel-heading">
<div class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse{{ $index }}">
{{ field.fieldAccordionHeader }} </a>
</div>
</div>
<div id="collapse{{ $index }}" class="panel-collapse collapse in">
<div class="panel-body">
<div ng-repeat="item in field.fieldAccordionItems track by $index">{{ item.desc }}</div>
</div>
</div>
</div>
</div>
</body>
</html>
Note: I've used the standard Bootstrap 3 classes since you didn't provide your custom styles in the question.
I am trying to learn Angular and stuck in the following Image array. Can anyone please explain what is the problem in my code and how to fix this ?
FilterAndImages.html
<!DOCTYPE html>
<html ng-app="store">
<head>
<title>First Angular</title>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body ng-controller="StoreController as store">
<div class="container">
<ul class="list-group" ng-repeat="product in store.products | orderBy = 'price'">
<li class="list-group-item">
<h3> {{product.name}} </h3>
<p> {{product.description}} </p>
<img ng-src="{{product.images[0].full}}" />
<em class="pull-right">
{{product.price | currency}}
<br><button ng-show="product.canPurchase"> Add to Cart </button>
</em>
</li>
</ul>
</div>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="App.js"></script>
</body>
</html>
App.js
(function () {
var app = angular.module('store', []);
var gems = [{
name: 'Ruby',
price: 2.95,
description: 'This is Ruby on Rails :)',
canPurchase: true,
images: [
{
full: 'full.png',
thumb: 'thump.jpg'
},
]
},
{
name: "Black Pearl",
price: 1.5,
description: "Jack Sparrow !!",
canPurchase: false,
images: [
{
full: 'full.png',
thumb: 'thump.jpg'
},
],
}];
app.controller('StoreController', function () {
this.products = gems;
});
})();
I will be really thankful to you guys.
I created a plunker example with your code , that makes the order ,check it here:
https://plnkr.co/edit/uVDl51EyRuwNmj428it1?p=preview
instead of <ul class="list-group" ng-repeat="product in products | orderBy ='price'">
try to use ':' instead of '=' on the orderby:
<ul class="list-group" ng-repeat="product in products | orderBy :'-price'">
One of the problems stands in the way you call the orderBy filter.
<ul class="list-group" ng-repeat="product in store.products | orderBy = 'price'">
should become:
<ul class="list-group" ng-repeat="product in store.products | orderBy: 'price'">
For further options on this feature please see official documentation.
try this
app.controller('StoreController', function ($scope) {
$scope.products = gems;
});
I have small problem with using a dotdotdot JQuery plugin with AngularJS. There is my HTML code:
<div class="col-md-2 col-sm-6 col-xs-12" ng-repeat="video in videos track by $index">
<a href="{{thumbsPath + video.thumbnail}}" class="thumb">
<div class="thumbnail">
<img ng-src="{{thumbsPath + video.thumbnail}}" alt="">
<div class="caption">
<p class="video-title" dotdotdot>{{video.name}}</p>
</div>
</div>
</a>
</div>
And this is my dotdotdot directive:
videoControllers.directive('dotdotdot', function() {
return function(scope, element, attrs) {
$(element).dotdotdot({'watch':true});
};
});
I want to make my {{video.name}} shorter, but when I add dotdotdot - it doesn't display the content of {{video.name}}, but a text: "{{video.name}}". I've read almost every post about this topic, but nothing helped me.
You should call scope.$apply in your directive. This will cause your controller to update the model. See my example below
EDIT
Needed to add require: 'ngModel' so it would update everytime
EDIT 2
Turns out you should use the compile property of the directive and not link when using the directive within an ng-repeat
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.videos = [{
name: 'Pool',
thumbnail: 'http://img.youtube.com/vi/dXo0LextZTU/0.jpg'
}, {
name: 'Pool2',
thumbnail: 'http://www.shender.com/db_picture/pro19/201105251714246730.jpg'
}];
});
app.directive('dotdotdot', function() {
return {
restrict: 'A',
compile: function(scope, element, attrs) {
return {
pre: function(scope, element, attrs) {
$(element).dotdotdot({
'watch': true
});
}
};
}
};
});
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery.dotdotdot/1.7.4/jquery.dotdotdot.min.js"></script>
<link rel="stylesheet" href="style.css" />
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body ng-controller="myController">
<div class="col-md-2 col-sm-6 col-xs-12" ng-repeat="video in videos track by $index">
<a href="{{thumbsPath + video.thumbnail}}" class="thumb">
<div class="thumbnail">
<img ng-src="{{thumbsPath + video.thumbnail}}" alt="">
<div class="caption">
<p class="video-title" dotdotdot>{{video.name}}</p>
</div>
</div>
</a>
</div>
</body>
</html>
So I'm learning directives and controllers in JSAngular. Currently I'm just trying to get the appetizers to loop through on the menu but can't seem to get the output to respond. What am I missing here? Thanks in advance.
MainController.js:
app.controller('MainController', ['$scope', function($scope) {
$scope.today = new Date();
$scope.appetizers = [
{
name: 'Caprese',
description: 'Mozzarella, tomatoes, basil, balsmaic glaze.',
price: 4.95
},
{
name: 'Bruschetta',
description: 'Grilled bread garlic, tomatoes, olive oil.',
price: 4.95
},
{
name: 'Mozzarella Sticks',
description: 'Served with marinara sauce.',
price: 3.95
}
];
$scope.mains = [
{
name: 'Roast Beef Au Jus',
description: 'Delicious Amazing Sauce',
price: 15.99
},
{
name: 'Prime Rib',
description: 'Just like Jacoby/s',
price: 18.95
},
{
name: 'BBQ Ribs',
description: 'Better than Krupa/s',
price: 15.99
}
]
$scope.extras = [
{
name: 'Cole slaw',
},
{
name: 'Creamed Spinach',
},
{
name: 'Boston Baked Beans',
}
]
}]);
<!doctype html>
<html>
<head>
<link href="https://s3.amazonaws.com/codecademy-content/projects/bootstrap.min.css" rel="stylesheet" />
<link href='https://fonts.googleapis.com/css?family=Playfair+Display:400,400italic,700italic|Oswald' rel='stylesheet' type='text/css'>
<link href="css/main.css" rel="stylesheet" />
<script src="js/vendor/angular.min.js"></script>
</head>
<body ng-app='PizzaPlanetApp'>
<div class="header">
<h1><span>Pizza</span><span>Planet</span></h1>
</div>
<div class="main" ng-controller="MainController">
<div class="container">
<h1>Specials for {{ today | date }}</h1>
<h2>Appetizers</h2>
<div class="appetizers row" ng-repeat="appetizer in appetizers">
<div class="item col-md-9">
<h3 class="name"> {{ appetizer.name }} </h3>
<p class="description"> {{ appetizer.description }} </p>
</div>
<div class="price col-md-3">
<p class="price"> {{ appetizers.price | currency }} </p>
</div>
</div>
</div>
</div>
<div class="footer">
<pizza-footer></pizza-footer>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/MainController.js"></script>
</body>
</html>
you need to refer to your PizzaPlanetApp application module first. Add the following line of code before creating the controller.
var app = angular.module("PizzaPlanetApp", []);
This refers to the app you want to create the controller of and contains the list of modules your app depends on.
In your case the list is empty.
jsfiddle
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>