I've seen different type of tooltips around. And actually jQuery tooltip plugin was one of the best I ever seen. And then I thought to build some tooltip similar to those tooltips available on asp.net learning items. Just simple one to be displayed on left or right of the tooltiped item (element). And I decide to build that using jQuery.ui widgets.
Very simple and straight forward, all I needed is the following:
- A tooltip fully UI customizable to be displayed to the right or left of the desired element. And it should detect if the desired element is closer to right or left on the screen; so the tooltip to be displayed correctly to the right or left of the element.
- Ability to control when the tooltip to be displayed, on hover or focus on the element or manually using tooltip widget methods such show and hide.
- Callback upon on show and hide of the tooltip.
- Optional fancy show/hide animations.
I built a sample which you can download to demonstrate how this tooltip should work and you can view the demo here.
Before go through the code, I recommend first to read the following posts:
So, I'll start with init function, where I register for hover/out events or focus/blur events. The handlers are functions that do not belong to the widget itself:
init: function() {
if(this.options.mode == 'hover'){
//Register for hover events
$(this.element).hover(hoverHandler,outHandler);
}
else if(this.options.mode == 'focus'){
//Register for focus/blur events
$(this.element).focus(hoverHandler);
$(this.element).blur(outHandler);
}
else if(this.options.mode == 'manual'){
}
}As you noticed, there are 2 handler functions
hoverHanlder and
outHandler. Where are exactly these function declared and defined? Best thing is to show you this through the code:
(function($) {
$.widget("ui.tooltip", {
init: function() {
//Code Here
},
show: function(){
//Code Here
},
hide: function(){
//Code Here
}
});
function hoverHandler(event){
//Handler Code
};
function outHandler(event){
//Handler Code
};
function someOtherFunction(parameter){
//Code Here
};
//....
})(jQuery);It worth to mention that those function are of the widget context. Means you cannot access widget properties such as
element or
options directly from within those functions using syntax like this
this.options or
this.element. However they are still accessible but in another way. Later I'll explore these functions and see how widget properties are accessed through them.
This tooltip has 7 options. Actually I implemented and using only 4 of them. The other 3 are related to animations which I didn't complete so far. But they will take just few minutes to be archived.
$.extend($.ui.tooltip, {
defaults: {
//ID of the element that will be used as Tooltip in form '#elementID'
tooltip: '',
//Show Callback
onShow: undefined,
//Hide Callback
onHide: undefined,
//Tooltip mode, hover,focus or manual
mode: 'hover',
// provide a speed for the animation
speed: 1000,
// provide a period for the popup to keep showing
period: 2000,
// default the animation algorithm to the basic slide
animation:'slide'
},
animations: {
slide: function(e, options) {
//Slide Animation Implementation
},
fade: function(e, options) {
//Fade Animation Implementation
}
}
});From the above code, I didn't implement any slide or fade animations, but I declared them because I had a plan to do so. And I will one day :o)
As shown earlier, the widget contains 2 public methods show and hide. Their implementation is very simple and straight forward as the following:
$.widget("ui.tooltip", {
init: function() {
//Code....
},
show: function(){
var o = this.options;
if(o.mode=='manual'){
prepare(this.element,o);
}
$(o.tooltip).show();
},
hide: function(){
var o = this.options;
$(o.tooltip).hide();
}
});You might noticed the
prepare function call. This is a helper function that accepts the tooltiped element and the options. It prepares the positioning of the tooltip. It is used here when the
mode is
manual, as the tooltip will be shown only upon manual call to
show method. And it will be used again in the
hoverHandler function. The implementation of this method will be shown below.
Below is how the handlers are implemented. There are few pieces of code that deal with positioning but to be honest, I'm not sure if this is a proper way to do such thing or not. Anyway it was working fine on all browsers (IE 7.0, FF 3.0.1, Opera 9.51 and Safari 3.1.2) so let's just dive and see what we can catch.
function hoverHandler(event)
{
//Fetch Options
var o = $.data(this,'tooltip').options;
//Element who raised the event
var $this = $(this);
//Helper functon for Positioning and Calling Callback function
prepare($this,o);
//Call Show method of the tooltip Widget,
//Show method should play on any required animations
$.data(this,'tooltip').show();
};
function outHandler(event)
{
//Fetch Options
var o = $.data(this,'tooltip').options;
//Get tooptip Element
var $tooltip = $(o.tooltip);
//If call back method defined, initiate the call
if($.data(this,'tooltip').options.onHide){
$.data(this,'tooltip').options.onHide.call(this, {target:$(this)});
}
//Call Hide method of the tooltip Widget,
//Hide method should play on any required animations
$.data(this,'tooltip').hide();
};
function prepare(jObj, options)
{
var $tooltip = $(options.tooltip);
var element = jObj[0];
var offset = jObj.offset();
var left = offset.left + jObj.width();
var top = offset.top-5;
if(options.onShow){
options.onShow.call(this, {target:jObj});
}
if($(window).width()-offset.left <= $tooltip.width()) {
left = offset.left - $tooltip.width();
}
else{
left += 5;
}
$tooltip.css({position:'absolute', top:top+'px', left:left+'px'});
};Time to see how do we instantiate the tooltip. The attached sample provide 3 demonstrations; one for focus, another one for hover and final one for manual shoe/hide of the tooltip. And this last one uses jQuery AJAX call to display some RSS feeds.
The design of your tooltip is up to you. I'll explore how to instantiate the tooltip and provide callbacks.
$(document).ready(function(){
//Focus
$('#leftsection input').tooltip({tooltip:'#tooltip',mode:'focus',onShow:onShow});
//Hover
$('#rightsection input').tooltip({tooltip:'#tooltip',mode:'hover',onShow:onShow});
//Manual using ajax
$('#avatar').tooltip({tooltip:'#avatarTooltip',mode:'manual',onShow:onShow});
$('#avatar').click(showRss);
$('#close').click(hideRss);
});Yes that is it! I just select the element I want to show a tooltip for. Then I specify the tooltip element as parameter for
tooltip option. I defined the mode on each example as well as onShow callback. And they all share the same callback. I actually use callback here for just CSS manipulation nothing more.
Below is the code for onShow callback
//onShow handler for correct positioning.
function onShow(sender)
{
//Filpping arrow and text
var $tooltip = $('#tooltip');
//Switch styles based on how close to viewport border
if($(window).width()-sender.target.offset().left <= $tooltip.width()) {
$('.tooltiptextleft',$tooltip).removeClass('tooltiptextleft').addClass('tooltiptextright');
$('.tooltiparrowleft',$tooltip).removeClass('tooltiparrowleft').addClass('tooltiparrowright');
}
else{
$('.tooltiptextright',$tooltip).removeClass('tooltiptextright').addClass('tooltiptextleft');
$('.tooltiparrowright',$tooltip).removeClass('tooltiparrowright').addClass('tooltiparrowleft');
}
} showRss and
hideRss function:
function showRss(event)
{
var $tooltip = $('.content','#avatarTooltip');
var count = 5;
var feedName = 'Encosia';
var params = '{count:'+ count +', feedName:"'+feedName+'"}';
$('#ajaxloading').css({position:'absolute',top:event.clientY,left:event.clientX});
$('#ajaxloading').show();
//Issue AJAX Call
$.ajax({
type: "POST", //POST
url: "Default.aspx/GetFeedburnerItems", //Set call to Page Method
data: params, // Set Method Params
cache:false,
beforeSend: function(xhr) {
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
xhr.setRequestHeader("Content-length", params.length);},
contentType: "application/json; charset=utf-8", //Set Content-Type
dataType: "json", // Set return Data Type
success: function(msg, status) {
$('#ajaxloading').hide();
$tooltip.html(msg.d);
//Call of show function manually
$('#avatar').tooltip('show');
},
error: function(xhr,msg,e){
alert(msg);//Error Callback
}
});
}
function hideRss(event)
{
//Call of hide function manually
$('#avatar').tooltip('hide');
};I guess I've mentioned everything in my mind right now. And you can
download the sample or
view the demo. Maybe you wish to implement some animations, so it your turn to provide some and check how do they look like. I guess fading would be the best animation to provide.
Download Sample | View Demo
