Moses' Blog

Living {.net} lifestyle

Muhammad Mosa

Moses' profile picture
Logo
Software Engineer.
MCT, MCSD.NET,
MCTS: .Net 2.0 Web, Windows, Distributed Applications
MCTS: .Net 3.5 WF Application Development
MCTS: WSS 3.0, MOSS 2007 Configuration & App Dev
MCPD: Enterprise Application Developer

Send mail My Live Space Moses on Facebook Twitter Moses on Technorati

Sponsors



Calendar

<<  January 2009  >>
MoTuWeThFrSaSu
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

View posts in large calendar

Community Credit

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Simple Static Tooltip Widget using jQuery.UI

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

Posted: Aug 02 2008, 15:07 by mosessaur | Comments (11) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: Client Side
Tags: ,
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us

Comments

Add comment


(For Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading