How to pass HTML to angular directive? - angularjs

I am trying to create an angular directive with a template, but I also don't want to lose the HTML inside of the div. For example, here is how I would like to call my directive from HTML:
<div my-dir>
<div class="contents-i-want-to-keep"></div>
</div>
Then, there is my directive:
app.directive('myDir', [ '$compile', function($compile) {
return {
restrict: 'E',
link: function(scope, iElement, iAttrs){
// assigning things from iAttrs to scope goes here
},
scope: '#',
replace: false,
templateUrl: 'myDir.html'
};
}]);
and then there is myDir.html, where I define a new element:
<div class="example" style="background: blue; height: 30px; width: 30px"></div>
Even when I set replace to false, I lose the inner contents-i-want-to-keep div - my understanding of the angular docs was that this would be appended after my template. Is there some way to preserve this (possibly through my linking function?) so that the result will be
<div class="example" style="background: blue; height: 30px; width: 30px">
<div class="contents-i-want-to-keep"></div>
</div>
Thanks!

You'll need to use ng-transclude, add transclude: true in your directive options, and add ng-transclude to your template:
<div class="example" style="…" ng-transclude></div>`
This plunkr has an example on how to use ng-transclude with a template, to keep the original dom element.
http://plnkr.co/edit/efyAiTmcKjnhRZMTlNGf

Related

Anglular Transclude from child directive

I have a directive that I use to render a bootstrap panel, I use transclude to allow me to render custom content eg
<tn-Panel class="ng-cloak" title="'My Things'" >
<tn-Thing>
</tn-Thing>
</tn-Panel>
The tn-panel renders a header with the title and places the directive tn-thing within.
I would like to be able to render content in the body and some other content in the footer.
The following plunk shows this
https://plnkr.co/edit/j8U8MZlVSQCFB7RkpwOY?p=preview
But, it does not render the bits from content and header
<pane title="Nested">
<panenested></panenested> <-- does not following the transclude
</pane>
updated your directive
.directive('pane', function(){
return {
restrict: 'E',
transclude: {
'content': '?content',
'footer': '?footer',
'panenested':'?panenested',
},
scope: { title:'#' },
template: '<div style="border: 1px solid black;">' +
'<div style="background-color: gray">{{title}}</div>' +
'Content : <br> <ng-transclude ng-transclude="content"></ng-transclude> <br>' +
'Footer : <br> <ng-transclude ng-transclude="footer"></ng-transclude> <br>'
+'<br> <ng-transclude ng-transclude="panenested"></ng-transclude> <br>'+
'</div>'
};

AngularJs transclude not working in Directive template or templateURL

I have written a custom directive like so, notice I have commented out the template URL that contains the same HTML structure and the template property:
.directive('sillyDirective', function ( ) {
'use strict';
return {
restrict: 'A',
replace: false,
transclude: true,
template: '<h2>Welcome to my site</h2>',
//templateUrl: '/views/hello.html' ,
link: function (scope, element, attrs) {
element.bind('click', function (){
alert('you click me! I am clicked');
});
};
});
In my HTML view I have the following...
<div data-silly-directive>
<div><img src="logo.jpg></div>
<div><h1>My First Website</h1></div>
</div>
The problem is the content of the directive, e.g.:
<div><img src="logo.jpg></div>
<div><h1>My First Website</h1></div>
is being overwritten with the template content even thought I have set transclude to true and replace to false? What am I doing wrong here?
you need to specify ng-transclude in the template of your directive, this will let angular know where to insert the content of the markup.
app.directive("foo", function() {
return {
transclude: true,
template: "<div>the template</div><div ng-transclude></div>"
};
})
html:
<div foo>
Some Content Here
</div>
result:
<div foo>
<div>the template</div>
<div ng-transclude>Some Content Here</div>
</div>
here's a plnkr
source: https://www.accelebrate.com/blog/angularjs-transclusion-part-1/
Your template must contain an element with an ng-transclude attribute. That's where the body will be "pasted" by angular.
See
https://docs.angularjs.org/api/ng/directive/ngTransclude

Angular directive works with inline style but not with class

I have this directive:
angular.module('exampleApp').directive('exampleDirective', ['$document', '$window', function($document, $window) {
return {
restrict: 'E',
scope: false,
template: '<div class="foo"></div>',
link: function($scope, $element, $attrs) {
var targetElement = angular.element(document.querySelector($attrs['targetSelector']));
console.log(targetElement.css('height'));
}
}
]);
Which works fine with this html:
<div id="div1" style="height: 100px">A div</div>
<example-directive target-selector="#div1" />
Because in the console I see: "100px" printed out
But with this html:
<style>
.div-example {
height: 100px;
}
</style>
<div id="div2" class="div-example">A div</div>
<example-directive target-selector="#div2" />
Which is basically the same but without inline-style, the directive is simply not working. The console is printing: "" (empty string).
How do I solve this?
I tried scope: true but it didn't work either.
Is targetElement.css('height') only good for inline style?
When you do .css('height'), jQuery can tell you only the values set in the element's style property or attribute.
If you want to know the actual height of an element, try with
targetElement[0].clientHeight
Or with jQuery:
targetElement.height()
See the difference explained a bit better here: https://api.jquery.com/height/

How to style a directive from the outside?

I have a directive which I want to customize with style attribute from where I invoke it, as follows:
<plant-stages style="-webkit-transform: scale(.8); border: solid blue 1px"
stages="stages"
affectedstages="accident.stages"
change-page="changePage(stage)"
title="Les étapes du cycle suceptibles d'être affectées"
subtitle="Taper sur une des étape de la plante pour obtenir des informations détaillées"
></plant-stages>
By passing in style attributes, I'd like they apply to the resulting HTML from the directive, as any standard HTML directive would do.
The partial code snippet is as follows:
<figure class="cornStages">
<div></div>
</figure>
And the directive itself is as follows:
app.directive('plantStages', function ($compile) {
return {
restrict: 'E',
templateUrl: 'corn.figure.plant.stages.html',
transclude: true,
scope: {
stages: "=",
affectedstages:"=",
changePage: "&",
title: "#",
subtitle : "#"
},
Any idea?
One option could be to store the style in the scope by adding style: '#' in the definition of the scope of the directive and then to add ng-style="style" in your template.
I've made a working example on JS Fiddle.
The code is the following:
HTML
<div ng-app="myApp">
<my-little-directive style="color: red"></my-little-directive>
<my-little-directive style="color: blue"></my-little-directive>
<my-little-directive style="-webkit-transform: scale(.8); border: solid blue 1px"></my-little-directive>
</div>
Javascript
angular.module('myApp',[]).directive('myLittleDirective', function() {
return {
restrict: 'E',
template: '<div ng-style="style">{{style}}</div>',
replace: true,
scope: {
style : "#"
},
};
});

angularjs bootstrap popover data-binding not working

Currently, i am trying to make the angularjs popover data binding work.
Here is the html part:
<div id="sortable" ng-repeat="object in arrayForShow">
<div ng-class="classGenerate(object)" class="well nomargin" id="resizable" pop-over-width-offset argument='object'>
{{object.default}}
</div>
</div>
Now: ng-repeat item: object is passed into directive pop-over-width-offset.
In the popOverWidthOffset directive: I am trying the make the template html be able to access the **argument (which I set in the scope in the directive).**
app.directive "popOverWidthOffset", ($templateCache)->
restrict: 'A',
controller: 'CustomiseFormCtrl'
scope: {
argument: '='
}
link: (scope, element, attrs)->
popOverContent = $templateCache.get('angular/templates/popOverCustomisationChangeWidthOffset.html')
options = {
content: popOverContent,
placement: "top",
html: true,
}
$(element).popover(options)
popOverCustomisationChangeWidthOffset.html:
<form>
{{argument}}
</form>
Compile the content of the pop-over:
compiledPopOverContent = $compile(popOverContent)(scope);

Resources