Yeats
Yeats

Reputation: 2065

Making tooltips reactive in Meteor

I'm using Bootstrap's own tooltips, which requires some initialization. Someone told me to do it like this:

Template.myTemplate.rendered = function() {
        $('.tooltipped').tooltip()
}

Then I can add tooltips by adding the class tooltipped and some data-tags, here on a Font Awesome icon:

<i class="tooltipped fa fa-square" data-toggle="tooltip" data-placement="top" title="Whatever the tooltip should say"></i>

The problem is that these icons spawn on items as they are dynamically added, and something is keeping the tooltips from working on fresh items. It takes a full reload of the page to get them working.

Googling the issue I found two supposed solutions, none of which is working.

The first solution was to wrap the initializing code inside a Meteor.defer() function, something with which I have no experience and indeed doesn't even show up in the official documents.

Template.myTemplate.rendered = function() {
    Meteor.defer(function() {
        $('.tooltipped').tooltip()
    })
}

This, however, doesn't seem to do anything.

The second solution wasn't really a solution at all, but simply a recommendation to ditch Bootstrap's tooltips and install lookback:tooltips but that was not a very pleasant experience at all (complicated and non-working).

So I'm left with Bootstrap and non-reactivity. Does anyone know how to make it work proper?

Upvotes: 3

Views: 1738

Answers (3)

evolross
evolross

Reputation: 533

Another solution I use is when change(s) in your templates are triggered by buttons/events, you can programmatically destroy and reinitialize your tooltips in the event handlers. This works really well if you have different versions of the same button with different tooltips/disabled settings based on some condition in your data.

Your template:

{{#unless exceededCapacity}}
    <a href="" id="addItemButton" class="add-item" data-toggle="tooltip" data-placement="top" title="" data-original-title="Click here to add items.">Add Item</a>
{{else}}
    <a href="" id="addItemButton" class="add-item" data-toggle="tooltip" data-placement="top" title="" data-original-title="You cannot add any more items." disabled>Add Item</a>
{{/unless}}

Then your event code:

'click .add-item': function(event) {
    event.preventDefault();  

    //  Destroy the tooltips
    $('.add-item').tooltip('destroy');

    //  Code to do your work... e.g insert time

    //  Reinitialize tooltips - this could also be called in an insert callback upon success, etc.
    $('.add-item').tooltip({trigger: 'hover'});

}

Upvotes: 0

Sander Garretsen
Sander Garretsen

Reputation: 1723

So this does not work...

<template name="myTemplate">
  {{#each myTemplateItems}}
    <i class="tooltipped fa fa-square" data-toggle="tooltip" data-placement="top" title="{{whateverTheTooltipShoudSay}}"></i>
  {{/each}}
</template>

Template.myTemplate.onRendered(function() {
  $('.tooltipped').tooltip()
})

The onRendered callback does not get triggered when an item is added to myTemplateItems. This is because the myTemplate is already rendered.

But this should work:

<template name="myTemplate">
  {{#each myTemplateItems}}
    {{>myTemplateItem}}
  {{/each}}
</template>

<template name="myTemplateItem">
  <i class="tooltipped fa fa-square" data-toggle="tooltip" data-placement="top" title="{{whateverTheTooltipShoudSay}}"></i>
</template>

Template.myTemplateItem.onRendered(function() {
  this.$('.tooltipped').tooltip();
})

When a new item is added to myTemplateItems, a new template instance of myTemplateItem gets created, which you can call onRendered on.

Upvotes: 5

Christian Fritz
Christian Fritz

Reputation: 21364

You can simply use a helper in the title attribute. For instance, if you use the default app meteor creates in meteor create then you can just write:

<i class="tooltipped fa fa-square" data-toggle="tooltip" data-placement="top"
   title="{{counter}}"> the text with the tooltip </i>

And you will see how the tooltip changes when the counter button is clicked. This is using a Session variable, which is a perfect example of a reactive data source. But other reactive data sources should work just the same, e.g., a query on a collection.

Caveat: I don't know what happens if the user hovers the item with the tooltip, i.e., in that case the tooltip may not update until the user moves the mouse away and then hovers again.

Upvotes: 1

Related Questions