//
// Usage:
// function setToolTip(eid, tipHTML, maxwidth)
// eid: The uniqe id of the element to which the tool tip is
// associated.
// tipHTML: HTML code describing the tool tip.
// maxwidth: Max width (pixles) of the tool tip bounding box (optional).
// Returns 'true' if successful, else 'false'.
//
// var TOOLTIP_MAX_WIDTH
// The max width of the tool tip bounding box, if no 'maxwidth' value is
// passed to setToolTop(). Default is 200.
//
// var TOOLTIP_DELAY
// Milliseconds to wait before displaying tool tip. Default is 500.
//
// Example:
// setToolTip('volSlider', 'Volume
Drag to set volume');
//
// Requirements:
// An empty
or with id='toolTip' and style='visibility: hidden'
// must be available in the document body for use as the tool tip box.
//
// Note:
// Event handlers 'onmouseover' and 'onmouseout' for the the element with
// id=eid will be replaced by setToolTip().
//
var toolTips = [];
var TOOLTIP_STYLE = 'position: absolute; left: 10px; top: 10px; border: black 1px solid; padding: 2px; background-color: lightyellow; font-family: verdana, arial, helvetica; font-size: 10px; font-weight: normal; z-index: 100;';
var TOOLTIP_STYLE2 = 'position: absolute; left: 11px; top: 10px; border: black 1px solid; padding: 2px; background-color: lightyellow; font-family: verdana, arial, helvetica; font-size: 10px; font-weight: normal; z-index: 100; white-space:nowrap; overflow:visible';
var TOOLTIP_FOLLOWMOUSE = 1;
function createToolTip(boxId, delay, defWidth, style, offX, offY, options) {
'use strict';
if (!boxId || !style || isNaN(delay) || isNaN(defWidth) || (delay < 0) || isNaN(offX) || isNaN(offY)) {
window.alert('missing options for createToolTip()');
return false;
}
var box = document.getElementById(boxId);
if (!box) {
return false;
}
var css_sel = '#' + boxId;
if (document.styleSheets[1].addRule) {
document.styleSheets[1].addRule(css_sel, style); // IE, Chrome
} else if (document.styleSheets[1].insertRule) {
try {
document.styleSheets[1].insertRule(css_sel + ' { ' + style + ' }', 0); // DOM
} catch (e) {}
}
toolTips[toolTips.length] = new ToolTip(box, Number(delay), Number(defWidth), Number(offX), Number(offY), options, toolTips.length);
return true;
}
function setToolTip(boxId, elementId, tipHTML, maxwidth, e) {
'use strict';
for (var i = 0; i < toolTips.length; i++) {
if (toolTips[i].box.id === boxId) {
if (!e) {
e = document.getElementById(elementId);
if (!e) {
window.alert('No element with id="' + elementId + '" found!');
return false;
}
}
if (!toolTips[i].tips[elementId]) {
setUpEventHandling(e, i, elementId, boxId);
}
toolTips[i].tips[elementId] = [tipHTML, maxwidth];
if (toolTips[i].tipId === elementId) {
setTip(toolTips[i], elementId);
}
return true;
}
}
return false;
}
function setUpEventHandling(e, i, elementId, boxId) {
'use strict';
var old_out = e.onmouseout ? e.onmouseout : function () {};
e.onmouseout = function (e) {
closeTip(this);
old_out(e);
};
if (toolTips[i].options !== TOOLTIP_FOLLOWMOUSE) {
var old_over = e.onmouseover ? e.onmouseover : function () {};
e.onmouseover = function (e) {
trigTip(e, this);
old_over(e);
};
} else {
var old_move = e.onmousemove ? e.onmousemove : function () {};
e.onmousemove = function (e) {
trigTip(e, this);
old_move(e);
};
}
}
function updateToolTip(boxId, elementId, tipHTML, maxwidth) {
'use strict';
for (var i = 0; i < toolTips.length; i++) {
if (toolTips[i].box.id === boxId) {
toolTips[i].tips[elementId] = [tipHTML, maxwidth];
if (toolTips[i].tipId === elementId) {
toolTips[i].box.innerHTML = toolTips[i].tips[elementId][0];
}
return true;
}
}
}
function ToolTip(box, delay, defWidth, offX, offY, options, index) {
'use strict';
this.box = box;
this.box.onmouseout = function() {releaseTip(this);};
this.box.onclick = function() {releaseTip(this);};
this.box.onmouseover = function() {holdTip(this);};
this.box.innerHTML = '';
this.delay = delay;
this.defWidth = defWidth;
this.tips = [];
this.hold = false;
this.offX = offX;
this.offY = offY;
this.options = options;
this.timer = undefined;
this.tipId = undefined;
this.index = index;
}
function trigTip(e, obj) {
'use strict';
if (!e) {
e = window.event;
}
if (!obj.id) {
return true;
}
for (var i = 0; i < toolTips.length; i++) {
if (toolTips[i].tips[obj.id]) {
if (toolTips[i].options === TOOLTIP_FOLLOWMOUSE) {
// get mouse coord
setMousePos(toolTips[i], e);
if (toolTips[i].tipId === obj.id) {
displayTip(toolTips[i]);
}
}
if (toolTips[i].tipId !== obj.id) {
if (toolTips[i].options !== TOOLTIP_FOLLOWMOUSE) {
setElementPos(toolTips[i], obj);
}
window.clearTimeout(toolTips[i].timer);
var call = 'setTip(toolTips[' + i + '], "' + obj.id + '")';
toolTips[i].timer = window.setTimeout(call, toolTips[i].delay);
}
return true;
}
}
window.alert('No tooltip for element ' + obj.id + '!');
return true;
}
function closeTip(obj) {
'use strict';
if (!obj.id) {
return true;
}
for (var i = 0; i < toolTips.length; i++) {
if (toolTips[i].tips[obj.id]) {
if (!toolTips[i].hold) {
window.clearTimeout(toolTips[i].timer);
toolTips[i].tipId = undefined;
toolTips[i].box.style.visibility = 'hidden';
}
return true;
}
}
return true;
}
function holdTip(obj) {
'use strict';
for (var i = 0; i < toolTips.length; i++) {
if (toolTips[i].box.id === obj.id) {
toolTips[i].hold = true;
toolTips[i].box.style.visibility = '';
return true;
}
}
return false;
}
function releaseTip(obj) {
'use strict';
for (var i = 0; i < toolTips.length; i++) {
if (toolTips[i].box.id === obj.id) {
toolTips[i].hold = false;
toolTips[i].tipId = undefined;
toolTips[i].box.style.visibility = 'hidden';
return true;
}
}
return false;
}
function setTip(toolTip, tipId) {
'use strict';
toolTip.box.innerHTML = toolTip.tips[tipId][0];
toolTip.tipId = tipId;
toolTip.box.style.left = '';
toolTip.box.style.right = '';
toolTip.box.style.top = '';
toolTip.box.style.bottom = '';
if (toolTip.tips[toolTip.tipId][1]) {
toolTip.box.style.width = toolTip.tips[toolTip.tipId][1] + 'px';
}
toolTip.box.style.height = '';
toolTip.box.style.visibility = '';
displayTip(toolTip);
}
function displayTip(toolTip) {
'use strict';
var bound = getBounds();
var tipPos = getPos(toolTip.box);
// Try placing box at specified offset
if (toolTip.offX < 0) {
// Place box to the left of position
tipPos.x = toolTip.posX + toolTip.offX - tipPos.w;
toolTip.box.style.left = tipPos.x + 'px';
} else if (toolTip.offX > 0) {
// Place box to the right of position
tipPos.x = toolTip.posX + toolTip.offX;
toolTip.box.style.left = tipPos.x + 'px';
} else {
// Place box centered on position
tipPos.x = toolTip.posX - Math.floor(tipPos.w / 2);
toolTip.box.style.left = tipPos.x + 'px';
}
if (toolTip.offY < 0) {
// Place box above position
tipPos.y = toolTip.posY + toolTip.offY - tipPos.h;
toolTip.box.style.top = tipPos.y + 'px';
} else if (toolTip.offY > 0) {
// Place box below position
tipPos.y = toolTip.posY + toolTip.offY;
toolTip.box.style.top = tipPos.y + 'px';
} else {
// Place box centered on position
tipPos.y = toolTip.posY - Math.floor(tipPos.h / 2);
toolTip.box.style.top = tipPos.y + 'px';
}
// Make sure box is not outside window boundaries.
if (tipPos.x < bound.x) {
// Outside left boundry
tipPos.x = bound.x;
}
if ((tipPos.x + tipPos.w) >= (bound.x + bound.w)) {
// Outside right boundry
tipPos.x = (bound.x + bound.w) - tipPos.w;
}
toolTip.posX = tipPos.x;
toolTip.box.style.left = toolTip.posX + 'px';
if (tipPos.y < bound.y) {
// Outside top boundry
tipPos.y = bound.y;
}
if ((tipPos.y + tipPos.h) > (bound.y + bound.h)) {
// Outside bottom boundry
tipPos.y = (bound.y + bound.h) - tipPos.h;
}
toolTip.posY = tipPos.y;
toolTip.box.style.top = toolTip.posY + 'px';
}
function Box(x, y, w, h) {
'use strict';
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
function getBounds() {
'use strict';
// www.quirksmode.org
var box = new Box(0, 0, 0, 0);
if (document.body) {
box.w = document.body.clientWidth;
box.h = document.body.clientHeight;
} else if (document.documentElement && !isNaN(document.documentElement.clientWidth)) {
// Explorer 6 Strict Mode
box.w = document.documentElement.clientWidth;
box.h = document.documentElement.clientHeight;
}
if (!isNaN(document.body.scrollLeft)) {
// all other Explorers
if (document.body.scrollLeft > 0) {
box.x = document.body.scrollLeft;
}
if (document.body.scrollTop > 0) {
box.y = document.body.scrollTop;
}
}
if (!isNaN(window.self.pageYOffset)) {
// all except Explorer
if (window.self.pageXOffset > 0) {
box.x = window.self.pageXOffset;
}
if (window.self.pageYOffset > 0) {
box.y = window.self.pageYOffset;
}
}
if (document.documentElement && !isNaN(document.documentElement.scrollLeft)) { // Explorer 6 Strict
if (document.documentElement.scrollLeft > 0) {
box.x = document.documentElement.scrollLeft;
}
if (document.documentElement.scrollTop > 0) {
box.y = document.documentElement.scrollTop;
}
}
return box;
}
function getPos(obj) {
'use strict';
// www.quirksmode.org
var box = new Box(0, 0, 0, 0);
box.w = obj.offsetWidth;
box.h = obj.offsetHeight;
if (obj.offsetParent) {
while (obj.offsetParent) {
box.x += obj.offsetLeft;
box.y += obj.offsetTop;
obj = obj.offsetParent;
}
} else if (!isNaN(obj.x)) {
box.x += obj.x;
box.y += obj.y;
}
return box;
}
// Set position to center of element
function setElementPos(toolTip, element) {
'use strict';
var ePos = getPos(element);
toolTip.posX = ePos.x + Math.floor(ePos.w / 2);
toolTip.posY = ePos.y + Math.floor(ePos.h / 2);
}
// set position to mouse
function setMousePos(toolTip, e) {
'use strict';
if (e.pageX && e.pageY) {
toolTip.posX = e.pageX;
toolTip.posY = e.pageY;
} else if (e.clientX) {
var bound = getBounds();
toolTip.posX = (e.clientX + bound.x);
toolTip.posY = (e.clientY + bound.y);
}
}