How do I create an AngularJS UI bootstrap popover with HTML content?

纵然是瞬间 提交于 2019-11-26 05:28:28

问题


I want to create a bootstrap popover with a pre tag containing a prettified JSON object. The naive implementation,

<span popover=\'<pre>{[ some_obj | json:\"  \" ]}</pre>\'
      popover-trigger=\'mouseenter\'>

escapes the content before inserting it into the popup. What\'s the best way of specifying a popover body with html content?


回答1:


UPDATE:

As can been seen in this, you should now be able to do this without overriding the default template.

ORIGINAL:

As of angular 1.2+ ng-bind-html-unsafe has been removed. you should be using the $sce service. Reference.

Here is a filter for creating trusted html.

MyApp.filter('unsafe', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsHtml(val);
    };
}]);

Here is the overwritten Angular Bootstrap 0.11.2 template making use of this filter

// update popover template for binding unsafe html
angular.module("template/popover/popover.html", []).run(["$templateCache", function ($templateCache) {
    $templateCache.put("template/popover/popover.html",
      "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
      "  <div class=\"arrow\"></div>\n" +
      "\n" +
      "  <div class=\"popover-inner\">\n" +
      "      <h3 class=\"popover-title\" ng-bind-html=\"title | unsafe\" ng-show=\"title\"></h3>\n" +
      "      <div class=\"popover-content\"ng-bind-html=\"content | unsafe\"></div>\n" +
      "  </div>\n" +
      "</div>\n" +
      "");
}]);

EDIT: Here is a Plunker implementation.

EDIT 2: As this answer keeps getting hits, i'll keep it updated as best i can. As a reference Here is the template from the angular-ui bootstrap repo. If this changes, the override template will require matching updates and the addition of the ng-bind-html=\"title | unsafe\" and ng-bind-html=\"content | unsafe\" attributes to continue working.

For updated conversation check the issue here.




回答2:


Use the popover-template directive

If you are using a version of angular-ui equal or above 0.13.0, your best option is to use the popover-template directive. Here is how to use it:

<button popover-template="'popover.html'">My HTML popover</button>

<script type="text/ng-template" id="popover.html">
    <div>
        Popover content
    </div>
</script>

NB: Do not forget the quotes around the template name in popover-template="'popover.html'".

See demo plunker


As a side note, it is possible to externalize the popover template in a dedicated html file, instead of declaring it in a <script type="text/ng-template> element as above.

See second demo plunker




回答3:


I have posted a solution on the github project: https://github.com/angular-ui/bootstrap/issues/520

I you want to add this functionality to your project, here is a patch.

Add those directives:

angular.module("XXX")
    .directive("popoverHtmlUnsafePopup", function () {
      return {
        restrict: "EA",
        replace: true,
        scope: { title: "@", content: "@", placement: "@", animation: "&", isOpen: "&" },
        templateUrl: "template/popover/popover-html-unsafe-popup.html"
      };
    })

    .directive("popoverHtmlUnsafe", [ "$tooltip", function ($tooltip) {
      return $tooltip("popoverHtmlUnsafe", "popover", "click");
    }]);

And add the template:

<div class="popover {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">
  <div class="arrow"></div>

  <div class="popover-inner">
      <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>
      <div class="popover-content" bind-html-unsafe="content"></div>
  </div>
</div>

Usage: <button popover-placement="top" popover-html-unsafe="On the <b>Top!</b>" class="btn btn-default">Top</button>

View it on plunkr: http://plnkr.co/edit/VhYAD04ETQsJ2dY3Uum3?p=preview




回答4:


You need to alter the default popover template to specify you want to allow Html content. Look the popover-content div, it now has its binding done to the content property allowing unsafe html:

 angular.module("template/popover/popover.html", []).run(["$templateCache", function ($templateCache) {
        $templateCache.put("template/popover/popover.html",
            "<div class='popover {{placement}}' ng-class='{ in: isOpen(), fade: animation() }'>" + 
            "<div class='arrow'></div><div class='popover-inner'>" + 
            "<h3 class='popover-title' ng-bind='title' ng-show='title'></h3>" + 
            "<div class='popover-content' ng-bind-html-unsafe='content'></div>" +
            "<button class='btn btn-cancel' ng-click='manualHide()'>Cancel</button>" +
            "<button class='btn btn-apply' ng-click='manualHide()'>Apply</button></div></div>");
    }]);



回答5:


For all your conventional Bootstrap popover needs you could utilize the following angular directive. It removes clutter from the HTML template and is very easy to use.

You can configure popover's title, content, placement, fade in/out delay, trigger event and whether content should be treated as html. It also prevents content overflow & clipping.

Related plunker with all teh codes here http://plnkr.co/edit/MOqhJi

Screencap

Usage

<!-- HTML -->
<div ng-model="popup.content" popup="popup.options">Some element</div>

/* JavaScript */
this.popup = {
  content: 'Popup content here',
  options: {
    title: null,
    placement: 'right', 
    delay: { show: 800, hide: 100 }
  }
}; 

JavaScript

/**
 * Popup, a Bootstrap popover wrapper.
 *
 * Usage: 
 *  <div ng-model="model" popup="options"></div>
 * 
 * Remarks: 
 *  To prevent content overflow and clipping, use CSS
 *  .popover { word-wrap: break-word; }
 *  Popup without title and content will not be shown.
 *
 * @param {String}  ngModel           popup content
 * @param {Object}  options           popup options
 * @param {String}  options.title     title
 * @param {Boolean} options.html      content should be treated as html markup
 * @param {String}  options.placement placement (top, bottom, left or right)
 * @param {String}  options.trigger   trigger event, default is hover
 * @param {Object}  options.delay     milliseconds or { show:<ms>, hide:<ms> }
 */
app.directive('popup', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    scope: {
      ngModel: '=',
      options: '=popup'
    },
    link: function(scope, element) {
      scope.$watch('ngModel', function(val) {
        element.attr('data-content', val);
      });

      var options = scope.options || {} ; 

      var title = options.title || null;
      var placement = options.placement || 'right';
      var html = options.html || false;
      var delay = options.delay ? angular.toJson(options.delay) : null;
      var trigger = options.trigger || 'hover';

      element.attr('title', title);
      element.attr('data-placement', placement);
      element.attr('data-html', html);
      element.attr('data-delay', delay);
      element.popover({ trigger: trigger });
    }
  };
});



回答6:


See https://github.com/jbruni/bootstrap-bower-jbruni, which allow to use a popover-template




回答7:


The following CSS styling seems to have done what I wanted in my specific case:

.popover-content {
  white-space: pre;
  font-family: monospace;
}

The general question still remains open.



来源:https://stackoverflow.com/questions/16722424/how-do-i-create-an-angularjs-ui-bootstrap-popover-with-html-content

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!