Archive for April, 2010
YUI3 Tooltip module
by Ron on Apr.09, 2010, under Javascript
Just quickly posting this bit of code that I’ve written to have a play with YUI3. There’s definitely room for improvement (e.g. making Tooltip inherit from the Overlay widget) and I haven’t tested the code thoroughly yet. But for a first try with a library, I figured it was nice enough to get the expected result:
YUI.add('tooltip', function (Y) {
var Tip = function (config) {
Tip.superclass.constructor.apply(this, arguments);
};
Tip.ATTRS = {
offsetX: {
value: 10,
setter: function (val) {
return val;
}
},
offsetY: {
value: 10,
setter: function (val) {
return val;
}
},
showDelay: {
value: 0.5,
setter: function (val) {
return val*1000;
},
validator: function (val) {
return Y.Lang.isNumber(val) && (val >= 0);
}
},
hideDelay: {
value: 1.5,
setter: function (val) {
return val*1000;
},
validator: function (val) {
return Y.Lang.isNumber(val) && (val >= 0);
}
}
};
Tip.HTML_PARSER = {
header: function (srcNode) {
var h = srcNode.getAttribute("title").match(/header=\[([^\]]*)\]/);
if (h !== null && h.length > 1) {
return h[1];
}
return "";
},
body: function (srcNode) {
var b = srcNode.getAttribute("title").match(/body=\[([^\]]*)\]/);
if (b !== null && b.length > 1) {
return b[1];
}
return "";
}
};
Tip.NAME = "tooltip";
Y.extend(Tip, Y.Widget, {
_srcNode: null,
_tipNode: null,
_config: null,
_timers: null,
initializer: function (config) {
this._config = config;
this._srcNode = config.srcNode;
this._createTipNode(config.header, config.body);
this._timers = {
show: null,
hide: null
};
Y.on("mouseenter", Y.bind(this._onMouseEnter, this), this._srcNode);
Y.on("mouseleave", Y.bind(this._onMouseLeave, this), this._srcNode);
},
destructor: function () {
this._onMouseEnter.detach();
this._onMouseLeave.detach();
this._tipNode.remove();
},
_createTipNode: function (header, body) {
this._tipNode = new Y.Overlay({
headerContent: header,
bodyContent: body,
visible: false,
width:"280px",
constrain: true
});
this._srcNode.setAttribute("title", "");
this._tipNode.render();
},
_onMouseEnter: function (e) {
if (Y.BOL.activeTooltip !== null) {
Y.BOL.activeTooltip.hide();
Y.BOL.activeTooltip = null;
}
if (this._timers.hide !== null) {
this._timers.hide = clearTimeout(this._timers.hide);
}
this._timers.show = setTimeout(Y.bind(function () {
this._tipNode.set("xy", [e.pageX+this.get("offsetX"), e.pageY+this.get("offsetY")]);
this._tipNode.show();
Y.BOL.activeTooltip = this;
}, this), this.get("showDelay"));
},
_onMouseLeave: function (e) {
if (this._timers.show !== null) {
this._timers.show = clearTimeout(this._timers.show);
}
this._timers.hide = setTimeout(Y.bind(function () {
this.hide();
Y.BOL.activeTooltip = null;
}, this), this.get("hideDelay"));
},
hide: function () {
if (this._timers.show !== null) {
this._timers.show = clearTimeout(this._timers.show);
}
this._tipNode.hide();
}
});
Y.namespace('BOL');
Y.BOL.Tooltip = Tip;
Y.BOL.activeTooltip = null;
},
'1.0',
{
requires: ['event-mouseenter', 'overlay']
});
To use it, the HTML needs to look like this:
<div id="testDiv" class="tooltip_trigger" title="header=[Verzendkosten per bestelling] body=[Nederland: &euro; 1,95<br>Belgi&euml;: &euro; 0,00<br>Overige Europa, Noord- en Midden-Amerika, Cara&iuml;bisch gebied, Azi&euml;, Australi&euml;, Nieuw-Zeeland: van &euro; 3,45 tot &euro; 19,80<br><br><strong>Let op!</strong> Software, pc-accessoires, elektronica en telefonie worden niet in het buitenland bezorgd.<br><br>]">Test</div>
And finally, to call it:
YUI().use('tooltip', function (Y) {
Y.all(".tooltip_trigger").each(function (trgNode) {
var tip = new Y.BOL.Tooltip({
srcNode: trgNode
});
})
})
