Usando Bootstrap Tooltip con AngularJS

90

Estoy tratando de usar la información sobre herramientas de Bootstrap en una aplicación mía. Mi aplicación usa AngularJS Actualmente, tengo lo siguiente:

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

Creo que necesito usar

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

Sin embargo, no estoy seguro. Sin embargo, incluso cuando agrego la línea anterior, mi código no funciona. Estoy tratando de evitar el uso de la interfaz de usuario bootstrap, ya que tiene más de lo que necesito. Sin embargo, si tuviera que incluir solo la información sobre herramientas, estaría abierto a eso. Sin embargo, no sé cómo hacer eso.

¿Alguien puede mostrarme cómo hacer que Bootstrap Tooltip funcione con AngularJS?

usuario2871401
fuente
4
Sin utilizar Angular-UI Bootstrap, deberá realizar todos los enlaces para sus eventos. Si no desea usar UI Bootstrap porque tiene más de lo que necesita, ¿ha considerado cargar solo las partes que necesita: github.com/angular-ui/bootstrap/tree/master/src/popover
TheSharpieOne

Respuestas:

151

Para que la información sobre herramientas funcione en primer lugar, debe inicializarlos en su código. Ignorando AngularJS por un segundo, así es como haría que la información sobre herramientas funcionara en jQuery:

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

Esto también funcionará en una aplicación AngularJS siempre que no sea contenido renderizado por Angular (por ejemplo: ng-repeat). En ese caso, debe escribir una directiva para manejar esto. Aquí hay una directiva simple que funcionó para mí:

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

Luego, todo lo que tiene que hacer es incluir el atributo "información sobre herramientas" en el elemento en el que desea que aparezca la información sobre herramientas:

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

¡Espero que ayude!

aStewartDesign
fuente
¡Buena solución! Reemplacé app.directive con angular.module ('tooltip', []). Directive para que funcione en mi aplicación.
Beanwah
Buena solucion. ¿Podemos agregar algo de CSS para cambiar la información sobre herramientas?
1
Podría agregar $(element).tooltip({html: 'true', container: 'body'})antes de llamar a la descripción emergente como un ejemplo sobre cómo proporcionar opciones personalizadas.
Vajk Hermecz
1
element.tooltip()se puede usar en lugar de jQuery.
Brian
1
Qué hermosa respuesta
Gimmly
58

La mejor solución que he podido encontrar es incluir un atributo "onmouseenter" en su elemento como este:

<button type="button" class="btn btn-default" 
    data-placement="left"
    title="Tooltip on left"
    onmouseenter="$(this).tooltip('show')">
</button>
gabeodess
fuente
1
Boostrap JS es una biblioteca jQuery. Al menos estaba en Bootstrap 3.
gabeodess
1
También funciona con Angular 2+. ¡Gracias!
Songtham T.
32

Respuesta simple : usando UI Bootstrap ( ui.bootstrap.tooltip )

Parece haber un montón de respuestas muy complejas a esta pregunta. Esto es lo que funcionó para mí.

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

  2. Inyecte UI Bootstrap como una dependencia - angular.module('myModule', ['ui.bootstrap']);

  3. Utilice la directiva uib-tooltip en su html.


<button class="btn btn-default"
        type="button"
        uib-tooltip="I'm a tooltip!">
     I'm a button!
</button>
Derek Soike
fuente
2
Sin jQuery, usando Angular puro y ui-bootstrap; Esto es lo que estaba buscando, gracias
Rsh
La única solución que funcionó para mí. ¡Gracias! (@Kondal - sí, funciona sin jQuery).
Nick Grealy
28

Si está creando una aplicación Angular, puede usar jQuery, pero hay muchas buenas razones para tratar de evitarlo en favor de paradigmas más angulares. Puede continuar usando los estilos proporcionados por bootstrap, pero reemplace los complementos de jQuery con angulares nativos usando UI Bootstrap

Incluya los archivos CSS de Boostrap, Angular.js y 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>

Asegúrese de haber inyectado ui.bootstrapcuando cree su módulo de esta manera:

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

Luego puede usar directivas angulares en lugar de atributos de datos recogidos 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>

