Usando Bootstrap Tooltip com AngularJS

90

Estou tentando usar a dica de ferramenta Bootstrap em um aplicativo meu. Meu aplicativo está usando AngularJS. Atualmente, tenho o seguinte:

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

Eu acho que preciso usar

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

No entanto, não tenho certeza. Mesmo quando adiciono a linha acima, meu código não funciona. Estou tentando evitar o uso de bootstrap da interface do usuário, pois tem mais do que preciso. No entanto, se eu tivesse que incluir apenas a peça de dica de ferramenta, estaria aberto a isso. No entanto, não consigo descobrir como fazer isso.

Alguém pode me mostrar como fazer o Bootstrap Tooltip funcionar com o AngularJS?

user2871401
fonte
4
Sem usar o Angular-UI Bootstrap, você precisará fazer todas as ligações para seus eventos. Se você não quiser usar o UI Bootstrap porque ele tem mais do que você precisa, considere carregar apenas as partes de que você precisa: github.com/angular-ui/bootstrap/tree/master/src/popover
TheSharpieOne

Respostas:

151

Para que as dicas de ferramentas funcionem em primeiro lugar, você deve inicializá-las em seu código. Ignorando AngularJS por um segundo, é assim que você faria as dicas de ferramentas funcionarem no jQuery:

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

Isso também funcionará em um aplicativo AngularJS, desde que o conteúdo não seja renderizado pelo Angular (por exemplo: ng-repeat). Nesse caso, você precisa escrever uma diretiva para lidar com isso. Aqui está uma diretiva simples que funcionou para mim:

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');
            });
        }
    };
});

Então, tudo que você precisa fazer é incluir o atributo "tooltip" no elemento em que deseja que a tooltip apareça:

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

Espero que ajude!

aStewartDesign
fonte
Ótima solução! Substituí app.directive por angular.module ('tooltip', []). Diretiva para fazê-lo funcionar em meu aplicativo.
Beanwah
Ótima solução. Podemos adicionar alguns css nele para alterar a dica de ferramenta?
1
Pode adicionar $(element).tooltip({html: 'true', container: 'body'})antes de chamar o show de dica de ferramenta como um exemplo de fornecimento de opções personalizadas.
Vajk Hermecz
1
element.tooltip()pode ser usado em vez de jQuery.
Brian
1
Que resposta bonita
Gimmly
58

A melhor solução que consegui encontrar é incluir um atributo "onmouseenter" em seu elemento como este:

<button type="button" class="btn btn-default" 
    data-placement="left"
    title="Tooltip on left"
    onmouseenter="$(this).tooltip('show')">
</button>
gabeodess
fonte
1
Boostrap JS é uma biblioteca jQuery. Pelo menos estava no Bootstrap 3.
gabeodess
1
Funciona com Angular 2+ também. Obrigado!
Songtham T.
32

Resposta simples - usando UI Bootstrap ( ui.bootstrap.tooltip )

Parece haver um monte de respostas muito complexas para essa pergunta. Aqui está o que funcionou para mim.

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

  2. Injetar UI Bootstrap como uma dependência - angular.module('myModule', ['ui.bootstrap']);

  3. Use a diretiva uib-tooltip em seu html.


<button class="btn btn-default"
        type="button"
        uib-tooltip="I'm a tooltip!">
     I'm a button!
</button>
Derek Soike
fonte
2
Sem jQuery, usando Angular puro e ui-bootstrap; Isso é o que eu estava procurando, obrigado
Rsh
A única solução que funcionou para mim. Obrigado! (@Kondal - sim, funciona sem jQuery).
Nick Grealy
28

Se você está construindo um aplicativo Angular, pode usar jQuery, mas há muitos bons motivos para tentar evitá-lo em favor de paradigmas mais angulares. Você pode continuar a usar os estilos fornecidos pelo bootstrap, mas substitua os plug-ins jQuery pelo angular nativo usando o UI Bootstrap

Inclua os arquivos Boostrap CSS, Angular.js e 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>

Certifique-se de que você injetou ui.bootstrapao criar seu módulo assim:

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

Então você pode usar diretivas angulares em vez de atributos de dados obtidos por 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>

Demonstração no Plunker


Evitando bootstrap de IU

