Recently I had to migrate a big web application from Wicket 1.1.1 to 1.2.1. I was using the contrib-dojo Tooltip class, which doesn't work with 1.2, so I had to find another solution. I found Igor's suggestions for tooltips and chose to go with "Sweet Titles".
Sweet titles is great, but the problem is that it automatically attaches tooltips to all <a>, <abbr> and <acronym> tags (correct me if I'm wrong, but I am sure about the <a> tag). I didn't want that, though. I needed tooltips for checkboxes, and I needed to explicitly say which element should show a tooltip and which element shouldn't. So I altered the sweetTitles.js a bit and this is what I came up with:
A quick and hopefully easy guide that will show you how to use pretty tooltips on your Wicket pages.
Download SweetTitles
Replace sweetTitles.js with this one:
/*
Sweet Titles (c) Creative Commons 2005
http://creativecommons.org/licenses/by-sa/2.5/
Author: Dustin Diaz | http://www.dustindiaz.com
Edited by Johannes Fahrenkrug. The script now honors the showtooltip attribute
*/
var sweetTitles = {
xCord : 0, // @Number: x pixel value of current cursor position
yCord : 0, // @Number: y pixel value of current cursor position
tipElements : ['input', 'td', 'tr', 'textarea', 'select', 'span', 'div', 'a','abbr','acronym'],
// @Array: Allowable elements that can have the toolTip
obj : Object, // @Element: That of which you're hovering over
tip : Object, // @Element: The actual toolTip itself
active : 0, // @Number: 0: Not Active || 1: Active
init : function() {
if ( !document.getElementById ||
!document.createElement ||
!document.getElementsByTagName ) {
return;
}
var i,j;
this.tip = document.createElement('div');
this.tip.id = 'toolTip';
document.getElementsByTagName('body')[0].appendChild(this.tip);
this.tip.style.top = '0';
this.tip.style.visibility = 'hidden';
var tipLen = this.tipElements.length;
for ( i=0; i<tipLen; i++ ) {
var current = document.getElementsByTagName(this.tipElements[i]);
var curLen = current.length;
for ( j=0; j<curLen; j++ ) {
if (current[j].getAttribute('showtooltip') == 'true') {
addEvent(current[j],'mouseover',this.tipOver);
addEvent(current[j],'mouseout',this.tipOut);
current[j].setAttribute('tip',current[j].title);
current[j].removeAttribute('title');
}
}
}
},
updateXY : function(e) {
if ( document.captureEvents ) {
sweetTitles.xCord = e.pageX;
sweetTitles.yCord = e.pageY;
} else if ( window.event.clientX ) {
sweetTitles.xCord = window.event.clientX+document.documentElement.scrollLeft;
sweetTitles.yCord = window.event.clientY+document.documentElement.scrollTop;
}
},
tipOut: function() {
if ( window.tID ) {
clearTimeout(tID);
}
if ( window.opacityID ) {
clearTimeout(opacityID);
}
sweetTitles.tip.style.visibility = 'hidden';
},
checkNode : function() {
var trueObj = this.obj;
if ( this.tipElements.inArray(trueObj.nodeName.toLowerCase()) ) {
return trueObj;
} else {
return trueObj.parentNode;
}
},
tipOver : function(e) {
sweetTitles.obj = this;
tID = window.setTimeout("sweetTitles.tipShow()",200);
sweetTitles.updateXY(e);
},
tipShow : function() {
var scrX = Number(this.xCord);
var scrY = Number(this.yCord);
var tp = parseInt(scrY+15);
var lt = parseInt(scrX+10);
var anch = this.checkNode();
var addy = '';
var access = '';
if ( anch.nodeName.toLowerCase() == 'a' ) {
addy = (anch.href.length > 25 ?
anch.href.toString().substring(0,25)+"..."
: anch.href);
var access = ( anch.accessKey ? ' <span>['+anch.accessKey+']</span> ' : '' );
} else if (anch.firstChild){
addy = anch.firstChild.nodeValue;
} else {
addy = '';
}
this.tip.innerHTML = "<p>"+anch.getAttribute('tip')+"<em>"+access+addy+"</em></p>";
if ( parseInt(document.documentElement.clientWidth+document.documentElement.scrollLeft) <
parseInt(this.tip.offsetWidth+lt) ) {
this.tip.style.left = parseInt(lt-(this.tip.offsetWidth+10))+'px';
} else {
this.tip.style.left = lt+'px';
}
if ( parseInt(document.documentElement.clientHeight+document.documentElement.scrollTop) <
parseInt(this.tip.offsetHeight+tp) ) {
this.tip.style.top = parseInt(tp-(this.tip.offsetHeight+10))+'px';
} else {
this.tip.style.top = tp+'px';
}
this.tip.style.visibility = 'visible';
this.tip.style.opacity = '.1';
this.tipFade(10);
},
tipFade: function(opac) {
var passed = parseInt(opac);
var newOpac = parseInt(passed+10);
if ( newOpac < 80 ) {
this.tip.style.opacity = '.'+newOpac;
this.tip.style.filter = "alpha(opacity:"+newOpac+")";
opacityID = window.setTimeout("sweetTitles.tipFade('"+newOpac+"')",20);
}
else {
this.tip.style.opacity = '.80';
this.tip.style.filter = "alpha(opacity:80)";
}
}
};
function pageLoader() {
sweetTitles.init();
}
addEvent(window,'load',pageLoader);
|
At the moment the replacement sweetTitles.js should be able to add tooltips to the following elements: 'input', 'td', 'tr', 'textarea', 'select', 'span', 'div', 'a','abbr','acronym'. If that's not enough (or too much), edit the "tipElements" array at the top of the file.
Put the 2 JavaScript files somewhere into your package (ie org.example.app.javascript)
Either put the CSS file (sweetTitles.css) into your package as well or add the contents to a CSS file you already use in your application.
Add this to the head section of the html file you want to use tooltips in:
<wicket:head> <wicket:link> <script wicket:id="addEventJs"></script> <script wicket:id="sweetTitlesJs"></script> </wicket:link> </wicket:head> |
If you also added the CSS file to your package, your also have to add this to the <wicket:link> section:
<link href="styles/sweetTitles.css" rel="stylesheet" type="text/css"> |
Of course you have to customize these examples so they'll work with your package structure.
Add the JavaScript resources to your page:
add(new JavaScriptReference("addEventJs",
new ResourceReference(YourClass.class, "javascript/addEvent.js")));
add(new JavaScriptReference("sweetTitlesJs",
new ResourceReference(YourClass.class, "javascript/sweetTitles.js")));
|
Alternatively, you can just add these 2 lines to your Wicket's Panel or WebPage without touching the HTML i.e. skip Step 6,
// for Wicket 1.4
add(JavascriptPackageResource.getHeaderContribution("javascript/addEvent.js"));
add(JavascriptPackageResource.getHeaderContribution("javascript/sweetTitles.js"));
// for Wicket 1.3.x
add(HeaderContributor.forJavaScript("javascript/addEvent.js"));
add(HeaderContributor.forJavaScript("javascript/sweetTitles.js"));
|
Add the attribute "showtooltip" to the element that should show a tooltip (only elements with this attibute will show tooltips):
someWicketComponent.add(new AttributeModifier("showtooltip", true, new Model("true")));
|
Either add the tooltip text to the element in the html file, using the "title" attribute:
<input type="checkbox" wicket:id="myCheckbox" title="Hi, I am a tooltip."/> |
...or add dynamic tooltip texts using an AttributeModifier:
someWicketComponent.add(new AttributeModifier("title", true, new Model("Hi, I am a dynamic tooltip.")));
|
Change
display:block |
to
display:none |
in the CSS selector div#toolTip p em if you just want to show the text in the Model. Otherwise, the element's text will be appended to the tip.
Well, actually step 10 was to add this to the wiki... But you don't have to do that anymore, obviously
Added by Johannes Fahrenkrug 8 August 2006