Reputation: 1343
I am trying to create a directive with popover.
I want to use ui.bootstrap for this. Unfortunately it doesn't display anything. Here is the plunker with example.
<div>
Popover uib (notworking- uib-popover-html) ->
<div mydirectiveuib ng-model="name"></div>
</div>
app.directive('mydirectiveuib', function(){
return{
restrict: 'EA',
replace: true,
scope: {
ngModel: '='
},
template: ' <span class="test">aaa<img popover-trigger="mouseenter" popover-placement="right" uib-popover-html="<h2>{{ngModel}}</h2>" width="20" height="20" src="http://icons.iconarchive.com/icons/dakirby309/windows-8-metro/48/Folders-OS-Info-Metro-icon.png" alt="info icon" /></span>',
link: function(scope, iElement, iAttrs) {
}
};
})
If I change uib-popover-html to only popover it is working.
<div>
Popover (working) ->
<div mydirective ng-model="name"></div>
</div>
app.directive('mydirective', function(){
return{
restrict: 'EA',
replace: true,
scope: {
ngModel: '='
},
template: ' <span class="test">aaa<img popover-trigger="mouseenter" popover-placement="right" popover="<h2>{{ngModel}}</h2>" width="20" height="20" src="http://icons.iconarchive.com/icons/dakirby309/windows-8-metro/48/Folders-OS-Info-Metro-icon.png" alt="info icon" /></span>',
link: function(scope, iElement, iAttrs) {
}
};
})
Any idea what i am doing wrong and how to fix it?
Upvotes: 3
Views: 11169
Reputation: 401
You may have found a solution already, so this may be for future readers with similar problems (as I was).
We need to look closely at the ui-bootstrap documentation here, which says:
There are two versions of the popover:
uib-popover
anduib-popover-template
:
uib-popover
takes text only and will escape any HTML provided for the popover body.uib-popover-html
takes an expression that evaluates to an html string. The user is responsible for ensuring the content is safe to put into the DOM!uib-popover-template
takes text that specifies the location of a template to use for the popover body. Note that this needs to be wrapped in a tag.
So the argument for uib-popover-html
is an expression that evaluates to an html string, not the html string itself. So you could have:
...
template: '<ANY ... uib-popover-html="popoverHtml" ... >',
link: function(scope, iElement, iAttrs) {
scope.popoverHtml = '<div><h2>{{ngModel}}</h2><p>Hello {{ngModel}}</p></div>';
}
However, this does not work as it is, because it is potentially unsafe, and "the user is responsible for ensuring the content is safe to put into the DOM". To make it work would need to understand and then implement strict contextual escaping. This is where I gave up on the HTML method, in favour of using uib-popover-template
.
Don't ask me why this is more safe, but the following template for your custom directive works:
...
template: '<ANY ... uib-popover-template="\'popover.html\'" popover-trigger="mouseenter" ... > Popover </ANY>',
// NB need to escape the single 's here ^ and here ^
...
NB As uib-popover-template
"takes text that specifies the location of a template", the location needs to render as "'popover.html'"
so the single quotes need to be escaped in the directive's inline template (or use an external template).
Other things to correct:
angular.js
and ui-bootstrap-tpls.js
are up to date.ui-bootstrap
is correctly injected in to the application (You had @Kosmno but I hadn't!)ng-app
Here's your working plunker, along with another one I made.
Upvotes: 10