ui.bootstrap- directrive with uib-popover-html doesn't work
Solution 1
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:
- Make sure the versions of
angular.js
andui-bootstrap-tpls.js
are up to date. - Make sure
ui-bootstrap
is correctly injected in to the application (You had @Kosmno but I hadn't!) - Make sure the App is initiated on an element using
ng-app
Here's your working plunker, along with another one I made.
Solution 2
You need to update your ui-bootstrap to ~0.14.x
Kosmonaft
Updated on June 26, 2022Comments
-
Kosmonaft almost 2 years
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?
-
Kosmonaft over 8 yearsIt doesn't work for me. Here is the plunker - plnkr.co/edit/dLBgL9WBxevYqCbnGl2b?p=preview
-
neridaj almost 8 yearsIt doesn't even work with the demo code from the docs: plnkr.co/edit/7o7OBnqxFqxl2eGTefcU?p=preview
-
AdamExchange almost 8 yearshere is one that works with 0.14.3 that is closer to the demo from the docs. plnkr.co/edit/6MwtASS0oR69XDh9OHun?p=preview
-
albttx almost 8 yearsYou just save my day ! Thank you !