Yoav Yoav - 11 days ago 10
AngularJS Question

Bootstrap tooltip from dynamic HTML not working

I have an

HTML
page that part of it is generated using
HTML
injection from a
typescript
angularjs
controller using
$sce
and
ng-bind-html
.

My problem is that the
bootstrap
tooltip style isn't applied and I only get the simple built in yellow tooltip.

My controller function that generates the HTML (not sure if it's relevant but note the comment next to the
console.log
section):

public renderHtml = () => {
this.test = '<span style="text-decoration:underline" data-toggle="tooltip" data-placement="top" title="Tooltip on top">my team</span>';
console.log(this.test); // this line is logged 6 times with the same value on each page refresh

return this.$sce.trustAsHtml(this.test);
}


The HTML (I've added the exact same HTML snippet directly to the page and it works fine):

<!--bootstrap tooltip doesn't show-->
<div class="row margin-25" ng-bind-html="cdc.renderHtml()"></div>

<div>
<!--bootstrap tooltip works-->
<span style="text-decoration:underline" data-toggle="tooltip" data-placement="top" title="Tooltip on top">my team</span>
</div>


Here is the outcome (not working on left):
tooltips

Answer

As per documentation:

Opt-in functionality

For performance reasons, the Tooltip and Popover data-apis are opt-in, meaning you must initialize them yourself.

Example with your approach on jsfiddle:

angular.module('ExampleApp', [])
  .controller('ExampleController', function($sce) {
    this.renderHTML = () => {
      return $sce.trustAsHtml('<span style="text-decoration:underline" data-toggle="tooltip" data-placement="bottom" title="Tooltip on top">my team</span>');
    };
  });
$(document).ready(function() {
  $('span').tooltip();
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<div ng-app="ExampleApp">
  <div ng-controller="ExampleController as vm">
    <div ng-bind-html="vm.renderHTML()"></div>
    <span style="text-decoration:underline" data-toggle="tooltip" data-placement="right" title="Tooltip on top">my team</span>
  </div>
</div>

Better solution is use directive:

angular.module('ExampleApp', [])
  .controller('ExampleController', function($sce) {})
  .directive("title", function($timeout) {
    return {
      link: function(scope, element) {
        $timeout(function() {
          $(element).tooltip()
        }, 0);
      }
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<div ng-app="ExampleApp">
  <div ng-controller="ExampleController as vm">
    <div>
      <span style="text-decoration:underline" data-toggle="tooltip" data-placement="bottom" title="Tooltip on top">my team</span>
    </div>
    <span style="text-decoration:underline" data-toggle="tooltip" data-placement="right" title="Tooltip on top">my team</span>
  </div>
</div>

Comments