Comment créer un popover AngularJS UI bootstrap avec du contenu HTML?

je veux créer un bootstrap liste avec une étiquette pré-contenant un objet JSON pré-certifié. L'implémentation naïve,

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

échappe au contenu avant de l'insérer dans le popup. Quelle est la meilleure façon de spécifier un corps popover avec du contenu html?

42
demandé sur Andrey Fedorov 2013-05-23 23:36:24

7 réponses

UPDATE:

Comme on peut le voir dans , vous devriez maintenant être en mesure de le faire sans écraser le modèle par défaut.

ORIGINAL:

à partir de l'angle 1,2+ ng-bind-html-unsafe a été supprimé. vous devriez être en utilisant le $ sce service. Référence.

voici un filtre pour créer du html de confiance.

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

Voici la écrasées Bootstrap Angulaire 0.11.2 modèle faisant usage de ce filtre

// 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: Voici un Plunker mise en œuvre.

EDIT 2: comme cette réponse ne cesse de recevoir des réponses, je la tiendrai à jour du mieux que je peux. Comme une référence Ici est le modèle de la angular-ui bootstrap repo. Si cela change, le modèle override nécessitera des mises à jour correspondantes et l'ajout du ng-bind-html=\"title | unsafe\" et ng-bind-html=\"content | unsafe\" attributs pour continuer à travailler.

pour mise à jour conversation vérifiez le ici.

69
répondu Matthew.Lothian 2017-05-23 10:29:52

liste-modèle la directive

Si vous utilisez une version de angular-ui égal ou supérieur à 0.13.0, votre meilleure option est d'utiliser le popover-template la directive. Voici comment l'utiliser:

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

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

NB: N'oubliez pas les guillemets autour du nom du modèle dans popover-template="'popover.html'".

Voir démo plunker


comme note secondaire, il est possible d'externaliser la liste modèle dans un fichier html, au lieu de le déclarer dans un <script type="text/ng-template> élément comme ci-dessus.

Voir deuxième démo plunker

23
répondu Michael P. Bazos 2015-10-02 17:15:55

je poste une solution sur le projet github: https://github.com/angular-ui/bootstrap/issues/520

I vous voulez ajouter cette fonctionnalité à votre projet, voici un patch.

Ajouter ces 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");
    }]);

Et ajouter le modèle:

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

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

Afficher sur plunkr: http://plnkr.co/edit/VhYAD04ETQsJ2dY3Uum3?p=preview

9
répondu user1067920 2014-07-24 09:49:15

vous devez modifier le modèle de popover par défaut pour spécifier que vous voulez autoriser le contenu Html. Regarder le popover-content div, il a maintenant sa liaison fait à l' content propriété permettant un html non sécurisé:

 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>");
    }]);
6
répondu Andres 2013-12-20 01:15:22

Pour tous vos classiques Bootstrap popover besoins vous pouvez utiliser la directive angulaire suivante. Il supprime le désordre du modèle HTML et est très facile à utiliser.

Vous pouvez configurer la liste des title,content,placement, fade in / out delay,trigger et si le contenu doit être traité comme html. Il empêche également le débordement de contenu & la coupure.

plunker apparenté avec tous les codes teh ici http://plnkr.co/edit/MOqhJi

Screencap

imgur

Utilisation

<!-- 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 });
    }
  };
});
5
répondu Mikko Viitala 2015-01-28 16:46:24

https://github.com/jbruni/bootstrap-bower-jbruni, qui permettent l'utilisation d'une liste-modèle

3
répondu Thierry 2014-07-04 10:08:56

Le code CSS suivant le style semble avoir fait ce que je voulais dans mon cas précis:

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

la question générale reste ouverte.

1
répondu Andrey Fedorov 2013-05-24 20:42:17