Utilisation de l'info-bulle Bootstrap avec AngularJS


90

J'essaie d'utiliser l'info-bulle Bootstrap dans une de mes applications. Mon application utilise AngularJS Actuellement, j'ai les éléments suivants:

<button type="button" class="btn btn-default" 
        data-toggle="tooltip" data-placement="left"
        title="Tooltip on left">
            Tooltip on left
</button>

Je pense que j'ai besoin d'utiliser

$("[data-toggle=tooltip]").tooltip();

Cependant, je ne suis pas sûr. Même lorsque j'ajoute la ligne ci-dessus, mon code ne fonctionne pas. J'essaie d'éviter d'utiliser le bootstrap de l'interface utilisateur car il en a plus que ce dont j'ai besoin. Cependant, si je devais inclure uniquement la partie de l'info-bulle, je serais ouvert à cela. Pourtant, je ne peux pas comprendre comment faire cela.

Quelqu'un peut-il me montrer comment faire fonctionner l'info-bulle Bootstrap avec AngularJS?


4
Sans utiliser Angular-UI Bootstrap, vous devrez effectuer toutes les liaisons pour vos événements. Si vous ne souhaitez pas utiliser UI Bootstrap car il en a plus que ce dont vous avez besoin, avez-vous envisagé de ne charger que les pièces dont vous avez besoin: github.com/angular-ui/bootstrap/tree/master/src/popover
TheSharpieOne

Réponses:


151

Pour que les info-bulles fonctionnent en premier lieu, vous devez les initialiser dans votre code. En ignorant AngularJS pendant une seconde, voici comment faire fonctionner les info-bulles dans jQuery:

$(document).ready(function(){
    $('[data-toggle=tooltip]').hover(function(){
        // on mouseenter
        $(this).tooltip('show');
    }, function(){
        // on mouseleave
        $(this).tooltip('hide');
    });
});

Cela fonctionnera également dans une application AngularJS tant que ce n'est pas du contenu rendu par Angular (par exemple: ng-repeat). Dans ce cas, vous devez écrire une directive pour gérer cela. Voici une directive simple qui a fonctionné pour moi:

app.directive('tooltip', function(){
    return {
        restrict: 'A',
        link: function(scope, element, attrs){
            element.hover(function(){
                // on mouseenter
                element.tooltip('show');
            }, function(){
                // on mouseleave
                element.tooltip('hide');
            });
        }
    };
});

Il ne vous reste plus qu'à inclure l'attribut "info-bulle" sur l'élément sur lequel vous voulez que l'info-bulle apparaisse:

<a href="#0" title="My Tooltip!" data-toggle="tooltip" data-placement="top" tooltip>My Tooltip Link</a>

J'espère que cela pourra aider!


Belle solution! J'ai remplacé app.directive par angular.module ('tooltip', []). Directive pour le faire fonctionner dans mon application.
Beanwah

Belle solution. Pouvons-nous y ajouter du CSS pour modifier l'info-bulle?

1
Pourrait ajouter $(element).tooltip({html: 'true', container: 'body'})avant d'appeler une info-bulle comme exemple sur la fourniture d'options personnalisées.
Vajk Hermecz

1
element.tooltip()peut être utilisé à la place de jQuery.
Brian

1
Quelle belle réponse
Gimmly

58

La meilleure solution que j'ai pu trouver est d'inclure un attribut "onmouseenter" sur votre élément comme ceci:

<button type="button" class="btn btn-default" 
    data-placement="left"
    title="Tooltip on left"
    onmouseenter="$(this).tooltip('show')">
</button>

1
Boostrap JS est une bibliothèque jQuery. Au moins, c'était dans Bootstrap 3.
gabeodess

1
Fonctionne également avec Angular 2+. Merci!
Songtham T.

32

Réponse simple - en utilisant UI Bootstrap ( ui.bootstrap.tooltip )

Il semble y avoir un tas de réponses très complexes à cette question. Voici ce qui a fonctionné pour moi.

  1. Installer UI Bootstrap -$ bower install angular-bootstrap

  2. Injecter UI Bootstrap en tant que dépendance - angular.module('myModule', ['ui.bootstrap']);

  3. Utilisez la directive uib-tooltip dans votre html.


<button class="btn btn-default"
        type="button"
        uib-tooltip="I'm a tooltip!">
     I'm a button!
</button>

2
Pas de jQuery, utilisant purement Angular et ui-bootstrap; C'est ce que je cherchais, merci
Rsh

La seule solution qui a fonctionné pour moi. Je vous remercie! (@Kondal - oui, cela fonctionne sans jQuery).
Nick Grealy

