How do I dynamically add an AngularJS directive to an element conditionally? - javascript

So I can't really get this to work, I've got the following code
HTML:
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<script>document.write("<base href=\"" + document.location + "\" />");</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
{{vt.t}}
<div my-directive="{{vt.t}}"></div>
{{vt.f}}
<div my-directive="{{vt.f}}"></div>
<hr />
{{vt.t}}
<div ng-class="{'my-directive': vt.t}"></div>
{{vt.f}}
<div ng-class="{'my-directive': vt.f}"></div>
<hr />
<div class="my-directive"></div>
<div class="nodirectiveclass"></div>
</body>
</html>
JavaScript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.vt = { t: true, f: false };
});
app.directive('myDirective', function($compile) {
return {
restrict: 'AC',
template: '<div>Directive on</div>',
replace: true
};
});
Plunker: http://plnkr.co/edit/7cJKhIuNqnsk1CkczjoE?p=preview
As you see the classes doesn't trigger the directive when added dynamically but works fine in my last "static" example. I also tried setting the directive attribute to true or false but that didn't seem to help.

I think you should use model variable in your directive. Then you can access what ever the value you want easily.
Refer this Answer:
AngularJS - Create a directive that uses ng-model

Related

ng-click on ng-repeat in a directive

I am new to AngualrJS and I am having trouble getting a ng-click working inside a ng-repeat that sits inside a directive.
I use ng-repeat to display a list of PDFs and currently just trying to be able to click them to pop up an alert window. But I don't seem to be able to get any ng-click working within the directive.
The Angular code:
var app = angular.module("aria", []);
app.directive("rdnglist", function(){
return {
restrict: 'E',
templateUrl: "rdnglist.html",
controller: function(){
this.pdfs = pdflist;
this.test = function() {
$window.alert("hi");
};
},
controllerAs: "plist",
};
});`
The HTML:
<div class="fullsect">
<div class="pdflist" ng-repeat="pdf in plist.pdfs">
<h3>{{pdf.name}}</h3>
<img ng-src="{{pdf.image}}" ng-click="test()"/>
<p>Class: {{pdf.class}}</p>
<div id="commentNo">{{pdf.comments}}</div>
</div>
<div class="pdflist">
<h3>New File</h3>
<a ng-click="test()">Open</a>
<img src="/pictures/addnew.png"/>
</div>
I assume it has something to do with the scope of the controller but I'm unsure. As I'm new, I learned to use ControllerAs over $scope, is this the issue?
Here is a working plunker based on your code.
I changed the directive to inject $window ... see ['$window, function($window) to make the alert work. I also initialize with dummy data:
The app:
var app = angular.module('plunker', []);
app.directive("rdnglist", ['$window', function($window){
return {
restrict: 'E',
templateUrl: "rdnglist.html",
controller: function(){
this.pdfs = [{'name':'abc'}];
this.test = function() {
$window.alert("hi");
};
},
controllerAs: "plist",
};
}]);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
And the rdnglist.htm... as you are using ControllerAs, you need plist.test(). To reduce my work I hardcoded an AngularJS image:
<div class="fullsect">
<div class="pdflist" ng-repeat="pdf in plist.pdfs">
<h3>{{pdf.name}}</h3>
<a ng-click="plist.test()"><img ng-src="http://code-maven.com/img/angularjs.png" /></a>
<p>Class: {{pdf.class}}</p>
<div id="commentNo">{{pdf.comments}}</div>
</div>
<div class="pdflist">
<h3>New File</h3>
<a ng-click="test()">Open</a>
<img src="/pictures/addnew.png"/>
</div>
</div>
index.html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<rdnglist></rdnglist>
</body>
</html>
let us know if that helps.

console.log for $scope in angular js

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>

AngularJS Directives ng-click

I must make a website. When you press an IMG it adds the template from the directive to another div.
In detail, I have 3 imgs on my website. Hamburger, Cola and Crips. When you press one of them it adds it to the Order List.
HTML code:
<!DOCTYPE HTML>
<html ng-app="myApp">
<head>
<script src="scripts/angular.min.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="Stylesheet" type="text/css" href="styles/style.css">
<title>Food Center</title>
<script src="scripts/skrypt.js"></script>
</head>
<body>
<h1 class="ladne"><center>Food Center</center></h1>
<div class="d1" ng-controller="myCtrl" myDir1>
<img src="styles/img/cola.gif"></img>
<img src="styles/img/fryt.gif"></img>
<img src="styles/img/ham.gif"></img>
<br>
<div class="zam" >
Date of order: {{data | date:'yyyy-MM-dd'}}
<br>
Your Order:
</div>
</div>
</body>
</html>
Controller code:
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope) {
$scope.data = new Date();
$scope.hamburger ={
name: 'Hambureger',
}
$scope.frytki = {
name: 'Frytki',
}
$scope.cola = {
name: 'Coca-Cola',
}
});
myApp.directive('dir1', function () {
return {
restrict: 'A',
template: '<br>{{hamburger.nazwa}}'
};
});
I really don't understand these directives. Would be nice if you can help me.

Can one trigger ng-class after ng-click?

I have the following element:
{{ project.label }}
The idea of the ng-class is this: if the photo belongs to the project, the function belongsPhotoToProject returns true, so the selected-project class is set. Now, on click, after the function removeFromProject(project, $index, currentPhoto) is triggered, belongsPhotoToProject does not evaluate to true anymore, so I expect it to remove the class, however, this doesn't happen.
So my questions are: after the initial page load, on which page events does ng-click get triggered? If ng-click gets triggered only on page load, can I manually trigger it again on ng-click?
That should work as you described it. Here's a plnkr showing it:
http://plnkr.co/edit/V4R0EUwKK5TeH5wn7Y5N?p=preview
Are you getting any errors in your browser?
javascript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.project = {
hasPhotos: true,
label: "My Test Project"
};
$scope.removeFromProject = function(project, $index, currentPhoto) {
$scope.project.hasPhotos = false;
};
$scope.addToProject = function($index, currentPhoto) {
$scope.project.hasPhotos = true;
};
$scope.belongsPhotoToProject = function(project, $index, currentPhoto) {
return $scope.project.hasPhotos;
};
});
html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
{{ project.label }}
</body>
</html>
css:
.selected-project {
background-color: #ccf;
}

How to get $attrs data of children DOM in a controller?

Let say I have a controller and many children DOMs with their own data attributes.
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.16/angular.js" data-semver="1.2.16"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p data-test-val='Brian'>Hello {{name}}!</p>
</body>
</html>
I want to access to the data-test-val like this
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $attrs) {
$scope.name = $attrs.testVal;
});
However, it does not seem to work as name is empty.
http://plnkr.co/edit/V1Leit8U7r2k4CZDGaGa?p=preview
How to access any data attribute in children DOM of the same scope?
Thanks.
you're messing up controllers with directives in terms of attribute acquiration.
directive:
.directive('directiveName', function() {
return {
link: function($scope, $elem, $attrs) {
// get $attrs stuff here
}
}
});
Create a separate directive named as "dataTestVal", then you can get an access to attributes of the tag.
Example Code:
<html ng-app="ExampleApp">
<head>
//required libraries, scripts
</head>
<body ng-controller="ExCtrl">
<div data-testval data="person"></div>
</body>
<script>
angular.module('ExampleApp',[]);
angular.module('ExampleApp")
.controller("ExCtrl",function($scope){
$scope.person = {
name:"afd",
age : 30
};
});
angular.module('ExampleApp")
.directive("dataTextval",function(){
return{
restrict:'A',
scope:{
data : '='
},
link:function(scope,element,attrs){
//you can gain access to element and its attributes
//scope.data is nothing but person details, which is declared in controller
}
}
});
</script>
</html>
Try this :
var ele = document.getElementsByTagName('p');
$scope.name = ele.getAttribuete('data-test-val');

Categories

Resources