angularjs bootstrap popover data-binding not working - angularjs

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

Related

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

Put directive template as a content of container the directive is attached to

Normally, when i'm creating a directive, i have two possible ways to deal with directive templates. I can create a html file somewhere on my server and use it's URL in directive settings:
#directives.directive "someDirective", [
'$rootScope'
($rootScope) ->
controller: ($scope) ->
link: (scope, element, attrs) ->
return
restrict: 'A'
templateUrl: 'path/to/template.html'
scope: {
eventId: '#'
}
]
or i can put the script tag somewhere in the markup and use it's ID as a templateUrl:
<script type="text/ng-template" id="template.html">
<p>Hello {{ name }}</p>
</script>
However, i was wondering - is that possible to put that template to directive container tag as a body of it? That's how i want it to look:
<div my-ng-directive>
<p>Hello {{ name }}</p>
</div>
I think what you're looking for is ng-transclude,
basically ng-transclude allows your to "create" a slot in your original template that will contain the content of the original html element, so in your example a basic directive that does what you want will look like:
angular.module('myModule', [])
.directive('myNgDirective', function() {
return {
controller: function($scope) {
$scope.name = "Test";
},
transclude: true,
restrict: 'A',
template: '<div><h1>The directive</h1><div ng-transclude></div></div>'
}
});
This code:
<div my-ng-directive>
<p>Hello {{ name }}</p>
</div>
Will return:
<div>
<h1>The directive</h1>
<div>
<p>Hello {{ name }}</p>
</div>
</div>

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.

Using ng-switch in directive with transclude

I am trying to create a template that shows some transcluded content. When I use ng-show everything works fine, but using ng-if or ng-switch gives me problems. I get this error message: Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found
I understand that ng-switch creates a new scope. But the transclude should still go up to the parent chain. Is this a defect in angularjs? See http://jsfiddle.net/HgvP7/
Here is my html, modified from the documentation example:
<div ng-app="docsTransclusionExample">
<div ng-controller="Ctrl">
<my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>
<!-- my-dialog.html -->
<script type="text/ng-template" id="my-dialog.html">
<div ng-switch="1+1">
<div ng-switch-when="2">
<div ng-transclude></div>
</div>
</div>
</script>
</div>
And the code:
angular.module('docsTransclusionExample', [])
.controller('Ctrl', function($scope) {
$scope.name = 'Tobias';
})
.directive('myDialog', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html',
link: function (scope, element) {
scope.name = 'Jeff';
}
};
});

ng-switch to change user interface of a directive

I've created a directive for showing a person details:
angular.module('person.directives', []).
directive("person", function() {
return {
restrict: "E",
templateUrl: "person/views/person.html",
replace: true,
scope: {
myPerson: '='
},
link: function (scope, element, attrs) {
}
}
});
the view:
<div>
<span>FirstName: {{myPerson.firstName}}</span><span>LastName: {{myPerson.lastName}} </span>
</div>
The way it's called:
<person my-person="mandat.Person"></person>
mandat being a property of the parent controller.
Now, if myPerson is null, the UI for the directive should show a search button instead of the person details.
What's the best way for doig that ? Can I use the ng-switch statement ? How would I use it in this particular case ?
I found out... I use ng-show and ng-hide
<div>
<div ng-show="myPerson">
<span>FirstName: {{myPerson.firstName}}</span><span>LastName: {{myPerson.lastName}}</span>
</div>
<div ng-hide="myPerson">
<button>search</button>
</div>

Resources