Make a card dynamic with Angular JS - javascript

I have this data in my index.js file:
angular.module('app', [])
.controller('MainCtrl', function($scope) {
$scope.demos = [ {
paragrafo: 'richiesta',
title:'demo1',
paragrafo2:'dskjdfdjfdfjkdf',
link: 'https://www.google.it',
},
{
paragrafo: 'richiesta',
title:'demo2',
paragrafo2:'dfhfhfjgfkjghfjkgf',
link: 'https://www.youtube.it',
},
{
paragrafo: 'richiesta',
title:'demo3',
paragrafo2:'sjdsdjddfjdf',
link: 'https://www.sportmediaset.it',
},
{
paragrafo: 'richiesta',
title:'demo4',
paragrafo2:'sdjkdhdkjfhdjfh',
link: 'https://www.elbocon.pe',
},
];
})
.component('card', {
templateUrl: 'card.html'
})
in my card.html component i used ng-repeat, i tried iterating it with ng -repeat:
<div ng-repeat="demo in demos">
<div class="card" style="width: 18rem">
<div class="card-body">
<p>{{demo.paragrafo}}</p>
<h5 class="card-title">{{demo.title}}</h5>
<h6 class="card-subtitle mb-2 text-muted"></h6>
<p class="card-text">{{demo.paragrafo2}}</p>
<a class="card-link">{{demo.link}}</a>
</div>
</div>
</div>
and in index.html, I put the component in the html index as well:
<body ng-app="app" ng-cloak>
<div ng-controller="MainCtrl">
<div class="container">
<div class="row">
<div class="col">
<card></card>
</div>
</div>
</div>
</div>
</body>
But it doesn't work, I would like 4 cards with different data to appear, can someone help me?

