Widget: Creating a simple Tooltip widget
+ +
+ This is an advanced example, in which we create a Tooltip widget, by extending the base Widget class, and adding WidgetStack and WidgetPosition extensions, through Base.build.
Creating A Tooltip Widget Class
+ +Basic Class Structure
+ +As with the basic "Extending Widget" example, the Tooltip class will extend the Widget base class and follows the same pattern we use for other classes which extend Base.
Namely:
+ +-
+
- Set up the constructor to invoke the superclass constructor +
- Define a
NAMEproperty, to identify the class
+ - Define the default attribute configuration, using the
ATTRSproperty
+ - Implement prototype methods +
This basic structure is shown below:
+ + + +Adding WidgetPosition and WidgetStack Extension Support
+ +The Tooltip class also needs basic positioning and stacking (z-index, shimming) support. As with the Custom Widget Classes example, we use
+Base.build to add this support to the Tooltip class. However in this case, we want to modify the Tooltip class, as opposed to extending it
+to create a completely new class, hence we set the dynamic configuration property to false:
Lifecycle Methods: initializer, destructor
+ +The initializer method is invoked during the init lifecycle phase, after the attributes are configured for each class. Tooltip uses it
+to setup the private state variables it will use to store the trigger node currently being serviced by the tooltip instance, event handles and show/hide timers.
The destructor is used to clear out stored state, detach any event handles and clear out the show/hide timers:
Lifecycle Methods: bindUI, syncUI
+ +The bindUI and syncUI are invoked by the base Widget class' renderer method.
bindUI is used to bind the attribute change listeners used to update the rendered UI from the current state of the widget and also to bind
+the DOM listeners required to enable the UI for interaction.
syncUI is used to sync the UI state from the current widget state, when initially rendered.
NOTE: Widget's renderer method also invokes the renderUI method, which is responsible for laying down any additional content elements a widget requires. However
+tooltip does not have any additional elements in needs to add to the DOM, outside of the default Widget boundingBox and contentBox.
Attribute Supporting Methods
+ +Tooltip's triggerNodes, which defines the set of nodes which should trigger this tooltip instance,
+has a couple of supporting methods associated with it.
The _afterSetNodes method is the default attribute change event handler for the triggerNodes
+attribute. It invokes the _uiSetNodes method, which marks all trigger nodes with a trigger class name (yui-tooltip-trigger) when set.
Similarly the _afterSetDelegate method is the default attributechange listener for the delegate attribute,
+and invokes _bindDelegate to set up the listeners when a new delegate node is set.
DOM Event Handlers
+ +Tooltips interaction revolves around the mouseover, mousemove and mouseout DOM events. The mouseover listener is the only listener set up initially, on the delegate node:
It attempts to determine if the mouse is entering a trigger node. It ignores mouseover events generated from elements
+inside the current trigger node (for example when mousing out of a child element of a trigger node). If it determines that the mouse is entering a trigger node,
+the delegates to the _enterTrigger method to setup the current trigger state and attaches mousemove and mouseout listeners on the current trigger node.
The mouse out listener delegates to the _leaveTrigger method, if it determines the mouse is leaving the trigger node:
The mouse move listener delegates to the _overTrigger method to store the current mouse XY co-ordinates (used to position the Tooltip when it is displayed after the showDelay):
Trigger Event Delegates: _enterTrigger, _leaveTrigger, _overTrigger
+ +As seen above, the DOM event handlers delegate to the _enterTrigger, _leaveTrigger and _overTrigger methods to update the
+Tooltip state based on the currently active trigger node.
The _enterTrigger method sets the current trigger state (which node is the current tooltip trigger,
+what the current mouse XY position is, etc.). The method also fires the triggerEnter event, whose default function actually handles
+showing the tooltip after the configured showDelay period. The triggerEnter event can be prevented by listeners, allowing
+users to prevent the tooltip from being shown if required. (triggerEnter listeners are passed the current trigger node and pageX, pageY mouse co-ordinates as event facade properties):
Similarly the _leaveTrigger method is invoked when the mouse leaves a trigger node, and clears any stored state, timers and listeners before setting up
+the hideDelay timer. It fires a triggerLeave event, but cannot be prevented, and has no default behavior to prevent:
As mentioned previously, the _overTrigger method simply stores the current mouse XY co-ordinates for use when the tooltip is shown:
Setting Tooltip Content
+ +Since the content for a tooltip is usually a function of the trigger node and not constant, Tooltip provides a number of ways to set the content.
-
+
- Setting the
contentattribute to a string or node. In this case, the value of thecontentattribute is used + for all triggerNodes
+ - Setting the
contentattribute to an object literal, containing a map of triggerNode id to content. The content for a trigger node + will be set using the map, when the tooltip is triggered for the node.
+ - Setting the title attribute on the trigger node. The value of the title attribute is used to set the tooltip content, + when triggered for the node. +
- By calling the
setTriggerContentmethod to set content for a specific trigger node, in atriggerEnterevent listener.
+
The precedence of these methods is handled in the _setTriggerContent method, invoked when the mouse enters a trigger:
Calling the public setTriggerContent in a triggerEvent listener will over-ride content set using the content attribute or the trigger node's title value.
Using Tooltip
+ +For this example, we set up 4 DIV elements which will act as tooltip triggers. They are all marked using a yui-hastooltip class, so that they can be queried using a simple selector, passed as the value for the triggerNodes attribute in the tooltip's constructor Also all 4 trigger nodes are contained in a wrapper DIV with id="delegate" which will act as the delegate node.
The tooltip content for each of the trigger nodes is setup differently. The first trigger node uses the title attribute to set it's content. The third trigger node's content is set using the content map set in the constructor above. The second trigger node's content is set using a triggerEnter event listener and the setTriggerContent method as shown below:
The fourth trigger node's content is set using it's title attribute, however it also has a triggerEvent listener which prevents the tooltip from being displayed for it, if the checkbox is checked.