28

Si vous créez une application angulaire, vous pouvez utiliser jQuery, mais il y a beaucoup de bonnes raisons d'essayer de l'éviter en faveur de paradigmes plus angulaires. Vous pouvez continuer à utiliser les styles fournis par bootstrap, mais remplacez les plugins jQuery par angular natif en utilisant UI Bootstrap

Incluez les fichiers CSS Boostrap, Angular.js et ui.Bootstrap.js:

<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.angularjs.org/1.2.20/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>

Assurez-vous d'avoir injecté ui.bootstraplorsque vous créez votre module comme ceci:

var app = angular.module('plunker', ['ui.bootstrap']);

Ensuite, vous pouvez utiliser des directives angulaires au lieu d'attributs de données récupérés par jQuery:

<button type="button" class="btn btn-default" 
        title="Tooltip on left" data-toggle="tooltip" data-placement="left"
        tooltip="Tooltip on left" tooltip-placement="left" >
  Tooltip on left
</button>

Démo dans Plunker


Éviter le bootstrap de l'interface utilisateur

jQuery.min.js (94kb) + Bootstrap.min.js (32kb) vous donne également plus que ce dont vous avez besoin, et bien plus que ui-bootstrap.min.js (41kb) .

Et le temps passé à télécharger les modules n'est qu'un aspect des performances.

Si vous voulez vraiment charger uniquement les modules dont vous avez besoin, vous pouvez "Créer une construction" et choisir des info-bulles sur le site Web Bootstrap-UI . Ou vous pouvez explorer le code source pour les info-bulles - et choisir ce dont vous avez besoin.

Voici une version personnalisée minifiée avec juste les infobulles et les modèles (6 Ko)


Il convient de noter que, au moment de l'écriture, la v 0.12.1 est pour la v1.2 d'Angular. la branche 0.13 sera pour Angular 1.3+ mais le nouveau mainteneur travaille toujours dessus (et fait un excellent travail!)
Nick

11

Avez-vous inclus Bootstrap JS et jQuery?

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>

Si vous ne les chargez pas déjà, l'interface utilisateur angulaire ( http://angular-ui.github.io/bootstrap/ ) ne sera peut-être pas très lourde. Je l'utilise avec mon application Angular, et elle a une directive Tooltip. Essayez d'utilisertooltip="tiptext"

<button type="button" class="btn btn-default" 
        data-toggle="tooltip" data-placement="left"
        title="Tooltip on left"
        tooltip="This is a Bootstrap tooltip"
        tooltip-placement="left" >
            Tooltip on left
</button>

Merci @prototype! J'allais opter pour la réponse @gabeodess, mais je préfère cette solution car elle ne dit pas explicitement qu'elle a besoin de jQuery, ce qui le rend un peu moins couplé et un peu plus facile à changer pour une solution entièrement angulaire à l'avenir.
hatsrumandcode

8

J'ai écrit une directive angulaire simple qui fonctionne bien pour nous.

Voici une démo: http://jsbin.com/tesido/edit?html,js,output

Directive (pour Bootstrap 3) :

// registers native Twitter Bootstrap 3 tooltips
app.directive('bootstrapTooltip', function() {
  return function(scope, element, attrs) {
    attrs.$observe('title',function(title){
      // Destroy any existing tooltips (otherwise new ones won't get initialized)
      element.tooltip('destroy');
      // Only initialize the tooltip if there's text (prevents empty tooltips)
      if (jQuery.trim(title)) element.tooltip();
    })
    element.on('$destroy', function() {
      element.tooltip('destroy');
      delete attrs.$$observers['title'];
    });
  }
});

Remarque: Si vous utilisez Bootstrap 4, aux lignes 6 et 11 ci-dessus, vous devrez remplacer tooltip('destroy')par tooltip('dispose')(Merci à user1191559 pour cette mise à jour )

Ajoutez simplement bootstrap-tooltipcomme attribut à n'importe quel élément avec un title. Angular surveillera les modifications apportées autitle mais sinon transmettra la gestion de l'info-bulle à Bootstrap.

Cela vous permet également d'utiliser l'une des options d'infobulle Bootstrap natives comme data-attributs de la manière normale Bootstrap.

Balisage :

<div bootstrap-tooltip data-placement="left" title="Tooltip on left">
        Tooltip on left
</div>

Clairement, cela n'a pas toutes les liaisons élaborées et l'intégration avancée qu'offrent AngularStrap et UI Bootstrap, mais c'est une bonne solution si vous utilisez déjà le JS de Bootstrap dans votre application Angular et que vous avez juste besoin d'un pont d'info-bulles de base sur toute votre application sans modifier les contrôleurs ou gérer les événements de souris.


