YUI3 Tooltip module
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 }); }) })