jQuery.min.js (94kb) + Bootstrap.min.js (32kb) também está dando a você mais do que você precisa, e muito mais do que ui-bootstrap.min.js (41kb) .

E o tempo gasto no download dos módulos é apenas um aspecto do desempenho.

Se você realmente deseja carregar apenas os módulos necessários, pode "Criar um Build" e escolher dicas de ferramentas no site Bootstrap-UI . Ou você pode explorar o código-fonte para dicas de ferramentas e escolher o que você precisa.

Aqui, uma construção personalizada reduzida com apenas dicas de ferramentas e modelos (6kb)

KyleMit
fonte
Vale a pena notar que, no momento da escrita, v 0.12.1 é para v1.2 do Angular. o branch 0.13 será para Angular 1.3+, mas o novo mantenedor ainda está trabalhando nisso (e fazendo um ótimo trabalho!)
Nick
11

Você incluiu o Bootstrap JS e 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>

Se você ainda não os carregou, a interface do usuário Angular ( http://angular-ui.github.io/bootstrap/ ) pode não ser muito sobrecarga. Eu uso isso com meu aplicativo Angular e tem uma diretiva de dica de ferramenta. Tente usartooltip="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>
protótipo
fonte
Obrigado @prototype! Eu estava indo para a resposta @gabeodess, mas prefiro esta solução porque ela não diz explicitamente que precisa do jQuery, o que torna isso um pouco menos acoplado e um pouco mais fácil de mudar para uma solução totalmente angular no futuro.
hatchrumandcode
8

Eu escrevi uma Diretriz Angular simples que está funcionando bem para nós.

Aqui está uma demonstração: http://jsbin.com/tesido/edit?html,js,output

Diretiva (para 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'];
    });
  }
});

Nota: Se você estiver usando o Bootstrap 4, nas linhas 6 e 11 acima, você precisará substituir tooltip('destroy')por tooltip('dispose')(Obrigado ao usuário 1191559 por esta atualização )

Basta adicionar bootstrap-tooltipum atributo a qualquer elemento com um title. O Angular monitorará as mudanças no, titlemas, caso contrário, passará a manipulação da dica de ferramenta para o Bootstrap.

Isso também permite que você use qualquer uma das opções nativas de dicas de ferramenta do Bootstrap como data-atributos da maneira normal do Bootstrap.

Markup :

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

Claramente, isso não tem todas as ligações elaboradas e integração avançada que AngularStrap e UI Bootstrap oferecem, mas é uma boa solução se você já estiver usando JS do Bootstrap em seu aplicativo Angular e precisar apenas de uma ponte de dica de ferramenta básica em todo o seu aplicativo, sem modificando controladores ou gerenciando eventos de mouse.

Brandonjp
fonte
1
Tentei usar isso e obtive um Error: cannot call methods on tooltip prior to initialization; attempted to call method 'destroy'erro.
Chris
@CD Hmm ... ainda não consigo reproduzir esse erro. Adicionei este url de demonstração à resposta: jsbin.com/tesido/edit?html,js,output Se você souber a diferença do seu código, me avise e verei se posso ajudar. A propósito, a demonstração está usando Angular v1.2, Bootstrap v3.3, jQuery v2.1
brandonjp
1
Obrigado, este foi o único nestes exemplos que atualiza a dica de ferramenta dinamicamente se o título for alterado por meio de vinculação.
dalcam de
1
BTW para BS4, você deve trocar a linha: element.tooltip('destroy'); com element.tooltip('dispose');em ambos os lugares.
dalcam
4

Você pode usar a selector opção para aplicativos dinâmicos de página única:

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

se um seletor for fornecido, os objetos de dica de ferramenta serão delegados aos destinos especificados. Na prática, isso é usado para permitir que o conteúdo HTML dinâmico tenha dicas de ferramentas adicionadas.

rinat.io
fonte
4

Você pode criar uma diretiva simples como esta:

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

Em seguida, adicione sua diretiva personalizada onde for necessário:

<button my-tooltip></button>
Emanuele Paratore
fonte
3

Você pode fazer isso com AngularStrap, que

é um conjunto de diretivas nativas que permite a integração perfeita do Bootstrap 3.0+ em seu aplicativo AngularJS 1.2+. "

Você pode injetar a biblioteca inteira assim:

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

Ou apenas puxe o recurso de dica como este:

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

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

