How to style a directive from the outside? - angularjs

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 : "#"
},
};
});

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

Understanding the contextual usage of scope in angular directive

I was just going through the documentation of Angular.js for ngTransclude, i came across the following example:
<script>
angular.module('transcludeExample', [])
.directive('pane', function(){
return {
restrict: 'E',
transclude: true,
scope: { title:'#' },
template: '<div style="border: 1px solid black;">' +
'<div style="background-color: gray">{{title}}</div>' +
'<ng-transclude></ng-transclude>' +
'</div>'
};
})
.controller('ExampleController', ['$scope', function($scope) {
$scope.title = 'Lorem Ipsum';
$scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
}]);
</script>
<div ng-controller="ExampleController">
<input ng-model="title" aria-label="title"> <br/>
<textarea ng-model="text" aria-label="text"></textarea> <br/>
<pane title="{{title}}">{{text}}</pane>
</div>
I am not quite sure why these two properties are used in the directive:
transclude: true,
scope: { title:'#' },
I beleive doing transclude: true, gives the directive access to
$scope.title
$scope.text
which is in the controller , i am not sure about this though , but why is scope being used here ? i mean in such a weird fashion that too, I.E. ,
scope: { title:'#' },
What is the # there for ? so to sum up my whole question, can somebody explain to me why the transclude and scope properties are used here in the directive ?
Thank you
The transclude property tells angular to replace the <ng-transclude> tag with the HTML code inside the directive. In your case, the {{text}} string.
The property:
scope: { title:'#' },
tells angular to include the attribute title passed to the directive in its scope.
More documentation here:
What is the difference between '#' and '=' in directive scope in AngularJS?
and of course here:
https://docs.angularjs.org/guide/directive

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 write an angularjs directive that makes use of both scope and attributes and refer it thru compiled partial?

I want to write a directive which takes advantage of custom attributes, as follows:
<plant-stages
title="Exploration<br/>du cycle de<br/>développement<br/>de la plante"
></plant-stages>
The controller is currently as follows:
app.directive('plantStages', function () {
return {
restrict: 'AE',
templateUrl: 'corn.figure.plant.stages.html',
link: function (scope, element, attrs) {
scope.title = attrs.title;
}
};
});
The partial is as follows:
<figure class="cornStages">
<div>
<p>{{title}}</p>
</div>
<div ng-repeat="stage in stages">
<div class="stage{{stage.stage}}"></div>
<div>
BBCH : {{stage.bbch}}<br/>
{{stage.displayName}}
</div>
</div>
</figure>
The partial makes use of some scope model variables.
And {{title}} should support plain HTML injection out of the view which embeds it, hence should be compiled. I tried to support this but without success.
What modification should I make to have the HTML compiled?
A bonus question: when I pass the attribute in, I create a dummy title variable in the scope that persists where it should only be local. How would one make changes to handle this?
If you want to wrap HTML in your custom directive take a look at the transclude option (see docs):
module.directive('myDirective', function() {
return {
restrict: 'E',
transclude: true,
template: '<div ng-transclude></div>'
};
});
This enables you to place HTML within the directive tag which can be used in the template:
<div ng-controller="Controller">
<my-directive>
<h1>Test</h1>
</my-directive>
</div>
In case you really want to pass HTML via an attribute use ng-bind-html. This requires the ngSanitize module:
module.directive('myDirective', function () {
return {
restrict: 'E',
template: '<div ng-bind-html="title"></div>',
scope: {
title:'#'
}
};
});
I added this to your fiddle.

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