I have extended your plugin: I needed the ability to fill the body of
the tooltip with individual content. So I have set an additional
option: bodyHandler, which can be set to a function reference. Now,
save can handle this:
} else if (settings.bodyHandler) {
tTitle.html(title);
tBody.html(settings.bodyHandler.call(this));
tBody.show();
}
The complete plugin:
/*
* Tooltip - jQuery plugin for styled tooltips
*
* Copyright (c) 2006 Jörn Zaefferer, Stefan Petre
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
/**
* Display a customized tooltip instead of the default one
* for every selected element. The tooltip behaviour mimics
* the default one, but lets you style the tooltip and
* specify the delay before displaying it.
*
* In addition, it displays the href value, if it is available.
*
* To style the tooltip, use these selectors in your stylesheet:
*
* #tooltip - The tooltip container
*
* #tooltip h3 - The tooltip title
*
* #tooltip p.body - The tooltip body, shown when using showBody
*
* #tooltip p.url - The tooltip url, shown when using showURL
*
* @example $('a, input, img').Tooltip();
* @desc Shows tooltips for anchors, inputs and images, if they have a title
*
* @example $('label').Tooltip({
* delay: 0,
* track: true,
* event: "click"
* });
* @desc Shows tooltips for labels with no delay, tracking
mousemovement, displaying the tooltip when the label is clicked.
*
* @example // modify global settings
* $.extend($.fn.Tooltip.defaults, {
* track: true,
* delay: 0,
* showURL: false,
* showBody: " - ",
* fixPNG: true
* });
* // setup fancy tooltips
* $('a.pretty').Tooltip({
* extraClass: "fancy"
* });
$('img.pretty').Tooltip({
* extraClass: "fancy-img",
* });
* @desc This example starts with modifying the global settings,
applying them to all following Tooltips; Afterwards, Tooltips for
anchors with class pretty are created with an extra class for the
Tooltip: "fancy" for anchors, "fancy-img" for images
*
* @param Object settings (optional) Customize your Tooltips
* @option Number delay The number of milliseconds before a tooltip is
display, default is 250
* @option String event The event on which the tooltip is displayed,
default is "mouseover", "click" works fine, too
* @option Boolean track If true, let the tooltip track the
mousemovement, default is false
* @option Boolean showURL If true, shows the href or src attribute
within p.url, default is true
* @option String showBody If specified, uses the String to split the
title, displaying the first part in the h3 tag, all following in the
p.body tag, separated with <br/>s, default is null
* @option String extraClass If specified, adds the class to the
tooltip helper, default is null
* @option Boolean fixPNG If true, fixes transparent PNGs in IE,
default is false
*
* @name Tooltip
* @type jQuery
* @cat Plugins/Tooltip
* @author Jörn Zaefferer (http://bassistance.de)
*/
(function($) {
// define variables and functions
var
// the tooltip element
helper,
// it's title part
tTitle,
// it's body part
tBody,
// it's url part
tUrl,
// the current tooltipped element
current,
// the title of the current element, used for restoring
oldTitle,
// timeout id for delayed tooltips
tID,
// the public plugin method
plugin = $.fn.Tooltip = function(settings) {
// setup configuration
// TODO: allow multiple arguments to extend, see bug #344
settings = $.extend($.extend({}, arguments.callee.defaults),
settings || {});
// there can be only one tooltip helper
if( !helper ) {
// create the helper, h3 for title, div for url
helper = $('<div id="tooltip"><h3></h3><p
class="body"></p><p
class="url"></p></div>')
// hide it at first
.hide()
// move to top and position absolute, to let it
follow the mouse
.css({ position: 'absolute', zIndex: 9500 })
// add to document
.appendTo('body');
// save references to title and url elements
tTitle = $('h3', helper);
tBody = $('p:eq(0)', helper);
tUrl = $('p:eq(1)', helper);
}
// bind events for every selected element with a title attribute
$(this).filter('[EMAIL PROTECTED]')
// save settings into each element
// TODO: pass settings via event system, not yet
possible
.each(function() {
this.tSettings = settings;
})
// bind events
.bind("mouseover", save)
.bind(settings.event, handle);
return this;
},
// main event handler to start showing tooltips
handle = function(event) {
// show helper, either with timeout or on instant
if( this.tSettings.delay )
tID = setTimeout(show, this.tSettings.delay);
else
show();
// if selected, update the helper position when the mouse moves
if(this.tSettings.track)
$('body').bind('mousemove', update);
// update at least once
update(event);
// hide the helper when the mouse moves out of the element
$(this).bind('mouseout', hide);
},
// save elements title before the tooltip is displayed
save = function() {
// if this is the current source, or it has no title (occurs
with
click event), stop
if(this == current || !this.title)
return;
// save current
current = this;
var source = $(this),
settings = this.tSettings;
// save title, remove from element and set to helper
oldTitle = title = source.attr('title');
source.attr('title','');
if(settings.showBody) {
var parts = title.split(settings.showBody);
tTitle.html(parts.shift());
tBody.empty();
for(var i = 0, part; part = parts[i]; i++) {
if(i < 0)
tBody.append("<br/>");
tBody.append(part);
}
tBody.show();
} else if (settings.bodyHandler) {
tTitle.html(title);
tBody.html(settings.bodyHandler.call(this));
tBody.show();
} else {
tTitle.html(title);
tBody.hide();
}
// if element has href or src, add and show it, otherwise hide
it
href = (source.attr('href') || source.attr('src'));
if( settings.showURL && href )
tUrl.html(href.replace('http://', '')).show();
else
tUrl.hide();
// add an optional class for this tip
if( settings.extraClass ) {
helper.addClass(settings.extraClass);
}
// fix PNG background for IE
if (settings.fixPNG && $.browser.msie ) {
helper.each(function () {
if (this.currentStyle.backgroundImage !=
'none') {
var image =
this.currentStyle.backgroundImage;
image = image.substring(5, image.length
- 2);
$(this).css({
'backgroundImage': 'none',
'filter':
"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,
sizingMethod=crop, src='" + image + "')"
});
tPNGfix = true;
}
});
}
},
// delete timeout and show helper
show = function() {
tID = null;
helper.show();
},
/**
* callback for mousemove
* updates the helper position
* removes itself when no current element
*/
update = function(event) {
// if no current element is available, remove this listener
if( current == null ) {
$('body').unbind('mousemove', update);
return;
}
// get the current mouse position
function pos(c) {
var p = c == 'X' ? 'Left' : 'Top';
return event['page' + c] || (event['client' + c] +
(document.documentElement['scroll' + p] || document.body['scroll' +
p])) || 0;
}
// position the helper 15 pixel to bottom right, starting from
mouse position
helper.css({
top: pos('Y') + 15 + 'px',
left: pos('X') + 15 + 'px'
});
},
// hide helper and restore added classes and the title
hide = function() {
// clear timeout if possible
if(tID)
clearTimeout(tID);
// no more current element
current = null;
helper.hide();
// remove optional class
if( this.tSettings.extraClass ) {
helper.removeClass( this.tSettings.extraClass);
}
// restore title and remove this listener
$(this)
.attr('title', oldTitle)
.unbind('mouseout', hide);
// remove PNG background fix for IE
if( this.tSettings.fixPNG && $.browser.msie ) {
helper.each(function () {
$(this).css({'filter': '', backgroundImage:
''});
});
}
};
// define global defaults, editable by client
plugin.defaults = {
delay: 250,
event: "mouseover",
track: false,
showURL: true,
showBody: null,
bodyHandler: null,
extraClass: null,
fixPNG: false
};
})(jQuery);
Would be nice, if you accept this extension :)
Mathias
_______________________________________________
jQuery mailing list
[email protected]
http://jquery.com/discuss/