Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / src / widgets / tips / QuickTip.js
1 /*!
2  * Ext JS Library 3.0.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**\r
8  * @class Ext.QuickTip\r
9  * @extends Ext.ToolTip\r
10  * A specialized tooltip class for tooltips that can be specified in markup and automatically managed by the global\r
11  * {@link Ext.QuickTips} instance.  See the QuickTips class header for additional usage details and examples.\r
12  * @constructor\r
13  * Create a new Tip\r
14  * @param {Object} config The configuration options\r
15  */\r
16 Ext.QuickTip = Ext.extend(Ext.ToolTip, {\r
17     /**\r
18      * @cfg {Mixed} target The target HTMLElement, Ext.Element or id to associate with this quicktip (defaults to the document).\r
19      */\r
20     /**\r
21      * @cfg {Boolean} interceptTitles True to automatically use the element's DOM title value if available (defaults to false).\r
22      */\r
23     interceptTitles : false,\r
24 \r
25     // private\r
26     tagConfig : {\r
27         namespace : "ext",\r
28         attribute : "qtip",\r
29         width : "qwidth",\r
30         target : "target",\r
31         title : "qtitle",\r
32         hide : "hide",\r
33         cls : "qclass",\r
34         align : "qalign",\r
35         anchor : "anchor"\r
36     },\r
37 \r
38     // private\r
39     initComponent : function(){\r
40         this.target = this.target || Ext.getDoc();\r
41         this.targets = this.targets || {};\r
42         Ext.QuickTip.superclass.initComponent.call(this);\r
43     },\r
44 \r
45     /**\r
46      * Configures a new quick tip instance and assigns it to a target element.  The following config values are\r
47      * supported (for example usage, see the {@link Ext.QuickTips} class header):\r
48      * <div class="mdetail-params"><ul>\r
49      * <li>autoHide</li>\r
50      * <li>cls</li>\r
51      * <li>dismissDelay (overrides the singleton value)</li>\r
52      * <li>target (required)</li>\r
53      * <li>text (required)</li>\r
54      * <li>title</li>\r
55      * <li>width</li></ul></div>\r
56      * @param {Object} config The config object\r
57      */\r
58     register : function(config){\r
59         var cs = Ext.isArray(config) ? config : arguments;\r
60         for(var i = 0, len = cs.length; i < len; i++){\r
61             var c = cs[i];\r
62             var target = c.target;\r
63             if(target){\r
64                 if(Ext.isArray(target)){\r
65                     for(var j = 0, jlen = target.length; j < jlen; j++){\r
66                         this.targets[Ext.id(target[j])] = c;\r
67                     }\r
68                 } else{\r
69                     this.targets[Ext.id(target)] = c;\r
70                 }\r
71             }\r
72         }\r
73     },\r
74 \r
75     /**\r
76      * Removes this quick tip from its element and destroys it.\r
77      * @param {String/HTMLElement/Element} el The element from which the quick tip is to be removed.\r
78      */\r
79     unregister : function(el){\r
80         delete this.targets[Ext.id(el)];\r
81     },\r
82     \r
83     /**\r
84      * Hides a visible tip or cancels an impending show for a particular element.\r
85      * @param {String/HTMLElement/Element} el The element that is the target of the tip.\r
86      */\r
87     cancelShow: function(el){\r
88         var at = this.activeTarget;\r
89         el = Ext.get(el).dom;\r
90         if(this.isVisible()){\r
91             if(at && at.el == el){\r
92                 this.hide();\r
93             }\r
94         }else if(at && at.el == el){\r
95             this.clearTimer('show');\r
96         }\r
97     },\r
98 \r
99     // private\r
100     onTargetOver : function(e){\r
101         if(this.disabled){\r
102             return;\r
103         }\r
104         this.targetXY = e.getXY();\r
105         var t = e.getTarget();\r
106         if(!t || t.nodeType !== 1 || t == document || t == document.body){\r
107             return;\r
108         }\r
109         if(this.activeTarget && t == this.activeTarget.el){\r
110             this.clearTimer('hide');\r
111             this.show();\r
112             return;\r
113         }\r
114         if(t && this.targets[t.id]){\r
115             this.activeTarget = this.targets[t.id];\r
116             this.activeTarget.el = t;\r
117             this.anchor = this.activeTarget.anchor;\r
118             if(this.anchor){\r
119                 this.anchorTarget = t;\r
120             }\r
121             this.delayShow();\r
122             return;\r
123         }\r
124         \r
125         var ttp, et = Ext.fly(t), cfg = this.tagConfig;\r
126         var ns = cfg.namespace;\r
127         if(this.interceptTitles && t.title){\r
128             ttp = t.title;\r
129             t.qtip = ttp;\r
130             t.removeAttribute("title");\r
131             e.preventDefault();\r
132         } else{\r
133             ttp = t.qtip || et.getAttribute(cfg.attribute, ns);\r
134         }\r
135         if(ttp){\r
136             var autoHide = et.getAttribute(cfg.hide, ns);\r
137             this.activeTarget = {\r
138                 el: t,\r
139                 text: ttp,\r
140                 width: et.getAttribute(cfg.width, ns),\r
141                 autoHide: autoHide != "user" && autoHide !== 'false',\r
142                 title: et.getAttribute(cfg.title, ns),\r
143                 cls: et.getAttribute(cfg.cls, ns),\r
144                 align: et.getAttribute(cfg.align, ns)\r
145                 \r
146             };\r
147             this.anchor = et.getAttribute(cfg.anchor, ns);\r
148             if(this.anchor){\r
149                 this.anchorTarget = t;\r
150             }\r
151             this.delayShow();\r
152         }\r
153     },\r
154 \r
155     // private\r
156     onTargetOut : function(e){\r
157         this.clearTimer('show');\r
158         if(this.autoHide !== false){\r
159             this.delayHide();\r
160         }\r
161     },\r
162 \r
163     // inherit docs\r
164     showAt : function(xy){\r
165         var t = this.activeTarget;\r
166         if(t){\r
167             if(!this.rendered){\r
168                 this.render(Ext.getBody());\r
169                 this.activeTarget = t;\r
170             }\r
171             if(t.width){\r
172                 this.setWidth(t.width);\r
173                 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));\r
174                 this.measureWidth = false;\r
175             } else{\r
176                 this.measureWidth = true;\r
177             }\r
178             this.setTitle(t.title || '');\r
179             this.body.update(t.text);\r
180             this.autoHide = t.autoHide;\r
181             this.dismissDelay = t.dismissDelay || this.dismissDelay;\r
182             if(this.lastCls){\r
183                 this.el.removeClass(this.lastCls);\r
184                 delete this.lastCls;\r
185             }\r
186             if(t.cls){\r
187                 this.el.addClass(t.cls);\r
188                 this.lastCls = t.cls;\r
189             }\r
190             if(this.anchor){\r
191                 this.constrainPosition = false;\r
192             }else if(t.align){ // TODO: this doesn't seem to work consistently\r
193                 xy = this.el.getAlignToXY(t.el, t.align);\r
194                 this.constrainPosition = false;\r
195             }else{\r
196                 this.constrainPosition = true;\r
197             }\r
198         }\r
199         Ext.QuickTip.superclass.showAt.call(this, xy);\r
200     },\r
201 \r
202     // inherit docs\r
203     hide: function(){\r
204         delete this.activeTarget;\r
205         Ext.QuickTip.superclass.hide.call(this);\r
206     }\r
207 });