286
votes

I'm using Twitter bootstrap tooltips with javascript like the following:

$('a[rel=tooltip]').tooltip();

My markup looks like this:

<a rel="tooltip" title="Not implemented" class="btn"><i class="icon-file"></i></a>

This works fine, but I add <a> elements dynamically and the tooltips aren't showing up for those dynamic elements. I know it's because I only bind .tooltip() once when the document is finished loaded with the typical jquery $(document).ready(function() functionality.

How can I bind this to dynamically created elements? Usually I would do this via the jquery live() method. However, what is the event that I use to bind? I'm just not sure how to hook up the bootstrap .tooltip() with jquery .live().

I've found one way to make this work is something like this:

/* Add new 'rows' when plus sign is clicked */
$("a.add").live('click', function () {
    var clicked_li = $(this).parent('li');
    var clone = clicked_li.clone();

    clone.find(':input').each(function() {
        $(this).val('');
    });

    clicked_li.after(clone);
    $('a[rel=tooltip]').tooltip();
});

This works, but seems kind of hackish. I'm also calling the exact same .tooltip() line in the $(ready) call. So, do the elements that exist when the page first loads and match that selector end up with the tooltip twice?

I don't see any problems with this approach. I'm just looking for a best practice or understanding of the behavior.

8
hmm good question, will this help? github.com/twitter/bootstrap/issues/2374Tim
That's an interesting read, but I'm only wanting a single type of tooltip. I just want to make sure any dynamically added elements that match the tooltip selector get added, which isn't the case.durden2.0
Great question. Seems like an oversite on the part of twitter.Luke The Obscure
@durden2.0 How did Christians answer work for you? Care to accept as correct?Ruslans Uralovs
Not really related to your question but... I find it bad style to hijack the rel attribute. This is non-semantic and was originated over a decade ago as a hack. Nowadays, every single browser going back several years supports data-* attributes and there's no more reason not to use them.T Nguyen

8 Answers

521
votes

Try this one:

$('body').tooltip({
    selector: '[rel=tooltip]'
});
155
votes

If you have multiple tooltip configurations that you want to initialise, this works well for me.

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

You can then set the property on individual elements using data attributes.

17
votes

For me, only catching the mouseenter event was a bit buggy, and the tooltip was not showing/hiding properly. I had to write this, and it is now working perfectly:

$(document).on('mouseenter','[rel=tooltip]', function(){
    $(this).tooltip('show');
});

$(document).on('mouseleave','[rel=tooltip]', function(){
    $(this).tooltip('hide');
});
16
votes

I've posted longer answer here: https://stackoverflow.com/a/20877657/207661

TL;DR: You need only one line of code that runs in document ready event:

$(document.body).tooltip({ selector: "[title]" });

Other more complicated code suggested in other answers don't seem necessary (I've tested this with Bootstrap 3.0).

8
votes

For me, this js reproduces the same problem that happens with Paola

My solution:

$(document.body).tooltip({selector: '[title]'})
.on('click mouseenter mouseleave','[title]', function(ev) {
    $(this).tooltip('mouseenter' === ev.type? 'show': 'hide');
});
2
votes

Rather than search it in full Body. One could just use dynamic title option already available in such scenarios I think:

$btn.tooltip({
  title: function(){
    return $(this).attr('title');
  }
});
1
votes

I found a combination of these answers gave me the best outcome - allowing me to still position the tooltip and attach it to the relevant container:

$('body').on('mouseenter', '[rel=tooltip]', function(){
  var el = $(this);
  if (el.data('tooltip') === undefined) {
    el.tooltip({
      placement: el.data("placement") || "top",
      container: el.data("container") || false
    });
  }
  el.tooltip('show');
});

$('body').on('mouseleave', '[rel=tooltip]', function(){
  $(this).tooltip('hide');
});

Relevant HTML:

<button rel="tooltip" class="btn" data-placement="bottom" data-container=".some-parent" title="Show Tooltip">
    <i class="icon-some-icon"></i>
</button>
0
votes

In Bootstrap 5, which doesn't use jQuery, you can do this:

const btn = document.createElement('button');
btn.innerHTML = 'Click me';
btn.dataset['toggle'] = 'tooltip';
btn.dataset['placement'] = 'top';
btn.title = 'Your Tooltip Here';
new bootstrap.Tooltip(btn);

document.getElementById('parent').appendChild(btn);
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-CuOF+2SnTUfTwSZjCXf01h7uYhfOBuxIhGKPbfEJ3+FqH/s6cIFN9bGr1HmAg4fQ" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-popRpmFF9JQgExhfw5tZT4I9/CI5e2QcuUZPOVXb1m7qUmeR2b50u+YFEYe1wgzy" crossorigin="anonymous"></script>
<div id="parent"></div>