1
J'ai essayé d'utiliser ceci et j'ai eu une Error: cannot call methods on tooltip prior to initialization; attempted to call method 'destroy'erreur.
Chris

@CD Hmm ... Je ne suis pas encore capable de reproduire cette erreur. J'ai ajouté cette URL de démonstration à la réponse: jsbin.com/tesido/edit?html,js,output Si vous savez en quoi votre code diffère, faites-le moi savoir et je verrai si je peux vous aider. À propos, la démo utilise Angular v1.2, Bootstrap v3.3, jQuery v2.1
brandonjp

1
Merci, c'est le seul de ces exemples qui met à jour l'info-bulle de manière dynamique si le titre change via la liaison.
dalcam

1
BTW pour BS4, vous devez permuter la ligne: element.tooltip('destroy'); avec element.tooltip('dispose');aux deux endroits.
dalcam

4

Vous pouvez utiliser l' selector option pour les applications dynamiques d'une seule page:

jQuery(function($) {
    $(document).tooltip({
        selector: '[data-toggle="tooltip"]'
    });
});

si un sélecteur est fourni, les objets d'info-bulle seront délégués aux cibles spécifiées. En pratique, cela est utilisé pour permettre au contenu HTML dynamique d'ajouter des info-bulles.


4

Vous pouvez créer une directive simple comme celle-ci:

angular.module('myApp',[])
    .directive('myTooltip', function(){
        return {
            restrict: 'A',
            link: function(scope, element){
                element.tooltip();
            }
        }
    });

Ensuite, ajoutez votre directive personnalisée si nécessaire:

<button my-tooltip></button>

3

Vous pouvez le faire avec AngularStrap qui

est un ensemble de directives natives qui permet une intégration transparente de Bootstrap 3.0+ dans votre application AngularJS 1.2+. "

Vous pouvez injecter toute la bibliothèque comme ceci:

var app = angular.module('MyApp', ['mgcrea.ngStrap']); 

Ou tirez uniquement sur la fonction d'info-bulle comme ceci:

var app = angular.module('MyApp', ['mgcrea.ngStrap.tooltip']); 

Démo dans Stack Snippets

var app = angular.module('MyApp', ['mgcrea.ngStrap']);  
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.tpl.min.js"></script>

<div ng-app="MyApp" class="container" >

  <button type="button" 
          class="btn btn-default" 
          data-trigger="hover" 
          data-placement="right"
          data-title="Tooltip on right"
          bs-tooltip>
    MyButton
  </button>

</div>


2

moyen le plus simple, ajoutez $("[data-toggle=tooltip]").tooltip();au contrôleur concerné.


1

var app = angular.module('MyApp', ['mgcrea.ngStrap']);  
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.tpl.min.js"></script>

<div ng-app="MyApp" class="container" >

  <button type="button" 
          class="btn btn-default" 
          data-trigger="hover" 
          data-placement="right"
          data-title="Tooltip on right"
          bs-tooltip>
    MyButton
  </button>

</div>


3
Veuillez ajouter quelques explications à votre réponse.
André Kool

1

N'oubliez pas qu'une chose si vous souhaitez utiliser l'info-bulle d'amorçage dans angularjs est l'ordre de vos scripts si vous utilisez également jquery-ui, cela devrait être:

  • jQuery
  • jQuery UI
  • Bootstap

Il a fait ses preuves


1

Ne lisez ceci que si vous attribuez des info-bulles dynamiquement

c'est à dire <div tooltip={{ obj.somePropertyThatMayChange }} ...></div>

J'ai eu un problème avec les info-bulles dynamiques qui ne se mettaient pas toujours à jour avec la vue. Par exemple, je faisais quelque chose comme ceci:

Cela n'a pas fonctionné de manière cohérente

<div ng-repeat="person in people">
    <span data-toggle="tooltip" data-placement="top" title="{{ person.tooltip }}">
      {{ person.name }}
    </span> 
</div> 

Et l'activer comme tel:

$timeout(function() {
  $(document).tooltip({ selector: '[data-toggle="tooltip"]'});
}, 1500)

Cependant, comme mon tableau de personnes changerait, mes info-bulles ne seraient pas toujours mises à jour. J'ai essayé tous les correctifs de ce fil et d'autres sans succès. Le problème ne semblait se produire que dans 5% du temps et était presque impossible à répéter.

