Bootstrap tooltips working in one template, not working in other template


#1

I have a weird problem with bootstrap tooltips.

They work just fine in one of my templates where I have:

in html
<a><i class="fa fa-plus" data-toggle="tooltip" data-placement="top" title="More Info" rel="tooltip"></i></a>

in js

Template.TempA.onRendered(function() {
this.$(’[data-toggle=“tooltip”]’).tooltip({trigger: “hover”,placement: ‘top’});
});

Then I have another tooltip

in html
<a><i class="fa fa-plus" data-toggle="tooltip" data-placement="top" title="More Info" rel="tooltip"></i></a>

in js

Template.TempB.onRendered(function() {
this.$(’[data-toggle=“tooltip”]’).tooltip({trigger: “hover”,placement: ‘top’});
});

The second one doesn’t work…
I tried changing the names, changing the init to work on class or other attributes, all failed.

what am I doing wrong here?


#2

It’s a bit hard to tell without seeing more of your code, maybe if you could paste your whole template here? Everything you’ve given so far looks correct to me. Have you tried putting a console.log or debugger in the onRendered callback to see if this.$('[data-toggle="tooltip"]') returns what you expect? If so, does calling tooltip() on it in the debugger work? If not, maybe your template name is incorrect?


#3

Looks like it’s in the right direction.

console.log(this.$(’[data-toggle=“tooltip”]’))

actually points to (?):

[prevObject: jQuery.fn.init[0], context: div.col-xs-offset-1.col-xs-10.col-sm-offset-2.col-sm-8]

Coming from the layout template wrapping this template

<template name="Layout1">
			<main class="container">
				<div class="row"> 
					<div class="col-xs-offset-1 col-xs-10 col-sm-offset-2 col-sm-8">
						{{> Template.dynamic template=main}}
					</div>
				</div>
			</main>
</template>
FlowRouter.route('/tempB',{
	name:'tempB',
	action(){
		GAnalytics.pageview();
		BlazeLayout.render('Layout1', {main: 'tempB'});
	}
});

In fact, regardless of what I put in the jquery selector I get the same element. I don’t understand why jquery is not returning the right object.

The only difference between TempA and TempB is that TempA is called from a third template using:

{{#each items}}
{{> TempA}}
{{/each}}


#4
Template.TempA.onRendered(function(){
    this.$('[data-toggle="tooltip"]').each(function(){
        var $elem = $(this);
        $elem.tooltip({
            placement: 'top',
            trigger: 'hover click',
            animation: true,
            html: true,
            container: $elem
        });
    });
});

I use it like this on my project.


#5

I think the issue is with rendering. It looks like onRendered in TempB is not finding these elements in the template (which I don’t understand why).
On TempA the #each statement is probably what is causing it to be ready onRendered ?!


#6

I put a workaround in place. It works but it’s ugly.

I just added a wrapping template to the tooltip element.

<template name="wrapper">
<a><i class="fa fa-plus" data-toggle="tooltip" data-placement="top" title="More Info" rel="tooltip"></i></a>
</template>

Then call {{> wrapper}}

Is there a proper way of doing it?


#7

You’re on the right track! Here’s a reply I made to a similar question:

So when you posit that the {{#each}} is making it work, you’re right - because {{#each}} will not render the tempA template unless there’s something to be rendered - and if there’s something to be rendered then your tooltip will work.