Simple Static Tooltip Widget using jQuery.UI

by mosessaur| 02 August 2008| 13 Comments

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.

Tooltip01 Tooltip02

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

kick it on DotNetKicks.com

Comments

Amr Elsehemy
Amr Elsehemy Egypt on 7/30/2008 6:34 PM Great one mosa keep on it, u are mastering the Jquery Laughing
mosessaur
mosessaur Egypt on 7/31/2008 1:59 AM I don't know, I wish but hard to reach Laughing
And in my next post I'm going back to AjaxControlToolkit collapsible Panel Smile It is fun to move between those things from time to time.
trackback
DotNetKicks.com on 7/31/2008 9:11 AM Trackback from DotNetKicks.com

Simple Static Tooltip Widget using jQuery.UI
sacabonos
sacabonos Egypt on 8/2/2008 10:57 PM Good tutorial mosa, keep up the good work.
mosessaur
mosessaur Egypt on 8/3/2008 12:02 AM @sacabonos Thank you for cheering Smile
Ganesh
Ganesh United States on 9/20/2008 5:37 PM Hi Mosa,
I really like your articles. I was very much impressed by collapsible panel on demand data fetch. I just downloaded the source code and hope to use in my next projects. keep up the great work and again, thank you very much
-Ganesh
mosessaur
mosessaur Egypt on 9/20/2008 5:44 PM @Ganesh Thank you so much and I really appreciate your cheerful comment.
My work is a result of this great community and those who participate to enrich our lives with such useful content. Thank to all of them
Beth Budwig
Beth Budwig United States on 9/28/2008 2:34 AM Excellent script, and it would be just what I'm looking for - if it weren't for having to support IE6 (the thorn in my side).  Do you have any advice on modding your script to work with IE6?  Or should I just be lazy and use another script?  Smile

Thanks, Beth
mosessaur
mosessaur Egypt on 9/29/2008 7:55 AM @Beth I really wished I could help with IE 6. I am not because I don't have IE 6 installed even in VMs so I am not able to test on it or support it.
Davy
Davy United States on 12/9/2008 3:33 PM Works for me in IE6 when implemented as directed in this tutorial.
Jeff
Jeff United States on 12/18/2008 8:22 AM Hey Mosa, Thanks so much for your great work.  I just wanted to point out to other users that with jQuery UI 1.6, you'll need to change the init method name to _init.  I guess this is a new convention with jQuery UI.  It took me a little while to figure out why I couldn't get any of the examples to workSmile
Cheers and thanks again for the great tutorials!

Speed Dating NYC
Speed Dating NYC United States on 1/20/2009 9:08 PM Great script - I will be using it one of my projects that I have a deadline for. Just wanted to give you a thanks before I got to work on it.
pingback
myaspexperience.wordpress.com on 2/24/2009 6:25 AM Pingback from myaspexperience.wordpress.com

a good site for Jquery « My Experiments with Truth

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading