Add html content after directive template - angularjs

Having this HTML :
<div messages>
Some content...
</div>
This directive :
myAppDirectives.directive("messages", function () {
return {
restrict: 'A',
templateUrl: '/directives/messages/messages.html',
link: function (scope, elem, attrs) {
//...
}
};
});
And messages.html :
<p>message1</p>
<p>message2</p>
The content of my html gets replaced by the directive template but i'd like it to just be appended.
Html becomes this :
<div messages>
<p>message1</p>
<p>message2</p>
</div>
But I'd like this :
<div messages>
<p>message1</p>
<p>message2</p>
Some content...
</div>
Is this possible without using ng-include?

This looks like a perfect situation to use ngTransclude.
Try:
myAppDirectives.directive("messages", function () {
return {
restrict: 'A',
transclude: true,
templateUrl: '/directives/messages/messages.html',
link: function (scope, elem, attrs) {
//...
}
};
});
messages.html:
<p>message1</p>
<p>message2</p>
<ng-transclude></ng-transclude>

If you really want this behaviour, use transclusion:
myAppDirectives.directive("messages", function () {
return {
restrict: 'A',
transclude: true,
templateUrl: '/directives/messages/messages.html',
link: function (scope, elem, attrs) {
//...
}
};
});
And the template becomes:
<p>message1</p>
<p>message2</p>
<span ng-transclude></span>
The original content of the <div messages> element will be wrapped in the <span ng-transclude>, but this should not harm.

Related

Passing HTML into TemplateURL using directive