Demo en Plunker


Evitar Bootstrap UI

jQuery.min.js (94kb) + Bootstrap.min.js (32kb) también le brinda más de lo que necesita, y mucho más que ui-bootstrap.min.js (41kb) .

Y el tiempo dedicado a descargar los módulos es solo un aspecto del rendimiento.

Si realmente desea cargar solo los módulos que necesita, puede "Crear una compilación" y elegir información sobre herramientas del sitio web Bootstrap-UI . O puede explorar el código fuente para obtener información sobre herramientas y elegir lo que necesita.

Aquí una compilación personalizada minificada con solo la información sobre herramientas y las plantillas (6kb)

KyleMit
fuente
Vale la pena señalar que, al momento de escribir, v 0.12.1 es para v1.2 de Angular. la rama 0.13 será para Angular 1.3+ pero el nuevo mantenedor todavía está trabajando en esto (¡y haciendo un gran trabajo!)
Nick
11

¿Ha incluido Bootstrap JS y 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 aún no los ha cargado, es posible que la interfaz de usuario angular ( http://angular-ui.github.io/bootstrap/ ) no requiera mucha sobrecarga. Lo uso con mi aplicación Angular y tiene una directiva de información sobre herramientas. Intenta 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>
prototipo
fuente
¡Gracias @prototype! Iba a buscar la respuesta de @gabeodess, pero prefiero esta solución, ya que no dice explícitamente que necesita jQuery, lo que hace que esto esté un poco menos acoplado y un poco más fácil de cambiar por una solución completamente angular en el futuro.
hatsrumandcode
8

Escribí una directiva angular simple que nos ha funcionado bien.

Aquí hay una demostración: http://jsbin.com/tesido/edit?html,js,output

Directiva (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: Si está utilizando Bootstrap 4, en las líneas 6 y 11 anteriores deberá reemplazar tooltip('destroy')con tooltip('dispose')(Gracias al usuario1191559 por esta actualización )

Simplemente agregue bootstrap-tooltipcomo atributo a cualquier elemento con extensión title. Angular monitoreará los cambios en titlepero, de lo contrario, pasará el manejo de la información sobre herramientas a Bootstrap.

Esto también le permite utilizar cualquiera de las opciones nativas de información sobre herramientas de Bootstrap como data-atributos de la forma habitual de Bootstrap.

Marcado :

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

Claramente, esto no tiene todos los enlaces elaborados y la integración avanzada que ofrecen AngularStrap y UI Bootstrap, pero es una buena solución si ya está usando JS de Bootstrap en su aplicación Angular y solo necesita un puente de información sobre herramientas básico en toda su aplicación sin modificar controladores o administrar eventos del mouse.

brandonjp
fuente
1
Intenté usar esto y obtuve un Error: cannot call methods on tooltip prior to initialization; attempted to call method 'destroy'error.
Chris
@CD Hmm ... Todavía no puedo reproducir ese error. Agregué esta URL de demostración a la respuesta: jsbin.com/tesido/edit?html,js,output Si sabe en qué se diferencia su código, avíseme y veré si puedo ayudar. Por cierto, la demostración utiliza Angular v1.2, Bootstrap v3.3, jQuery v2.1
brandonjp
1
Gracias, este fue el único en estos ejemplos que actualiza la información sobre herramientas dinámicamente si el título cambia mediante el enlace.
dalcam
1
Por cierto para BS4, debe intercambiar la línea: element.tooltip('destroy'); con element.tooltip('dispose');en ambos lugares.
dalcam
4

Puede utilizar la selector opción para aplicaciones dinámicas de una sola página:

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

si se proporciona un selector, los objetos de información sobre herramientas se delegarán a los destinos especificados. En la práctica, esto se utiliza para permitir que se agregue información sobre herramientas al contenido HTML dinámico.

rinat.io
fuente
4

Puede crear una directiva simple como esta:

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

Luego, agregue su directiva personalizada donde sea necesario:

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

Puede hacer esto con AngularStrap que

es un conjunto de directivas nativas que permite la integración perfecta de Bootstrap 3.0+ en su aplicación AngularJS 1.2+ ".

Puede inyectar toda la biblioteca de esta manera:

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

O solo extraiga la función de información sobre herramientas como esta:

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

Demostración en fragmentos de pila

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

forma más fácil, agregue $("[data-toggle=tooltip]").tooltip();al controlador correspondiente.

zied.hosni
fuente
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
fuente
3
Agregue un poco de exageración a su respuesta.
André Kool
1

Recuerde una cosa si desea usar la información sobre herramientas de bootstrap en angularjs es el orden de sus scripts si también está usando jquery-ui, debería ser:

  • jQuery
  • interfaz de usuario de jQuery
  • Bootstap

Está probado y probado

user6706
fuente
1

Lea esto solo si está asignando información sobre herramientas de forma dinámica

es decir <div tooltip={{ obj.somePropertyThatMayChange }} ...></div>

Tuve un problema con la información sobre herramientas dinámica que no siempre se actualizaba con la vista. Por ejemplo, estaba haciendo algo como esto:

Esto no funcionó de manera consistente

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

Y activándolo como tal:

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

Sin embargo, como mi matriz de personas cambiaría, mi información sobre herramientas no siempre se actualizaría. Probé todas las correcciones en este hilo y otros sin suerte. La falla parecía estar ocurriendo solo alrededor del 5% del tiempo y era casi imposible de repetir.

Desafortunadamente, esta información sobre herramientas es fundamental para la misión de mi proyecto y mostrar una información sobre herramientas incorrecta podría ser muy mala.

Cuál parecía ser el problema

Bootstrap estaba copiando el valor de la titlepropiedad en un nuevo atributo data-original-titley eliminando la titlepropiedad (a veces) cuando activaba las sugerencias. Sin embargo, cuando mi title={{ person.tooltip }}cambiara, el nuevo valor no siempre se actualizaría en la propiedad data-original-title. Intenté desactivar la información sobre herramientas y reactivarlas, destruirlas, vincularlas directamente a esta propiedad ... todo. Sin embargo, cada uno de estos no funcionó o creó nuevos problemas; como que los atributos titley data-original-titlese eliminan y se liberan de mi objeto.

Que funciono

Quizás el código más feo que jamás haya introducido, pero resolvió este pequeño pero sustancial problema para mí. Ejecuto este código cada vez que la información sobre herramientas se actualiza con nuevos datos:

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

Lo que está sucediendo aquí en esencia es:

  • Espere algún tiempo (1500 ms) hasta que se complete el ciclo de resumen y titlese actualicen los correos electrónicos.
  • Si hay una titlepropiedad que no está vacía (es decir, ha cambiado), data-original-titlecópiela en la propiedad para que las herramientas de Bootstrap la recojan.
  • Reactivar la información sobre herramientas

Espero que esta larga respuesta ayude a alguien que haya estado luchando como yo.

Mate
fuente
1

Pruebe la información sobre herramientas (ui.bootstrap.tooltip). Consulte las directivas angulares para Bootstrap

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

Se recomienda evitar el código JavaScript en la parte superior de AngularJS

Asha Joshi
fuente
1

para obtener información sobre herramientas para actualizar cuando cambia el modelo , simplemente uso en data-original-titlelugar de title.

p.ej

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

tenga en cuenta que estoy inicializando el uso de información sobre herramientas como esta:

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

versiones:

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

AngularStrap no funciona en IE8 con la versión 1.2.9 de angularjs, así que no use esto si su aplicación necesita ser compatible con IE8

Tron Diggy
fuente
0

improving @aStewartDesign respuesta:

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

No hay necesidad de jquery, es una respuesta tardía, pero pensé que, dado que es el más votado, debería señalar esto.

aXul
fuente
0

instalar las dependencias:

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

a continuación, agregue scripts en su 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"
    ]

luego, crea un script.js

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

ahora reinicie su servidor.

Danilo Thiago Alves de Oliveir
fuente
versión angular incorrecta, la pregunta original es sobre AngularJS no Angular
Jose Luis Berrocal
0

Debido a la función de información sobre herramientas, debe decirle a angularJS que está usando jQuery.

Esta es tu directiva:

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

y así es como se usa la directiva:


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