You need to bind your data to the component. Additionally, accessing that data inside the component requires a reference to $ctrl.
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.demos = [{
paragrafo: 'richiesta',
title: 'demo1',
paragrafo2: 'dskjdfdjfdfjkdf',
link: 'https://www.google.it',
},
{
paragrafo: 'richiesta',
title: 'demo2',
paragrafo2: 'dfhfhfjgfkjghfjkgf',
link: 'https://www.youtube.it',
},
{
paragrafo: 'richiesta',
title: 'demo3',
paragrafo2: 'sjdsdjddfjdf',
link: 'https://www.sportmediaset.it',
},
{
paragrafo: 'richiesta',
title: 'demo4',
paragrafo2: 'sdjkdhdkjfhdjfh',
link: 'https://www.elbocon.pe',
},
];
}])
.component('card', {
bindings: {
demo: '<'
},
template: '<div class="card" style="width: 18rem"><div class="card-body"><p>{{$ctrl.demo.paragrafo}}</p><h5 class="card-title">{{$ctrl.demo.title}}</h5><h6 class="card-subtitle mb-2 text-muted"></h6><p class="card-text">{{$ctrl.demo.paragrafo2}}</p><a class="card-link">{{$ctrl.demo.link}}</a></div></div>'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<card demo="data" ng-repeat="data in demos">
</card>
</div>

Related

Pass method child parent angular js

I have this function:
$scope.link = function (){
return [{
value: 'https://www.google.it',
text: 'go to details'
}
]
}
i want pass this function in parent controller to the child, i tried to do this:
.directive('card', function(){
var TPL = `<div class="card" style="width: 18rem">
<div class="card-body">
<p>{{c.paragrafo}}</p>
<h4 class="card-title">{{c.title}}</h4>
<h6 class="card-subtitle mb-2 text-muted">{{c.paragrafo2}}</h6>
<p class="card-text"></p>
<a class="card-link">{{c.link()}}</a>
</div>
</div>`
var directive = {
restrict: 'E',
template: TPL,
scope: {
paragrafo: '#',
title: '#',
paragrafo2: '#',
link: '&'
},
controller: ctrlFn,
controllerAs: 'c',
bindToController: true
};
return directive;
function ctrlFn(){
}
})
and in index.html:
<body ng-app="app" ng-cloak>
<div ng-controller="MainCtrl">
<div class="container">
<div class="row">
<div class="col" ng-repeat="demo in demos">
<card title="{{demo.title}}"
paragrafo="{{demo.paragrafo}}"
paragrafo2="{{demo.paragrafo2}}"
link="link()"
></card>
</div>
</div>
</div>
</div>
</body>
But the body of the function returns to me, how can i fix this?
I want to see the link text "go to details" and when I click on it it takes me to the google page

angularjs dynamic form with different field types

In my current project I need to create a dynamic form using AngularJS.
I am already building the form following the ideas from this video here.
I can't seem to get the submitted data back to my controller. I only receive undefined in the console log.
Currently the data for the form is resolved in ui-router before the state is loaded, then copied to the controller's data property.
Unlike the video our form requires that questions are broken down into sections.
There is a ng-repeat over each section in the data, then a nested ng-repeat goes over each question. The type is determined and the proper directive for the question/field type is loaded to via ng-switch.
I whipped up a small Plunker to help illustrate as well.
https://plnkr.co/edit/6dCnHiFDEYu03kfX07mr
Finally there are some types I am unsure how to handle, such as address or phone number which will be considered one question type but have multiple fields.
(e.g. [Street] [City] [State] [Zip])
Controller
namespace portal.dashboard.form{
class formCtrl{
formData: portal.domain.interfaces.IHousingRequest;
static $inject = ["formResolve"];
constructor(private formResolve:any) {
this.formData= this.loadHousingRequestFormData;
}
public submit(isValid,data) {
if (isValid) {
console.log(data);
}
}
}
angular
.module("portal")
.controller("formCtrl", formCtrl);
}
Directive for input type text
namespace portal.directives {
function inputText(): ng.IDirective {
return {
scope: {
model: '='
},
controller: function ($scope: ng.IScope) {
var directiveScope = $scope.$parent.$parent;
},
controllerAs:'vm',
templateUrl: 'form/templates/input-text.html'
}
}
angular
.module("portal")
.directive("inputText", inputText);
}
input type html
<input type="text"
ng-model="model"/>
HTML
<form name="form" ng-submit="vm.submit(form.$valid, data)" novalidate>
<!-- Section repeat -->
<div ng-repeat="section in vm.formData.sections track by $index">
<section>
<div>
<h4>
{{section.name}}<br />
<small ng-show="section.description">{{section.description}}</small>
</h4>
</div>
<section>
<!-- Section questions repeat -->
<div ng-form="formFields" ng-repeat="field in section.fields track by $index">
<label>
{{field.name}}<br />
<small>{{field.description}}</small>
</label>
<!-- input field switch -->
<div ng-switch="field.type">
<div ng-switch-when="Text">
<input-text model="data.answer[$index]">
</input-text>
</div>
<div ng-switch-when="Email">
<input-email model="data.answer[$index]">
</input-email>
</div>
</div>
</div>
</section>
</section>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
You have to init $scope.data = {}; before using it, also use correct sectionIndex and fieldIndex to populate the answer:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.data = {};
$scope.sections = [{
name: 'User Info',
description: 'I\'m a description.',
fields: [{
label: "Name",
type: "text"
}, {
label: "Email",
type: "email"
}]
}, {
name: 'Pet Info',
description: '',
fields: [{
label: "Pet Breed",
type: "text"
}]
}];
$scope.submit = function(isValid, data) {
console.log('submit fired');
if (isValid) {
console.log(data);
}
}
});
app.directive('inputText', function() {
return {
scope: {
model: '='
},
controller: function($scope) {
var directiveScope = $scope.$parent.$parent;
},
controllerAs: 'vm',
template: '<input type="text" ng-model="model"/>'
}
});
app.directive('inputEmail', function() {
return {
scope: {
model: '='
},
controller: function($scope) {
var directiveScope = $scope.$parent.$parent;
},
controllerAs: 'vm',
template: '<input type="email" ng-model="model"/>'
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl">
<form name="form" ng-submit="submit(form.$valid, data)" novalidate>
<!-- Section repeat -->
<div ng-repeat="(sectionIndex, section) in sections track by $index">
<section>
<div>
<h4>
{{section.name}}<br />
<small ng-show="section.description">{{section.description}}</small>
</h4>
</div>
<section>
<!-- Section questions repeat -->
<div ng-form="formFields" ng-repeat="(fieldIndex, field) in section.fields track by $index">
<label>
{{field.label}}<br />
</label>
<!-- input field switch -->
<div ng-switch="field.type">
<div ng-switch-when="text">
<input-text model="data.answer[sectionIndex][fieldIndex]">
</input-text>
</div>
<div ng-switch-when="email">
<input-email model="data.answer[sectionIndex][fieldIndex]">
</input-email>
</div>
</div>
</div>
</section>
</section>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</body>
Also I'm not sure why do you need this var directiveScope = $scope.$parent.$parent; in your directive's controller, do you really need this?

call function in controller from template.html

I am new to AngularJS, Somehow while going through many sites now I am able to create a directive for showing some data.Now I need to send some data to controller by clicking the button. I need to know the proper way of doing this
I have created the plunk
html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="jquery#*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="movieDesc">
<div ng-repeat="m in movies" movies="m"></div>
</body>
</html>
Directive and Controller
// Code goes here
angular.module('app', []);
angular.module('app').controller('movieDesc', function($scope) {
$scope.movies = [{
name: 'abc',
desc: 'this is desc text for the movie',
pic: 'http://png.clipart.me/graphics/thumbs/134/abstract-geometric-background-triangle-and-square-black_134053397.jpg'
}, {
name: 'def',
desc: 'this is desc text for the movie def',
pic: 'http://png.clipart.me/graphics/thumbs/201/abstract-modern-banner-background-of-geometric-shapes-abstract-geometric-form_201768245.jpg'
}, {
name: 'ghi',
desc: 'this is desc text for the movie ghi',
pic: 'http://www.cianellistudios.com/images/abstract-art/abstract-art-infinite-150.jpg'
}]
$scope.saveData = function(data) {
console.log(data);
}
});
angular.module('app').directive('movies', function() {
return {
templateUrl: "movieCard.html",
restrict: "EA",
scope: {
movies: '='
},
link: function(scope, element, attrs) {
element.addClass('moviesBox');
var clickedFn = function() {
alert("clicked");
};
console.log("console", element[0].querySelector('.btnSelect'));
var $this = element[0].querySelector('.btnSelect');
$($this).click(function() {
alert(scope.movies.desc)
})
}
}
})
My Template
<div>
<div>
<b>Name:</b> {{movies.name}}
</div>
<div>
<b>Description:</b> {{movies.desc}}
</div>
<div>
<img src="{{movies.pic}}" />
</div>
<div>
<input type="text" ng-model="movies.someText">
</div>
<div>
<input class="btnSelect" type="button" value="Desc" ng-click="clickedFn()">
</div>
<div>
<input class="btnSelect" type="button" value="Save Data" ng-click="saveData({{movies}})">
</div>
</div>
I need to send the data to the controller's $scope.saveData() function, the data will be entered through the textbox. I have given it as ng-model="movies.someText" which I suppose is the wrong way.
So please help me.
Use the & scope binding.
scope: {
movies: '=',
save: '&'
},
and in the directive template
<input type="button" ng-click="save({movie: movies})" ...>
You then bind the controller method via
<div ng-repeat="m in movies" movies="m" save="saveData(movie)"></div>
Note the argument name passed to the controller function matches the object key in the directive template.
https://plnkr.co/edit/9bF5FDea6wLn7vcGvEzU?p=preview
While you're there, use ng-src instead of src to avoid a 404 request for a non-existent image
<img ng-src="{{movies.pic}}" />
html
<body ng-controller="movieDesc">
<div ng-repeat="m in movies" movies="m">
<movies-dir
movies="m" save-data="saveData(movie)"></movies-dir>
</div>
</body>
Directive and Controller
angular.module('app', []);
angular.module('app')
.controller('movieDesc', function($scope) {
$scope.movies = [/* movie object array data */]
$scope.saveData = function(movie) {
console.log(movie);
}
});
angular.module('app').directive('moviesDir', function() {
return {
templateUrl: "movieCard.html",
restrict: "EA",
scope: {
movies: '=',
saveData: '&'
},
link: function(scope, element, attrs) {
}
}
})
Template
<div>
<input class="btnSelect" type="button" value="Save Data" ng-click="saveData({ 'movie': movies })">
</div>
You need to pass saveData as a parameter like this:
<body ng-controller="movieDesc">
<div ng-repeat="m in movies" movies="m" save-data="saveData()"></div>
And you get back in your directive like this:
return {
templateUrl: "movieCard.html",
restrict: "EA",
scope: {
movies: '=',
saveData:'='
},
link: ...
And then in your template.html, you don't need to use '{{}}' :
<input class="btnSelect" type="button" value="Save Data" ng-click="saveData(movies)">

Being thrown an error that my angular js function isn't defined

Error: https://docs.angularjs.org/error/ng/areq?p0=ProjectsController&p1=not%20a%20function,%20got%20undefined
I mimicked a ng-repeat that I did earlier, the only difference being I didn't split up the directive, controller, and initializing the app into 3 different javascript files. Also, are you allowed to add multiple ng-apps to the <body> tag? If no, then that may be my problem.
HTML:
<div class="projects">
<h2>Projects</h2>
<div class="row">
<div class="col-lg-12">
<div class="row" ng-controller="ProjectsController">
<div class="project-boxes" ng-repeat="project in projects">
<project-info info="project"></project-info>
</div>
</div>
</div>
</div>
</div>
app.js:
var projectApp = angular.module("projectApp", ['ngAnimate'])
.controller('ProjectsController', ['$scope', function($scope) {
$scope.projects = [
{
link: '#',
img: 'img/box.jpeg',
description: 'Project 1'
}];
}])
.directive('projectsInfo', function() {
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: 'components/projects/projects-template/projectsInfo.html'
};
});

AngularJS Routing is not Binding the Controller

I am trying to create a simple application in AngularJS and for some reason I cannot figure out why my routing is not binding the controller to the template. When I click on my links they take me to the correct path and the code is executed and the template is displayed in the data-ng-view directive. What does not happen is the template is not bound to the networkController? I been trying to figure it out for a while now and I am stuck any help would be appreciated.
Thank You!
Here is all my code;
app.js
'use strict';
var habeoApp = angular.module('habeo', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider.when(
'/network/:id',
{
templateUrl: '/app/templates/networkDetails.html',
controller: NetworkCntl
}
);
});
function NetworkCntl($scope, $routeParams) {
$scope.name = "networkController";
$scope.params = $routeParams;
}
networkListController.js
'use strict';
habeoApp.controller('networkListController',
function networkListController($scope) {
$scope.networks = [
{ name: 'Data Network', activeClass: "", url: "#/network/1" },
{ name: 'Voip', activeClass: "", url: "#/network/2" },
{ name: 'Servers', activeClass: "", url: "#/network/3" },
{ name: 'Clients', activeClass: "", url: "#/network/4" }
];
$scope.selectNetwork = function(network) {
clearSelectedNetwork();
network.activeClass = "active";
console.log(network.name);
};
var clearSelectedNetwork = function() {
$.each($scope.networks, function(index, value) {
value.activeClass = "";
});
};
}
);
networkController.js
'use strict';
habeoApp.controller('networkController', ['$scope', '$routeParams'],
function networkController($scope, $routeParams) {
var par = $routeParams;
$scope.network = {
availableIps: 200,
assignedIps: 55,
totalIps: 255,
ips: [
{ ipAddress: "10.39.2.7", dns: "sw-lnp-vhdev", requested: "2013/12/04", Owner: "Lukasz Maslanka" },
{ ipAddress: "10.39.3.17", dns: "sw-lnp-vh7", requested: "2013/12/02", Owner: "Tom Bedard" },
{ ipAddress: "10.39.3.19", dns: "sw-lnp-vh10", requested: "2013/12/01", Owner: "Blake Kennedy" },
{ ipAddress: "10.39.4.114", dns: "sw-lnp-vh12", requested: "2013/11/27", Owner: "Terry McKerral" },
{ ipAddress: "10.39.4.171", dns: "sw-lnp-vh21", requested: "2013/11/14", Owner: "Andrew Henry" }
]
};
}
);
networkDetails.html
<div class="row">
<div class="col-md-4 info-box-blue">
<h5 class="">Available IP's</h5>
</div>
<div class="col-md-4 info-box-lightblue">
<h5 class="">Assigned IP's</h5>
</div>
<div class="col-md-4 info-box-green">
<h5 class="">Total IP's</h5>
</div>
</div>
<div class="row">
<div class="col-md-4 info-box-blue info-box-footer-padding">
<h1 class="text-center info-box">{{network.availableIps}}</h1>
</div>
<div class="col-md-4 info-box-lightblue info-box-footer-padding">
<h1 class="text-center info-box">{{network.assignedIps}}</h1>
</div>
<div class="col-md-4 info-box-green info-box-footer-padding">
<h1 class="text-center info-box">{{network.totalIps}}</h1>
</div>
</div>
<div class="row">
<button type="button" class="btn btn-primary wide">Request IP</button>
</div>
<div class="row">
<input type="text" class="form-control wide" placeholder="Search...">
</div>
<div class="row top-margin">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>IP Address</th>
<th>DNS</th>
<th>Requested</th>
<th>Owner</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="ip in network.ips">
<td>{{ip.ipAddress}}</td>
<td>{{ip.dns}}</td>
<td>{{ip.requested}}</td>
<td>{{ip.owner}}</td>
</tr>
</tbody>
</table>
</div>
index.cshtml
<div class="row" data-ng-controller="networkListController">
<div class="col-md-3">
<div class="add-vlan-button-container">
<button type="button" class="btn btn-default add-vlan-button" data-toggle="modal" data-target="#add-new-network-form">Add Network</button>
</div>
<div class="">
<ul class="nav nav-pills nav-stacked">
<li data-ng-class="network.activeClass" data-ng-repeat="network in networks" data-ng-click="selectNetwork(network)">{{network.name}}</li>
</ul>
</div>
</div>
<div class="col-md-9" data-ng-view>
</div>
</div>
There is bug in your networkController definition: the array should contain the function (which is the controller) as the last argument, not as a separate third argument.
habeoApp.controller('networkController', ['$scope', '$routeParams',
function networkController($scope, $routeParams) {
var par = $routeParams;
$scope.network = {
availableIps: 200,
assignedIps: 55,
totalIps: 255,
ips: [
{ ipAddress: "10.39.2.7", dns: "sw-lnp-vhdev", requested: "2013/12/04", Owner: "Lukasz Maslanka" },
{ ipAddress: "10.39.3.17", dns: "sw-lnp-vh7", requested: "2013/12/02", Owner: "Tom Bedard" },
{ ipAddress: "10.39.3.19", dns: "sw-lnp-vh10", requested: "2013/12/01", Owner: "Blake Kennedy" },
{ ipAddress: "10.39.4.114", dns: "sw-lnp-vh12", requested: "2013/11/27", Owner: "Terry McKerral" },
{ ipAddress: "10.39.4.171", dns: "sw-lnp-vh21", requested: "2013/11/14", Owner: "Andrew Henry" }
]
};
}]
);
I am assuming that you wanted to use the networkController as the controller for networkDetail.html and NetworkCntl is merely a dummy controller you introduced during your debugging.
Working demo: http://plnkr.co/edit/uA59OUGZr1FiiNy5tnTT?p=preview

Categories

Resources