I am trying to get the HTML inside the directive tag into the template file and render it on the screen
HTML
<insert-test-tab><b>Put this text in the template test.html</b></insert-test-tab>
script.js
directive('insertTestTab', function() {
return {
replace: true,
link: function (scope, element, attr) {
},
templateUrl: function (elem, attr) {
return 'test.html'
},
}
}
test.html
<div>
<p>bla bla bla</p>
<p>[[I want to get that HTML inside <insert-test-tab> here]]</p>
</div>
Desired output
<div>
<p>bla bla bla</p>
<b>Put this text in the template test.html</b>
</div>
Thank you.
Directive definition:
directive('insertTestTab', function() {
return {
replace: true,
transclude: true,
link: function (scope, element, attr) {
}, templateUrl: function (elem, attr) {
return 'test.html'
},
}
}
test.html:
<div>
<p>bla bla bla</p>
<p><ng-transclude></ng-transclude></p>
</div>
You can achieve this using directive tranclude feature.
So your directive definition should be as follows :
directive('insertTestTab', function() { return {
replace: true,
transclude: true,
link: function (scope, element, attr) {
}, templateUrl: function (elem, attr) {
return 'test.html'
},
}
}
And test.html should::
<div>
<p>bla bla bla</p>
<p><ng-transclude></ng-transclude></p>
</div>
Hope this will work for you(Ref:: https://codepen.io/pankajbadukale/pen/aVbGaM)

Angular toggle directive from parent controller

How i can show/hide directive when some elements in parent controller has event?
app.directive('rest', function(){
return {
restrict: 'E',
scope: false,
replace: true,
link: function(scope, elem, attr) {
},
templateUrl: '<div ng-show="showDirective"></div>',
}
});
<div ng-controller="AppCtrl">
<rest></rest>
<div ng-click="showDirective = false"><div> <!-- hide directive -->
<div ng-click="showDirective = true"><div> <!-- show directive -->
</div>
Here, your mistake was "templateUrl" instead of "template". When you provide html inline, user "template", when you provide html in a separate html file, use "templateUrl" and provide a url to the template html:
http://plnkr.co/edit/xzqOvcjKYfWxazWfHWyS?p=preview
.directive('rest', function(){
return {
restrict: 'E',
scope: false,
replace: true,
link: function(scope, elem, attr) {
},
template: '<div ng-if = "showDirective" >Test</div>',
}

Get image src within directive

I have a directive with an img tag inside it.
angular.module('example')
.directive('customDirective', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {}, //isolate scope
templateUrl: 'directives/customDirective.html'
link: function(scope, element, attrs) {
// returns undefined
console.log(element.find('img').src);
}
};
});
the directive template:
<div class="customDirective">
<img src="image.jpg" />
</div>
I'm trying to get a hold of the src attribute on the image tag.
var src = element.find('img').attr('src');
This is assuming there is only a single img tag.
It would probably be easier to set the source in your directive.
Directive
angular.module('example')
.directive('customDirective', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'directives/customDirective.html'
link: function(scope, element, attrs) {
scope.imgSrc = 'image.jpg';
}
};
});
Template
<div class="customDirective">
<img ng-src="{{imgSrc}}" />
</div>
Then your code drives the template instead of you needing to read data out of the template.

AngularJS: how do I code an element directive with optional attribute parameters?

I'm doing my first steps in AngularJS directives. Just set up this one as an exercise to output a product name:
.directive('productname', function (Prefs) {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: '/partials/productname.html',
link: function (scope, element, attrs) {
scope.brand = Prefs.owner;
}
}
})
productname.html
<span class="productname"><span class="brand">{{brand}}</span> <span class="product" ng-transclude>{{productname}}</span></span>
and so the usage is plainly: <productname>{{product.name}}</productname>
Now, could someone tell me how I should go about making this directive configurable by adding a flag to output the productname linked?
The usage would be: <productname linked>{{product.name}}</productname> and the output/template would be:
<span class="productname"> <span class="brand">{{brand}}</span> <span class="product" ng-transclude>{{productname}}</span></span>
Seems complicated and I cannot quite figure out where the logic should be injected...
First of all, you should use the scope property of the directive declaration. Also, you do not need transclude in this case. Like so:
.directive('productname', function (Prefs) {
return {
restrict: 'E',
scope: {
product: "=",
linked: "="
},
replace: true,
templateUrl: '/partials/productname.html',
link: function (scope, element, attrs) {
// scope.product and scope.linked are automatically set
scope.brand = Prefs.owner;
}
}
})
And the template:
<span class="productname" ng-switch="linked">
<a href="/edit/{{id}}" ng-switch-when="true">
<span class="brand">{{brand}}</span>
<span class="product">{{product.name}}</span>
</a>
<span ng-switch-default>
<span class="brand">{{brand}}</span>
<span class="product">{{product.name}}</span>
</span>
</span>
Call the template like so:
<productname product="product"></productname>
or:
<productname product="product" linked="'true'"></productname>
Update
If you want to use the linked attribute as a flag, you could do that by using the attrs variable:
.directive('productname', function (Prefs) {
return {
restrict: 'E',
scope: {
product: "="
},
replace: true,
templateUrl: '/partials/productname.html',
link: function (scope, element, attrs) {
// scope.product is automatically set
scope.linked = typeof attrs.linked != 'undefined';
scope.brand = Prefs.owner;
}
}
})
Call it like so:
<productname product="product" linked></productname>

How to call a directive from an another directive in AngularJS?

I have just started using AngularJS. Is there a way to use a directive from an another directive ?
I would like to add new <div time></div> on click on the parent.
EDIT : index.html
<div class="time" addtime ng-click="addTime()">
<!-- ADD NEW <div resizable draggable ...></div> from directive 'time' HERE -->
</div>
EDIT : directive.js
dragDirectives.directive('addtime', function() {
return {
restrict: 'A',
link: function(scope, element, attr, ctrl) {
},
controller: function addtimeCtrl($scope, $element){
$scope.addTime = function() {
// ADD NEW <div resizable draggable ...></div> from directive 'time'
};
}
}
});
dragDirectives.directive('time', function() {
return {
restrict: 'A',
template: '<div resizable draggable class="duree" ng-class="{\'resize-active\': isResizeActive, \'drag-active\': isDragActive }" ng-style="{ width: myWidth, left: myLeft }">',
link: function(scope, element, attr) {
}
}
});
With Angular you do not do DOM-related or jQuery-ish stuff (i.e. addEventListener). The approach would be:
Have a model describe the <div time> elements you have, e.g.:
scope.timeElements = [];
Itarate over it in the template:
<div time ng-repeat="t in timeElements"></div>
Handle the event by manipulating the model, e.g.:
(HTML)
<div class="time" addtime ng-click="addTime()">
(JS)
scope.addTime = function() {
scope.timeElements.push(something);
};
This is only an outline for a real solution, as many details are still missing, but you should get the idea. A fiddle would help getting more specific.
Also check out this.
require: '^parent' // a better way to go
dragDirectives.directive('addtime', function() {
return {
restrict: 'A',
template: '<div time ng-repeat="t in timeElements"></div>',
link: function(scope, element, attr, ctrl) {
scope.timeElements = [1, 2, 3]
},
controller: function addtimeCtrl($scope) {
this.addTime = function() {
$scope.timeElements.push($scope.timeElements.length + 1);
};
}
}
});
dragDirectives.directive('time', function() {
return {
restrict: 'A',
require: '^addtime',
template: '<div ng-click="addTime()">time</div>',
link: function(scope, element, attr, ctrl) {
scope.addTime = ctrl.addTime;
}
}
});

Resources