1 if(!dojo._hasResource["dijit.Tooltip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit.Tooltip"] = true;
3 dojo.provide("dijit.Tooltip");
5 dojo.require("dijit._Widget");
6 dojo.require("dijit._Templated");
9 "dijit._MasterTooltip",
10 [dijit._Widget, dijit._Templated],
13 // Internal widget that holds the actual tooltip markup,
14 // which occurs once per page.
15 // Called by Tooltip widgets which are just containers to hold
19 // Milliseconds to fade in/fade out
22 templateString:"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector\"></div>\n</div>\n",
24 postCreate: function(){
25 dojo.body().appendChild(this.domNode);
27 this.bgIframe = new dijit.BackgroundIframe(this.domNode);
29 // Setup fade-in and fade-out functions.
30 this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") });
31 this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
35 show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
37 // Display tooltip w/specified contents to right specified node
38 // (To left if there's no space on the right, or if LTR==right)
40 if(this.aroundNode && this.aroundNode === aroundNode){
44 if(this.fadeOut.status() == "playing"){
45 // previous tooltip is being hidden; wait until the hide completes then show new one
46 this._onDeck=arguments;
49 this.containerNode.innerHTML=innerHTML;
51 // Firefox bug. when innerHTML changes to be shorter than previous
52 // one, the node size will not be updated until it moves.
53 this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
55 // position the element and change CSS according to position[] (a list of positions to try)
57 var ltr = this.isLeftToRight();
58 dojo.forEach( (position && position.length) ? position : dijit.Tooltip.defaultPosition, function(pos){
61 align[ltr ? "BR" : "BL"] = ltr ? "BL" : "BR";
64 align[ltr ? "BL" : "BR"] = ltr ? "BR" : "BL";
67 // first try to align left borders, next try to align right borders (or reverse for RTL mode)
68 align[ltr ? "BL" : "BR"] = ltr ? "TL" : "TR";
69 align[ltr ? "BR" : "BL"] = ltr ? "TR" : "TL";
73 // first try to align left borders, next try to align right borders (or reverse for RTL mode)
74 align[ltr ? "TL" : "TR"] = ltr ? "BL" : "BR";
75 align[ltr ? "TR" : "TL"] = ltr ? "BR" : "BL";
79 var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align, dojo.hitch(this, "orient"));
82 dojo.style(this.domNode, "opacity", 0);
84 this.isShowingNow = true;
85 this.aroundNode = aroundNode;
88 orient: function(/* DomNode */ node, /* String */ aroundCorner, /* String */ tooltipCorner){
89 // summary: private function to set CSS for tooltip node based on which position it's in
90 node.className = "dijitTooltip " +
92 "BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
93 "TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
94 "BR-TR": "dijitTooltipBelow dijitTooltipABRight",
95 "TR-BR": "dijitTooltipAbove dijitTooltipABRight",
96 "BR-BL": "dijitTooltipRight",
97 "BL-BR": "dijitTooltipLeft"
98 }[aroundCorner + "-" + tooltipCorner];
103 // the arrow won't show up on a node w/an opacity filter
104 this.domNode.style.filter="";
108 hide: function(aroundNode){
109 // summary: hide the tooltip
110 if(!this.aroundNode || this.aroundNode !== aroundNode){
114 // this hide request is for a show() that hasn't even started yet;
115 // just cancel the pending show()
120 this.isShowingNow = false;
121 this.aroundNode = null;
126 this.domNode.style.cssText=""; // to position offscreen again
128 // a show request has been queued up; do it now
129 this.show.apply(this, this._onDeck);
137 dijit.showTooltip = function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
139 // Display tooltip w/specified contents in specified position.
140 // See description of dijit.Tooltip.defaultPosition for details on position parameter.
141 // If position is not specified then dijit.Tooltip.defaultPosition is used.
142 if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
143 return dijit._masterTT.show(innerHTML, aroundNode, position);
146 dijit.hideTooltip = function(aroundNode){
147 // summary: hide the tooltip
148 if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
149 return dijit._masterTT.hide(aroundNode);
157 // Pops up a tooltip (a help message) when you hover over a node.
160 // Text to display in the tooltip.
161 // Specified as innerHTML when creating the widget from markup.
164 // showDelay: Integer
165 // Number of milliseconds to wait after hovering over/focusing on the object, before
166 // the tooltip is displayed.
169 // connectId: String[]
170 // Id(s) of domNodes to attach the tooltip to.
171 // When user hovers over any of the specified dom nodes, the tooltip will appear.
174 // position: String[]
175 // See description of dijit.Tooltip.defaultPosition for details on position parameter.
178 postCreate: function(){
180 this.srcNodeRef.style.display = "none";
183 this._connectNodes = [];
185 dojo.forEach(this.connectId, function(id) {
186 var node = dojo.byId(id);
188 this._connectNodes.push(node);
189 dojo.forEach(["onMouseOver", "onMouseOut", "onFocus", "onBlur", "onHover", "onUnHover"], function(event){
190 this.connect(node, event.toLowerCase(), "_"+event);
200 _onMouseOver: function(/*Event*/ e){
204 _onMouseOut: function(/*Event*/ e){
205 if(dojo.isDescendant(e.relatedTarget, e.target)){
206 // false event; just moved from target to target child; ignore.
212 _onFocus: function(/*Event*/ e){
215 this.inherited(arguments);
218 _onBlur: function(/*Event*/ e){
221 this.inherited(arguments);
224 _onHover: function(/*Event*/ e){
225 if(!this._showTimer){
226 var target = e.target;
227 this._showTimer = setTimeout(dojo.hitch(this, function(){this.open(target)}), this.showDelay);
231 _onUnHover: function(/*Event*/ e){
232 // keep a tooltip open if the associated element has focus
233 if(this._focus){ return; }
235 clearTimeout(this._showTimer);
236 delete this._showTimer;
241 open: function(/*DomNode*/ target){
242 // summary: display the tooltip; usually not called directly.
243 target = target || this._connectNodes[0];
244 if(!target){ return; }
247 clearTimeout(this._showTimer);
248 delete this._showTimer;
250 dijit.showTooltip(this.label || this.domNode.innerHTML, target, this.position);
252 this._connectNode = target;
256 // summary: hide the tooltip; usually not called directly.
257 dijit.hideTooltip(this._connectNode);
258 delete this._connectNode;
260 clearTimeout(this._showTimer);
261 delete this._showTimer;
265 uninitialize: function(){
271 // dijit.Tooltip.defaultPosition: String[]
272 // This variable controls the position of tooltips, if the position is not specified to
273 // the Tooltip widget or *TextBox widget itself. It's an array of strings with the following values:
275 // * before: places tooltip to the left of the target node/widget, or to the right in
276 // the case of RTL scripts like Hebrew and Arabic
277 // * after: places tooltip to the right of the target node/widget, or to the left in
278 // the case of RTL scripts like Hebrew and Arabic
279 // * above: tooltip goes above target node
280 // * below: tooltip goes below target node
282 // The list is positions is tried, in order, until a position is found where the tooltip fits
283 // within the viewport.
285 // Be careful setting this parameter. A value of "above" may work fine until the user scrolls
286 // the screen so that there's no room above the target node. Nodes with drop downs, like
287 // DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
288 // that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
289 // is only room below (or above) the target node, but not both.
290 dijit.Tooltip.defaultPosition = ["after", "before"];