/* * Based on: * Ext JS Library 1.1.1 * Copyright(c) 2006-2007, Ext JS, LLC. * * Originally Released Under LGPL - original licence link has changed is not relivant. * * Fork - LGPL * <script type="text/javascript"> */ /** * @class Roo.QuickTips * Provides attractive and customizable tooltips for any element. * @singleton */ Roo.QuickTips = function(){ var el, tipBody, tipBodyText, tipTitle, tm, cfg, close, tagEls = {}, esc, removeCls = null, bdLeft, bdRight; var ce, bd, xy, dd; var visible = false, disabled = true, inited = false; var showProc = 1, hideProc = 1, dismissProc = 1, locks = []; var onOver = function(e){ if(disabled){ return; } var t = e.getTarget(); if(!t || t.nodeType !== 1 || t == document || t == document.body){ return; } if(ce && t == ce.el){ clearTimeout(hideProc); return; } if(t && tagEls[t.id]){ tagEls[t.id].el = t; showProc = show.defer(tm.showDelay, tm, [tagEls[t.id]]); return; } var ttp, et = Roo.fly(t); var ns = cfg.namespace; if(tm.interceptTitles && t.title){ ttp = t.title; t.qtip = ttp; t.removeAttribute("title"); e.preventDefault(); }else{ ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute) || et.getAttributeNS(cfg.alt_namespace, cfg.attribute) ; } if(ttp){ showProc = show.defer(tm.showDelay, tm, [{ el: t, text: ttp.replace(/\\n/g,'<br/>'), width: et.getAttributeNS(ns, cfg.width), autoHide: et.getAttributeNS(ns, cfg.hide) != "user", title: et.getAttributeNS(ns, cfg.title), cls: et.getAttributeNS(ns, cfg.cls) }]); } }; var onOut = function(e){ clearTimeout(showProc); var t = e.getTarget(); if(t && ce && ce.el == t && (tm.autoHide && ce.autoHide !== false)){ hideProc = setTimeout(hide, tm.hideDelay); } }; var onMove = function(e){ if(disabled){ return; } xy = e.getXY(); xy[1] += 18; if(tm.trackMouse && ce){ el.setXY(xy); } }; var onDown = function(e){ clearTimeout(showProc); clearTimeout(hideProc); if(!e.within(el)){ if(tm.hideOnClick){ hide(); tm.disable(); tm.enable.defer(100, tm); } } }; var getPad = function(){ return 2;//bdLeft.getPadding('l')+bdRight.getPadding('r'); }; var show = function(o){ if(disabled){ return; } clearTimeout(dismissProc); ce = o; if(removeCls){ // in case manually hidden el.removeClass(removeCls); removeCls = null; } if(ce.cls){ el.addClass(ce.cls); removeCls = ce.cls; } if(ce.title){ tipTitle.update(ce.title); tipTitle.show(); }else{ tipTitle.update(''); tipTitle.hide(); } el.dom.style.width = tm.maxWidth+'px'; //tipBody.dom.style.width = ''; tipBodyText.update(o.text); var p = getPad(), w = ce.width; if(!w){ var td = tipBodyText.dom; var aw = Math.max(td.offsetWidth, td.clientWidth, td.scrollWidth); if(aw > tm.maxWidth){ w = tm.maxWidth; }else if(aw < tm.minWidth){ w = tm.minWidth; }else{ w = aw; } } //tipBody.setWidth(w); el.setWidth(parseInt(w, 10) + p); if(ce.autoHide === false){ close.setDisplayed(true); if(dd){ dd.unlock(); } }else{ close.setDisplayed(false); if(dd){ dd.lock(); } } if(xy){ el.avoidY = xy[1]-18; el.setXY(xy); } if(tm.animate){ el.setOpacity(.1); el.setStyle("visibility", "visible"); el.fadeIn({callback: afterShow}); }else{ afterShow(); } }; var afterShow = function(){ if(ce){ el.show(); esc.enable(); if(tm.autoDismiss && ce.autoHide !== false){ dismissProc = setTimeout(hide, tm.autoDismissDelay); } } }; var hide = function(noanim){ clearTimeout(dismissProc); clearTimeout(hideProc); ce = null; if(el.isVisible()){ esc.disable(); if(noanim !== true && tm.animate){ el.fadeOut({callback: afterHide}); }else{ afterHide(); } } }; var afterHide = function(){ el.hide(); if(removeCls){ el.removeClass(removeCls); removeCls = null; } }; return { /** * @cfg {Number} minWidth * The minimum width of the quick tip (defaults to 40) */ minWidth : 40, /** * @cfg {Number} maxWidth * The maximum width of the quick tip (defaults to 300) */ maxWidth : 300, /** * @cfg {Boolean} interceptTitles * True to automatically use the element's DOM title value if available (defaults to false) */ interceptTitles : false, /** * @cfg {Boolean} trackMouse * True to have the quick tip follow the mouse as it moves over the target element (defaults to false) */ trackMouse : false, /** * @cfg {Boolean} hideOnClick * True to hide the quick tip if the user clicks anywhere in the document (defaults to true) */ hideOnClick : true, /** * @cfg {Number} showDelay * Delay in milliseconds before the quick tip displays after the mouse enters the target element (defaults to 500) */ showDelay : 500, /** * @cfg {Number} hideDelay * Delay in milliseconds before the quick tip hides when autoHide = true (defaults to 200) */ hideDelay : 200, /** * @cfg {Boolean} autoHide * True to automatically hide the quick tip after the mouse exits the target element (defaults to true). * Used in conjunction with hideDelay. */ autoHide : true, /** * @cfg {Boolean} * True to automatically hide the quick tip after a set period of time, regardless of the user's actions * (defaults to true). Used in conjunction with autoDismissDelay. */ autoDismiss : true, /** * @cfg {Number} * Delay in milliseconds before the quick tip hides when autoDismiss = true (defaults to 5000) */ autoDismissDelay : 5000, /** * @cfg {Boolean} animate * True to turn on fade animation. Defaults to false (ClearType/scrollbar flicker issues in IE7). */ animate : false, /** * @cfg {String} title * Title text to display (defaults to ''). This can be any valid HTML markup. */ title: '', /** * @cfg {String} text * Body text to display (defaults to ''). This can be any valid HTML markup. */ text : '', /** * @cfg {String} cls * A CSS class to apply to the base quick tip element (defaults to ''). */ cls : '', /** * @cfg {Number} width * Width in pixels of the quick tip (defaults to auto). Width will be ignored if it exceeds the bounds of * minWidth or maxWidth. */ width : null, /** * Initialize and enable QuickTips for first use. This should be called once before the first attempt to access * or display QuickTips in a page. */ init : function(){ tm = Roo.QuickTips; cfg = tm.tagConfig; if(!inited){ if(!Roo.isReady){ // allow calling of init() before onReady Roo.onReady(Roo.QuickTips.init, Roo.QuickTips); return; } el = new Roo.Layer({cls:"x-tip", shadow:"drop", shim: true, constrain:true, shadowOffset:4}); el.fxDefaults = {stopFx: true}; // maximum custom styling //el.update('<div class="x-tip-top-left"><div class="x-tip-top-right"><div class="x-tip-top"></div></div></div><div class="x-tip-bd-left"><div class="x-tip-bd-right"><div class="x-tip-bd"><div class="x-tip-close"></div><h3></h3><div class="x-tip-bd-inner"></div><div class="x-clear"></div></div></div></div><div class="x-tip-ft-left"><div class="x-tip-ft-right"><div class="x-tip-ft"></div></div></div>'); el.update('<div class="x-tip-bd"><div class="x-tip-close"></div><h3></h3><div class="x-tip-bd-inner"></div><div class="x-clear"></div></div>'); tipTitle = el.child('h3'); tipTitle.enableDisplayMode("block"); tipBody = el.child('div.x-tip-bd'); tipBodyText = el.child('div.x-tip-bd-inner'); //bdLeft = el.child('div.x-tip-bd-left'); //bdRight = el.child('div.x-tip-bd-right'); close = el.child('div.x-tip-close'); close.enableDisplayMode("block"); close.on("click", hide); var d = Roo.get(document); d.on("mousedown", onDown); d.on("mouseover", onOver); d.on("mouseout", onOut); d.on("mousemove", onMove); esc = d.addKeyListener(27, hide); esc.disable(); if(Roo.dd.DD){ dd = el.initDD("default", null, { onDrag : function(){ el.sync(); } }); dd.setHandleElId(tipTitle.id); dd.lock(); } inited = true; } this.enable(); }, /** * Configures a new quick tip instance and assigns it to a target element. The following config options * are supported: * <pre> Property Type Description ---------- --------------------- ------------------------------------------------------------------------ target Element/String/Array An Element, id or array of ids that this quick tip should be tied to * </ul> * @param {Object} config The config object */ register : function(config){ var cs = config instanceof Array ? config : arguments; for(var i = 0, len = cs.length; i < len; i++) { var c = cs[i]; var target = c.target; if(target){ if(target instanceof Array){ for(var j = 0, jlen = target.length; j < jlen; j++){ tagEls[target[j]] = c; } }else{ tagEls[typeof target == 'string' ? target : Roo.id(target)] = c; } } } }, /** * Removes this quick tip from its element and destroys it. * @param {String/HTMLElement/Element} el The element from which the quick tip is to be removed. */ unregister : function(el){ delete tagEls[Roo.id(el)]; }, /** * Enable this quick tip. */ enable : function(){ if(inited && disabled){ locks.pop(); if(locks.length < 1){ disabled = false; } } }, /** * Disable this quick tip. */ disable : function(){ disabled = true; clearTimeout(showProc); clearTimeout(hideProc); clearTimeout(dismissProc); if(ce){ hide(true); } locks.push(1); }, /** * Returns true if the quick tip is enabled, else false. */ isEnabled : function(){ return !disabled; }, // private tagConfig : { namespace : "roo", // was ext?? this may break.. alt_namespace : "ext", attribute : "qtip", width : "width", target : "target", title : "qtitle", hide : "hide", cls : "qclass" } }; }(); // backwards compat Roo.QuickTips.tips = Roo.QuickTips.register;