Anglular Transclude from child directive - angularjs

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>'
};

Related

Directive displaying Error: [$parse:lexerr] after moving template to templateURL

I have a directive working without any issues when the HTML markup is written in the template section of the directive.
I've just moved the HTML markup in a .html file and on load of the page, i am seeing:
Error: [$parse:lexerr] http://errors.angularjs.org/1.3.14/$parse/lexerr?p0=Unexpected%20next%20character%20&p1=s%2016-16%20%5B%5C%5D&p2=option.name%20%3D%3D%3D%20%5C'choices%5C'
Original directive:
app.directive('myDirective', function () {
return {
restrict: 'E',
scope: {
data: "="
},
template: '<p>' +
'<div ng-repeat="select in data.output">' +
'<div ng-if= "select.name === \'choices\'">' +
'<p ng-repeat="choice in select.value"><label><input type="radio" ng-model="data.input[0].value" ng-value="$index" >{{choice}}</label></p>' +
'</div>' +
'</div>' +
'</p>'
}
}
);
New:
app.directive('myDirective', function () {
return {
restrict: 'E',
scope: {
data: "="
},
templateUrl: 'home/mydirective.html'
}
}
);
I page load i can see the http request for mydirective.html and the markup is correct, however the lexerr then appears in the console.
Your html should not contain concatenation that will mess while angular $compile that template. It should be plain html.
mydirective.html
<p>
<div ng-repeat="select in data.output">
<div ng-if="select.name === 'choices'">
<p ng-repeat="choice in select.value">
<label>
<input type="radio" ng-model="data.input[0].value" ng-value="$index">{{choice}}</label>
</p>
</div>
</div>
</p>
In my case this was related to using single quote with a backslash (\') in the .html-file. It was working well when the html was put directly inside the directive using template.
But it threw an error when it was put in a separate .html-file and using templateUrl. So changing ng-class="{\'something\'}" to ng-class="{'something'}" fixed it for me. Hope this will save someone else couple of hours.

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

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);

How to pass HTML to angular directive?

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

Resources