ilndboi
fonte
2

maneira mais fácil, adicione $("[data-toggle=tooltip]").tooltip();ao controlador em questão.

zied.hosni
fonte
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>

Ravi Kumar
fonte
3
Por favor, acrescente alguma explicação à sua resposta.
André Kool
1

Lembre-se de uma coisa se você quiser usar a dica de ferramenta de bootstrap no angularjs: a ordem dos seus scripts, se você também estiver usando jquery-ui, deve ser:

  • jQuery
  • jQuery UI
  • Bootstap

É experimentado e testado

user6706
fonte
1

Leia isto apenas se estiver atribuindo dicas de ferramentas dinamicamente

ie <div tooltip={{ obj.somePropertyThatMayChange }} ...></div>

Tive um problema com dicas de ferramentas dinâmicas que nem sempre eram atualizadas com a visualização. Por exemplo, eu estava fazendo algo assim:

Isso não funcionou de forma consistente

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

E ativando-o assim:

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

No entanto, como minha matriz de pessoas mudaria, minhas dicas de ferramentas nem sempre eram atualizadas. Tentei todas as soluções neste tópico e em outros sem sorte. A falha parecia estar acontecendo apenas cerca de 5% das vezes e era quase impossível de repetir.

Infelizmente, essas dicas de ferramentas são essenciais para o meu projeto e mostrar uma dica de ferramenta incorreta pode ser muito ruim.

O que parecia ser o problema

O bootstrap estava copiando o valor da titlepropriedade para um novo atributo data-original-titlee removendo a titlepropriedade (às vezes) quando eu ativava as pontas de demais. No entanto, quando meu title={{ person.tooltip }}fosse alterado, o novo valor nem sempre seria atualizado na propriedade data-original-title. Tentei desativar as dicas e reativá-las, destruindo-as, vinculando a essa propriedade diretamente ... tudo. No entanto, cada um deles não funcionou ou criou novos problemas; como os atributos titlee data-original-titlesendo removidos e não vinculados do meu objeto.

O que funcionou

Talvez o código mais feio que já empurrei, mas resolveu esse problema pequeno, mas substancial para mim. Eu executo este código sempre que a dica de ferramenta é atualizada com novos dados:

$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);

O que está acontecendo aqui em essência é:

  • Aguarde algum tempo (1500 ms) para que o ciclo de resumo seja concluído e os titles sejam atualizados.
  • Se houver uma titlepropriedade que não está vazia (ou seja, foi alterada), copie-a para a data-original-titlepropriedade para que seja selecionada pelas dicas de ferramentas do Bootstrap.
  • Reative as dicas de ferramentas

Espero que esta longa resposta ajude alguém que pode estar passando por dificuldades como eu.

Matt
fonte
1

Experimente a dica de ferramenta (ui.bootstrap.tooltip). Consulte as diretivas angulares para Bootstrap

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

Recomenda-se evitar o código JavaScript na parte superior do AngularJS

Asha Joshi
fonte
1

para obter dicas para atualizar quando o modelo muda , eu simplesmente uso em data-original-titlevez detitle .

por exemplo

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

observe que estou inicializando o uso de dicas de ferramentas como esta:

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

versões:

  • AngularJS 1.4.10
  • bootstrap 3.1.1
  • jquery: 1.11.0
zim
fonte
0

AngularStrap não funciona no IE8 com angularjs versão 1.2.9, portanto, não use isso se seu aplicativo precisar ser compatível com o IE8

Tron Diggy
fonte
0

melhorando a resposta de @aStewartDesign:

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

Não há necessidade de jquery, é uma resposta tardia, mas percebi que, uma vez que é a mais votada, devo salientar isso.

aXul
fonte
0

instale as dependências:

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

em seguida, adicione scripts em seu 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"
    ]

então, crie um script.js

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

agora reinicie seu servidor.

Danilo Thiago Alves de Oliveir
fonte
versão angular errada, a pergunta original é sobre AngularJS, não Angular
Jose Luis Berrocal
0

Por causa da função de dica de ferramenta, você deve informar ao angularJS que está usando jQuery.

Esta é a sua diretriz:

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

e é assim que se usa a diretiva:


<a href="#" title="ToolTip!" data-toggle="tooltip" tooltip></a>
Iman Shafiei
fonte