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?
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?
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}}
cricku
February 17, 2017, 8:10am
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.
cricku:
this.$(’[data-toggle=“tooltip”]’).each(function(){
var $elem = $(this);
$elem.tooltip({
placement: ‘top’,
trigger: ‘hover click’,
animation: true,
html: true,
container: $elem
});
});
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 ?!
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?
You’re on the right track! Here’s a reply I made to a similar question:
Here’s my answer. Template.xxx.onRendered is run as soon as all non-reactive parts of the DOM are ready, unless those reactive parts are available immediately. So, taking this template as an example:
<template name="xxx">
<h1>Here's some stuff I found</h1>
{{#each thing in stuff}}
<div>{{thing.a}}, {{thing.b}}
{{/each}}
<p>Hope that's useful</p>
</template>
The onRendered is typically run here:
<h1>Here's some stuff I found</h1>
<p>Hope that's useful</p>
So, the more complex and…
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.