Malheureusement, ces info-bulles sont essentielles à la mission de mon projet et l'affichage d'une info-bulle incorrecte peut être très mauvais.

Ce qui semblait être le problème

Bootstrap copiait la valeur de la titlepropriété dans un nouvel attribut data-original-titleet supprimait la titlepropriété (parfois) lorsque j'activerais les info-bulles. Cependant, lorsque mon title={{ person.tooltip }}changerait, la nouvelle valeur ne serait pas toujours mise à jour dans la propriété data-original-title. J'ai essayé de désactiver les info-bulles et de les réactiver, de les détruire, de lier directement cette propriété ... tout. Cependant, chacun de ces éléments n'a pas fonctionné ou a créé de nouveaux problèmes; tels que les attributs titleet à la data-original-titlefois supprimés et non liés de mon objet.

Qu'est-ce qui a fonctionné

Peut-être le code le plus laid que j'ai jamais poussé, mais il a résolu ce petit mais substantiel problème pour moi. J'exécute ce code chaque fois que l'info-bulle est mise à jour avec de nouvelles données:

$timeout(function() {
    $('[data-toggle="tooltip"]').each(function(index) {
      // sometimes the title is blank for no apparent reason. don't override in these cases.
      if ($(this).attr("title").length > 0) {
        $( this ).attr("data-original-title", $(this).attr("title"));
      }
    });
    $timeout(function() {
      // finally, activate the tooltips
      $(document).tooltip({ selector: '[data-toggle="tooltip"]'});
    }, 500);
}, 1500);

Ce qui se passe ici est essentiellement:

  • Attendez un peu (1500 ms) pour que le cycle de digestion se termine, et le title s soient mis à jour.
  • S'il y a une titlepropriété qui n'est pas vide (c'est-à-dire qu'elle a changé), copiez-la dans la data-original-titlepropriété afin qu'elle soit récupérée par les toolips de Bootstrap.
  • Réactiver les info-bulles

J'espère que cette longue réponse aidera quelqu'un qui a peut-être eu du mal comme moi.


1

Essayez l'info-bulle (ui.bootstrap.tooltip). Voir les directives angulaires pour Bootstrap

<button type="button" class="btn btn-default" tooltip-placement="bottom" uib-tooltip="tooltip message">Test</button>

Il est recommandé d'éviter le code JavaScript en haut d'AngularJS


1

pour obtenir des info-bulles à actualiser lorsque le modèle change , j'utilise simplement data-original-titleau lieu detitle .

par exemple

<i class="fa fa-gift" data-toggle="tooltip" data-html="true" data-original-title={{getGiftMessage(gift)}} ></i>

notez que j'initialise l'utilisation des infobulles comme celle-ci:

<script type="text/javascript">
    $(function () {
        $("body").tooltip({ selector: '[data-toggle=tooltip]' });
    })
</script>

versions:

  • AngularJS 1.4.10
  • bootstrap 3.1.1
  • jquery: 1.11.0

0

AngularStrap ne fonctionne pas dans IE8 avec angularjs version 1.2.9 donc ne l'utilisez pas si votre application doit prendre en charge IE8


0

Impproving @aStewartDesign réponse:

.directive('tooltip', function(){
  return {
    restrict: 'A',
    link: function(scope, element, attrs){
      element.hover(function(){
        element.tooltip('show');
      }, function(){
        element.tooltip('hide');
      });
    }
  };
});

Il n'y a pas besoin de jquery, c'est une réponse tardive, mais je me suis dit que c'est celui qui a été le plus voté, je devrais le souligner.


0

installez les dépendances:

npm install jquery --save
npm install tether --save
npm install bootstrap@version --save;

ensuite, ajoutez des scripts dans votre angular-cli.json

"scripts": [
        "../node_modules/jquery/dist/jquery.min.js",
        "../node_modules/tether/dist/js/tether.js",
        "../node_modules/bootstrap/dist/js/bootstrap.min.js",
        "script.js"
    ]

puis, créez un script.js

$("[data-toggle=tooltip]").tooltip();

redémarrez maintenant votre serveur.


mauvaise version angulaire, la question originale concerne AngularJS not Angular
Jose Luis Berrocal

0

En raison de la fonction d'info-bulle, vous devez indiquer à angularJS que vous utilisez jQuery.

Voici votre directive:

myApp.directive('tooltip', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('mouseenter', function () {
                jQuery.noConflict();
                (function ($) {
                    $(element[0]).tooltip('show');
                })(jQuery);
            });
        }
    };
});

et voici comment utiliser la directive:


<a href="#" title="ToolTip!" data-toggle="tooltip" tooltip></a>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.