3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.tip.QuickTip
17 * @extends Ext.tip.ToolTip
18 * A specialized tooltip class for tooltips that can be specified in markup and automatically managed by the global
19 * {@link Ext.tip.QuickTipManager} instance. See the QuickTipManager documentation for additional usage details and examples.
22 Ext.define('Ext.tip.QuickTip', {
23 extend: 'Ext.tip.ToolTip',
24 alternateClassName: 'Ext.QuickTip',
26 * @cfg {String/HTMLElement/Ext.Element} target The target HTMLElement, Ext.Element or id to associate with this Quicktip (defaults to the document).
29 * @cfg {Boolean} interceptTitles True to automatically use the element's DOM title value if available.
31 interceptTitles : false,
33 // Force creation of header Component
50 initComponent : function(){
53 me.target = me.target || Ext.getDoc();
54 me.targets = me.targets || {};
59 * Configures a new quick tip instance and assigns it to a target element. The following config values are
60 * supported (for example usage, see the {@link Ext.tip.QuickTipManager} class header):
61 * <div class="mdetail-params"><ul>
64 * <li>dismissDelay (overrides the singleton value)</li>
65 * <li>target (required)</li>
66 * <li>text (required)</li>
68 * <li>width</li></ul></div>
69 * @param {Object} config The config object
71 register : function(config){
72 var configs = Ext.isArray(config) ? config : arguments,
77 for (; i < len; i++) {
79 target = config.target;
81 if (Ext.isArray(target)) {
82 for (j = 0, targetLen = target.length; j < targetLen; j++) {
83 this.targets[Ext.id(target[j])] = config;
86 this.targets[Ext.id(target)] = config;
93 * Removes this quick tip from its element and destroys it.
94 * @param {String/HTMLElement/Ext.Element} el The element from which the quick tip is to be removed or ID of the element.
96 unregister : function(el){
97 delete this.targets[Ext.id(el)];
101 * Hides a visible tip or cancels an impending show for a particular element.
102 * @param {String/HTMLElement/Ext.Element} el The element that is the target of the tip or ID of the element.
104 cancelShow: function(el){
106 activeTarget = me.activeTarget;
108 el = Ext.get(el).dom;
109 if (me.isVisible()) {
110 if (activeTarget && activeTarget.el == el) {
113 } else if (activeTarget && activeTarget.el == el) {
114 me.clearTimer('show');
120 * Reads the tip text from the closest node to the event target which contains the attribute we
121 * are configured to look for. Returns an object containing the text from the attribute, and the target element from
122 * which the text was read.
124 getTipCfg: function(e) {
125 var t = e.getTarget(),
129 if (this.interceptTitles && titleText && Ext.isString(titleText)) {
131 t.removeAttribute("title");
138 cfg = this.tagConfig;
139 t = e.getTarget('[' + cfg.namespace + cfg.attribute + ']');
143 text: t.getAttribute(cfg.namespace + cfg.attribute)
150 onTargetOver : function(e){
152 target = e.getTarget(),
163 // TODO - this causes "e" to be recycled in IE6/7 (EXTJSIV-1608) so ToolTip#setTarget
164 // was changed to include freezeEvent. The issue seems to be a nested 'resize' event
165 // that smashed Ext.EventObject.
166 me.targetXY = e.getXY();
168 if(!target || target.nodeType !== 1 || target == document || target == document.body){
172 if (me.activeTarget && ((target == me.activeTarget.el) || Ext.fly(me.activeTarget.el).contains(target))) {
173 me.clearTimer('hide');
179 Ext.Object.each(me.targets, function(key, value) {
180 var targetEl = Ext.fly(value.target);
181 if (targetEl && (targetEl.dom === target || targetEl.contains(target))) {
182 elTarget = targetEl.dom;
187 me.activeTarget = me.targets[elTarget.id];
188 me.activeTarget.el = target;
189 me.anchor = me.activeTarget.anchor;
191 me.anchorTarget = target;
198 elTarget = Ext.get(target);
201 tipConfig = me.getTipCfg(e);
205 // getTipCfg may look up the parentNode axis for a tip text attribute and will return the new target node.
206 // Change our target element to match that from which the tip text attribute was read.
207 if (tipConfig.target) {
208 target = tipConfig.target;
209 elTarget = Ext.get(target);
211 autoHide = elTarget.getAttribute(ns + cfg.hide);
215 text: tipConfig.text,
216 width: +elTarget.getAttribute(ns + cfg.width) || null,
217 autoHide: autoHide != "user" && autoHide !== 'false',
218 title: elTarget.getAttribute(ns + cfg.title),
219 cls: elTarget.getAttribute(ns + cfg.cls),
220 align: elTarget.getAttribute(ns + cfg.align)
223 me.anchor = elTarget.getAttribute(ns + cfg.anchor);
225 me.anchorTarget = target;
232 onTargetOut : function(e){
235 // If moving within the current target, and it does not have a new tip, ignore the mouseout
236 if (me.activeTarget && e.within(me.activeTarget.el) && !me.getTipCfg(e)) {
240 me.clearTimer('show');
241 if (me.autoHide !== false) {
247 showAt : function(xy){
249 target = me.activeTarget;
253 me.render(Ext.getBody());
254 me.activeTarget = target;
257 me.setTitle(target.title || '');
262 me.body.update(target.text);
263 me.autoHide = target.autoHide;
264 me.dismissDelay = target.dismissDelay || me.dismissDelay;
266 me.el.removeCls(me.lastCls);
270 me.el.addCls(target.cls);
271 me.lastCls = target.cls;
274 me.setWidth(target.width);
277 me.constrainPosition = false;
278 } else if (target.align) { // TODO: this doesn't seem to work consistently
279 xy = me.el.getAlignToXY(target.el, target.align);
280 me.constrainPosition = false;
282 me.constrainPosition = true;
290 delete this.activeTarget;