Fiddle: http://jsfiddle.net/LkqTU/9399/
Code:
var ViewModel = function (first, last) {
var self = this;
self.showIcon = ko.observable(false);
self.triggerIcon = function () {
self.showIcon(true);
};
};
$('.card-delete-button').tooltip({
'placement': 'top',
'title': 'Text'
});
ko.applyBindings(new ViewModel("Planet", "Earth"));
For some reason the tooltip isn't showing up for the '.card-delete-button'. I think it's because that DOM element isn't available until the triggerIcon function is hit. But in application, I have to bind these tooltips to a lot of different elements and would prefer to do it once, in one place, instead of sticking the binding into the triggerIcon function. how can this be achieved?
Your best bet in a situation like this is to create a custom binding that you can use to place tooltips anywhere in the markup.
Here is one implementation of a tooltip binding:
ko.bindingHandlers.tooltip = {
init: function(element, valueAccessor) {
var local = ko.utils.unwrapObservable(valueAccessor()),
options = {};
ko.utils.extend(options, ko.bindingHandlers.tooltip.options);
ko.utils.extend(options, local);
$(element).tooltip(options);
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).tooltip("destroy");
});
},
options: {
placement: "right",
trigger: "click"
}
};
You would then use this binding on your page like:
<input data-bind="value: name, tooltip: { title: help, trigger: 'hover' }" />
You can set options globally and then override them with whatever you pass into the binding.
When you get into templating and control-flow scenarios, using a custom binding really helps, because it will automatically get initialized (and cleaned up) at the right time without needing to manually know when to call code.
Here is a sample: http://jsfiddle.net/rniemeyer/BF5yW/
Addendum to @RP Niemeyer's answer...
On github there is a small project called Knockout-Bootstrap for making "rich two way interactions with Bootstrap and Knockout bindings".
Below is a fork of your fiddle that includes Knockout-Bootstrap.
http://jsfiddle.net/qZkXP/
<div class='liveExample' data-bind="event: {mouseover: triggerIcon}">
<!-- ko if: showIcon -->
<a class="card-delete-button"
data-bind="tooltip: {title: 'Another tooltip', placement: 'right'}">
<i class="icon-trash"></i>
</a>
<!-- /ko -->
</div>
I also encountered some problems regarding the tooltip binding with knockout and the answer offered by RP Niemeyer helped me. But then, when I tried to bind to a function which returns the options object of the tooltip, that wasn't called (it has been called only once). So it was not working if I was trying to dynamically change the title of the tooltip, based on the mapped css classes. So, the solution I found is:
ko.bindingHandlers["tooltip"] = {
'init': function (element, valueAccessor) {
var local = ko.utils.unwrapObservable(valueAccessor());
var options = {};
ko.utils.extend(options, ko.bindingHandlers.tooltip.options);
ko.utils.extend(options, local);
$(element).tooltip(options);
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).tooltip("destroy");
});
},
'update': function (element, valueAccessor) {
var local = ko.utils.unwrapObservable(valueAccessor());
var options = {};
ko.utils.extend(options, ko.bindingHandlers.tooltip.options);
ko.utils.extend(options, local);
$(element).data("bs.tooltip").options.title = options.title;
},
options: {
placement: "top",
trigger: "click"
}};
I wanted to make this remark here because I think it would be useful in those cases when the title of the tooltip has to be changed dynamically.
The answer provided by Adi Mihasan almost worked for me. I had to make the following changes, which may also help others.
$(element).tooltip("destroy");
to
$(element).tooltip("dispose");
AND
$(element).data("bs.tooltip").options.title = options.title
to
$(element).data("bs.tooltip").config.title = options.title