Want to get Lullabot article, videocast, and podcast announcements delivered right to your in-box?
Let us know your email address (we won't share it) and we'll let you know when anything exciting happens.
Announcing BeautyTips, a jQuery Tooltip Plugin
Well I've done it! I've written my first jQuery plugin. The plugin creates rollover balloon-help style tooltips for any element on your page. While there were a few different tool tips plugins that existed for jQuery, none of them seemed to quite meet my need for a NetFlix (or Google Maps) style talk-balloon popup.
It quickly became apparent that in order to accomplish this type of flexible talk-balloon tooltips, I was going to need to engage the use the HTML 5 canvas element (and a lot of high-school algebra and trigonometry). The result is BeautyTips, a flexible and smart tooltip which calculates the best position for each tooltip bubble and then draws it. Bubbles can have rounded corners with a variable corner radius, "spike" length, color, opacity, and much more.
The canvas element is supported in modern versions of Firefox, Safari, and Opera. However, Internet Explorer needs a separate library called ExplorerCanvas included on the page in order to support canvas drawing functions. ExplorerCanvas was created by Google for use with Google Maps and several of their other web apps. Include it on the page according to the readme file and BeautyTips should work just fine in IE.
Beauty Tips was written to be simple to use and pretty. All of its options are documented at the bottom of the jquery.bt.js file and defaults can be overwritten globally for the entire page, or individually on each call.
By default each tooltip will be positioned on the side of the target element which has the most free space. This is affected by the scroll position and size of the current window, so each Beauty Tip is redrawn each time it is displayed. It may appear above an element at the bottom of the page, but when the page is scrolled down (and the element is at the top of the page) it will then appear below it. Additionally, positions can be forced or a preferred order can be defined.
Each tip's position is determined based on its size and the available space around the target.
Visit the DIWD schedule to see how it works.
Usage
The function can be called in a number of ways.
$(selector).bt();
$(selector).bt('Content text');
$(selector).bt('Content text', {option1: value, option2: value});
$(selector).bt({option1: value, option2: value});
Some examples:
$('[title]').bt();
This is probably the simplest example. It will go through the page finding every element which has a title attribute and give it a Beauty Tips popup which gets fired on hover.
$('h2').bt('I am an H2 element!', {
trigger: 'click',
positions: 'top'
});When any H2 element on the page is clicked on, a tip will appear above it.
$('a[href]').bt({
titleSelector: "attr('href')",
fill: 'red',
cssStyles: {color: 'white', fontWeight: 'bold', width: 'auto'},
width: 400,
padding: 10,
cornerRadius: 10,
animate: true,
spikeLength: 15,
spikeGirth: 5,
positions: ['left', 'right', 'bottom'],
});This will find all <a> tags and display a red baloon with bold white text containing the href link. The box will be a variable width up to 400px with rounded corners and will fade in and animate position toward the target object when appearing. The script will try to position the box to the left, then to the right, and finally it will place it on the bottom if it does not fit elsewhere.
$().bt.defaults.fill = 'rgba(102, 102, 255. .8)';
$(selector).bt();All bubbles will be filled with a semi-transparent light-blue background unless otherwise specified.
Live Demo
We've got a good example of BeautyTips in action over on the Do It With Drupal schedule. Resize your window and scroll the page up and down to see how the tips move around to accommodate.
Get it!
There are still a few buggy options such as the animation in IE (it's always IE, isn't it?). And I have yet to figure out how to submit the plugin to jquery.com. But I'm really proud of what I've got so far, so I thought I'd share it here.
A complete list of options are available at the end of file. Enjoy!
| Attachment | Size |
|---|---|
| jquery.bt.js | 33.71 KB |






Comments
Nice work! Perhaps
Nice work!
Perhaps http://www.nickstakenburg.com/projects/prototip2/ could be ported over from prototype, it has some pretty options :)
Robin
I totally love it!
Needed this a couple of weeks ago. Would have saved me days.
much impressed!
This is a great contribution. if I could send you a beer, I'd be doin' that now.
Nice Work
Very nice work. I'm thinking this would be very cool to incorporate into forms as a new way to emphasize help text. It's much more apparent then small text below input fields.
Food for thought.
Code?
Nice idea, but that code needs some serious love... it repeats itself all over, both on a statement level as well as a block level. Also a bit puzzled as to why you'd put the defaults in jQuery.fn rather than just jQuery.
Finally, the name .bt() seems unnecessarily short and confusing.
Robin, Prototip is licensed
@Robin, Prototip can't be ported, it's against the license. No derivative works are allowed, so you may not alter, transform, or build upon it.
Awesome
Looks great! And I can't wait to show my kids what you can do with high-school algebra :).
Great job!
Hey Jeff,
Great job with the plugin. I haven't looked at the code yet, but the tips themselves are really pretty. My favorite feature is the spikes. Very nice.
I've written a tooltip plugin, too, called clueTip. Lots of options, but no canvas. One nice thing about it is that it can populate the tooltip with contents from a variety of sources -- another file (via ajax), another element on the page, the title attribute of the invoking element, a string, a function, whatever. Please excuse the shameless self-promotion, but I thought you might like to take a look. Feel free to take anything from it that you find useful.
To list your plugin in the jQuery plugin repository, go to http://plugins.jquery.com/ (it uses Drupal) and register. I think it uses the Project module, so it'll probably be pretty familiar to you. But if you run into any problems, let me know and I'll make sure we get you set up.
P.S. Not sure if you remember me, but we met last year at jQuery camp ("JonBob" introduced us). Missed you this year!
Should have looked at the code
Okay, so now I feel kind of silly. If I had looked at the code first, I would have known that you were already aware of my plugin. :)
Hi Karl!
Yes, of course I remember you. I've got your book sitting right here. And clueTip is awesome! I was really inspired by all of the options you added to that plugin and I'm sure that you can see some similarities looking at my code -- and probably some rookie mistakes. :-)
I actually started out thinking that I would just do this as some sort of an add-on to clueTip, but when I started getting all caught up in the canvas stuff, it started seeming too hard to stay in sync with clueTip, so I decided to just let go and basically write the new plugin from scratch.
The ajax stuff is still fun to have and when I can come up with a personal use case for that, I'll probably comb through clueTip and figure out how you're doing that magic!
Likewise, feel free to move any of this code into clueTip if you think it can be done.
And for anyone else that wants to help clean up this code, help make it more efficient, more compatible, or just generally better, I'm open to it. I'll post a link to the jQuery.com project page when I get a chance to create it.
Congrats
Wonderful plugin! I'll definitely be making use of this.
You know you can EASILY
You know you can EASILY create balloons like that with CSS....
Great! But one small thing?
Hi, this is a great tooltip but there's one small problem.
I am forced to develop for IE6 (yes, yes... I know) and the tooltips appear under a select box.
What's the best way to have the tooltip check to see if it covers a select box, and if so, hide that select box until the tooltip is gone?
JS/jQuery is not my strength at all.
Many thanks for your hard work.
use bgiframe plugin
Hi Bradley,
You can use the bgiframe plugin.
The above
Thanks :-)
Thanks Karl
Thanks for that Karl. However, I can't seem to get it working. I'm using bt() like this:
<label for="projectno" class="helpLink" title="Help text for pop up goes here">Project No</label>Then my bt() is set up using livequery like this:
$(document).ready(function () {
$('.helpLink').livequery(
function()
{$(this).bt();}
);
}
I've tried:
$('.helpLink').livequery(function()
{$(this).bgiframe();}
);
and...
$('.bt-wrapper').livequery(function()
{$(this).bgiframe();}
);
and
$('.bt-content').livequery(function()
{$(this).bgiframe();}
);
but none of it works.
As I said I'm new to jQuery and DOM manipulation so I'm having trouble figuring it out.
Can you give me a pointer?
Cheers,
Brad
Well, well,,,well! It's
Well, well,,,well!
It's great!
Really great jQuery
Really great jQuery plugin.
Thanks.
Btw,
maybe you could contribute that module to jquery.com site ?
Why did you not just style
Why did you not just style http://onehackoranother.com/projects/jquery/tipsy/
differently? not to mention it is a bad practice to have style data within your javascript aka the configuration object in your example.
PLUS tipsy is an elegant 57 lines...
nice
Nice tool, I will add it to my site.
Thanks so much .
How to add help text..
Really cool plugin, just what I needed for my little project.
But I can't figure out how to set "help text", I use the script to make tool tips for my input fields and would like to have it say: "please write email", instead of just "email".
my code looks like:
jQuery('input').bt({titleSelector: "attr('name')",
fill: 'white',
cssStyles: {color: 'black', fontWeight: 'bold', width: 'auto'},
width: 400,
padding: 10,
cornerRadius: 5,
animate: true,
spikeLength: 10,
spikeGirth: 15,
positions: ['right', 'left', 'bottom'],
});
and how will I, if my request is possible, set different help text to different names?
Thanks in advance
Well there's yer problem right there! :-)
There are two ways of calling the bt() function,
1) You can send it specific content text, as follows:
$('selector').bt('This is the help text', {fill: 'white'});2) You can have it auto-discover content text. This is usually for grabbing the title text of each of what could be a long list of elements. In this case, you omit the first argument and just send options (or no arguments).
$('a[title]').bt({fill: 'white'});Using method #1 would solve your problem. The other solution to your problem is to add a "title" attribute to your input fields. You should also probably add an id or class to them while you're there so that you can select them more easily. The problem that you're experiencing is that the "name" attribute doesn't understand the space character in its values, so what you are getting is the last "item" after the last space in the name value: the word "email". I'm guessing your form processing script will choke on this too.
If you move your help text into <input title="my help text" ... >, then you could do the following:
$('#myform input[title]').bt({trigger: ['focus', 'blur'], fill: 'white', option2: 'etc'});This would find all of the input elements in your form which posses a title attribute and add the BeautyTips behavior to them showing the help balloon when they get the field gets focus and removing it when the field loses focus. This means the balloon would show up even if the user tabs into the field (without clicking their mouse).
Cool, huh!?
Thanks for that nice walk
Thanks for that nice walk trough Jeff! It really helped me. I think I can figure the rest out now... But it would be nice is the the author had mad and commandlist so that we knew what was able and what wasn't :)
helpful change
I tied your plugin into the form validation function to have the errors show up as tooltips (as opposed to additional labels). I ran into a little bit of trouble when I had to remove the tooltips (once the input field has a valid value).
I added the following to line 138, which essentially just adds a "remove" option. Really simple, obviously, since you've already written the "turn off" code, however this opens that up to the public.
if(opts.remove){
turnOff.apply(this);
return true;
}
IE7 and BT
Doesn't work in IE7 with default options? Get an error on line 398
RE: IE7 and BT
IE doesn't support the
canvaselement yet, which is why you're seeing that error.ExCanvas
Yes, please read above. You'll need to include ExCanvas in order to get IE compatibility.
Syntax error
I have tried numerous ways to get your plugin working, including several Drupal plugin handlers, yet I keep getting the error message :
"Parse error: syntax error, unexpected '(', expecting T_VARIABLE or '$' in C:\xampp\htdocs\xampp\d6_pc08\includes\common.inc(1547) : eval()'d code on line 6"
I'm guessing there is something obvious that I am not doing or dumb that I am doing. Nevertheless, I would appreciate a little help.
Troubles getting this going
Hi Jeff (or anyone here who can help),
I've tried all the helpful examples, but I keep getting an error of:
opts.trigger is undefined on line 500
Am I missing something?
Cheers,
Chris.
just thought I would post
just thought I would post that I figured out what my issue was. I was using an older version of jQuery that didn't like BeautyTips.
Nice
Just what I was looking for. Actually, what I really wanted was something like the task bar notifications in Vista, but I was able to accomplish this with the simple addition of a setTimeout() with jQuery's fadeOut().
Something like:
$("#next").bt("Hello World", {positions: "top",
trigger: "now"
});
setTimeout("$('.bt-wrapper').fadeOut(2000)", 2000);
Might be nice to have an option for something like this in the lib (seeing how easy it is to add).
This is great plugin. So I
This is great plugin.
So I wanna use tip from a other tag like , not in title attr, does this supported?
It works with image maps only in Firefox 3
Any clues how to get it work with image maps?
Image Maps!
Wow. Image maps! Old skool!
This isn't really a BeautyTips issue so much as an image maps and jQuery issue. You should be able to use any DOM element as a target. I would test it out by giving each <area> element a CSS id and then try something like this:
$('#area57').bt('Hello from Area 57');I'm guessing that should work. But it's been a long time since I've had occasion to use an image map.
More questions for IE
It looks that collection based filters don't work in IE either. Named #id does.
$('[title]').bt(); does not work!?
$('a').bt(); does not either.
The same page works in FF3.
$('#myid').bt(); does work.
I tried to download Visual Express so that I took a look in IE debuuger. That piece of junk is installing for the past hour so I canceled.
What do you replace the image maps with? It's true I'm on the server side and my first image map was in '97.
Thanks.
Unnecessary btx-title added to element
I have a list item innerHTML wrapped in a SPAN tag.
The UL has four LI.
The SPAN tag of the fist LI gets a btx-title attribute added resulting in overlapped tooltips.
FF3.
It's the animate option that messes with IE7
When the animate option is removed, the IE7 displays the tooltip fine.
The problem with the AREA / MAP remains as well as the duplicate tooltip for the
<li><span>text</span></li>.Absolute positioned DIV-s probelm in IE7
Your plugin is great. I try to use it in my calendar project. There are normal, and absolute positioned DIVs for the daily events. Everything is working fine in FF of course :) But in IE7 not. The "balloons" appearing correctly on the normal positioned DIVs, but on the absolute positioned DIVs not. There is no balloons at all.
What could be the problem? Do you have any suggestion.
Finally a tip for everyone. I have changed this line:
//content = eval('$(this).' + opts.titleSelector);
to this one:
content = eval(opts.titleSelector);
In this case you can refer by ID to any of the HTML elements on the site. For example another DIV. The DIV content will be displayed in the balloon. (not the title of the element)
Ha!
I'm glad others are thinking the same thing I am. I had already changed the eval() line exactly as you did. I have a new version of the plug-in with MANY changes that I will be uploading in the next week or so.
As for the absolutely positioned DIVs in IE, would it be possible for you to put up an example somewhere?
Waiting for the next rel
Hi there Jeff,
OK, I'm waiting for the next release :)
I try to make you an example page.
Balloon not fully rendering
First let me just say that I love this plug in. However, I created a small test page to see if I could make this work the way I wanted and everything was perfect except that the back of the balloon didn't render so it appears truncated. The arrow displays as does the nicely curved front of the balloon but not the back. All of the text displays but that's it and the back is perfectly straight. I'm hoping this the result of my being terminally stupid and there's something simple I'm doing wrong. I tested this in IE 7 and FF 3 and both did the same thing. Any help would be appreciated.
Screen shot?
I'm not sure I'm quite understanding what's happening. Can you post a link to a screen shot and also the code you're using to generate the balloon?
trouble
i keep getting js error
$(this).attr("bt-xTitle", $(this).attr("title")) is undefined
any ideas??
thank's for probably the
thank's for probably the greates jQuery tooltip plugins, it's realy gooood job, thank's one more........
Compatibility Problem
I really like your beautytips and will be using them in my next project. Just one thing - their appears to be a positioning problem when used with jquery.dimensions. Tried to work out the problem, but my high school math was a long time ago.
A bug fixing
Jeff,
I found a small bug.
Symptom: The ballons sometimes stick on the screen and do not want to dissapear.
Here is the bug fix for this (if someone else need it):
Place this line:
$(".bt-wrapper").remove();
After the row immediatelly:
var turnOn = function () {
I could not find a solution for the floating DIV-s problem under IE7... I'm still investigating :)
a bug
I didn't read all the comments, so I might be repeating a known issue. In that case I am sorry to bother you :)
So the bug: I used "overlap: 5," and when you position mouse cursor on the part of the div that overlaps with the baloon stem the baloon starts flickering. Depends on cpu speed(more speed faster flicker). Quite annoying.
So for now I just removed overlap and its ok.
Otherwise - great plugin. My usage case is quite similar to the demo :) Anyway, I was searching for this kind of a plugin for days and I have found yours that does the job really nicely :) I kinda miss the ability to place some input fields in the ballon (google style), but hey, you can't have everything...
Very Nice
Implemented it on my project without much of a problem. Works great. Good Job, the 'now' trigger really sealed the deal for me, I didn't find any other tooltips that offered that.
added support for HTML content in tooltip
Thanks for a great plugin. We wanted to put html content from a hidden div into the displayed tooltip so I made a few changes:
line 104: (fixed typo)
* $().bt.defaults.fill = 'rgba(102, 102, 255, .8)';
line 147: (first and last lines are same. Inserted middle three lines.
content = eval('$(this).' + opts.titleSelector);
if( opts.evalTitle )
{ content = eval( content ); // eval it to get whatever from the page. E.g. HTML markup from some div: $('#toolTipEC').html()
}
if (opts.killTitle) {
line 805: added a comma. Added line 806
postHide: function(){return;}, // function to run after popup is removed
evalTitle: false // false displays string in tip, true evals it and displays the results.
Usage example: cannot get the HTML through but basically do this in a div:
title="$('#toolTipEC').html()"
And make your wonderful HTML in the div id'ed as toolTipEC.
Thanks again!
TimJowers
DIV issue... css eval
By "Cannot get the HTML through" I meant the discussion forum is hiding it when I try to post the example.
Callback
Awesome plugin, I'm a bit of a jQuery noob, and was trying to figure out if there was any sort of a callback function for after the tooltip has been executed, I'm trying to set up a cookie of some sort that will not make the user see the tool tip if it has fired once.
Thanks!
Post new comment