Roo/bootstrap/Tooltip.js
[roojs1] / Roo / bootstrap / Tooltip.js
1 /*
2  * - LGPL
3  *
4  * Tooltip
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.Tooltip
10  * Bootstrap Tooltip class
11  * This is basic at present - all componets support it by default, however they should add tooltipEl() method
12  * to determine which dom element triggers the tooltip.
13  * 
14  * It needs to add support for additional attributes like tooltip-position
15  * 
16  * @constructor
17  * Create a new Toolti
18  * @param {Object} config The config object
19  */
20
21 Roo.bootstrap.Tooltip = function(config){
22     Roo.bootstrap.Tooltip.superclass.constructor.call(this, config);
23 };
24
25 Roo.apply(Roo.bootstrap.Tooltip, {
26     /**
27      * @function init initialize tooltip monitoring.
28      * @static
29      */
30     currentEl : false,
31     currentTip : false,
32     currentRegion : false,
33     
34     //  init : delay?
35     
36     init : function()
37     {
38         Roo.get(document).on('mouseover', this.enter ,this);
39         Roo.get(document).on('mouseout', this.leave, this);
40          
41         
42         this.currentTip = new Roo.bootstrap.Tooltip();
43     },
44     
45     enter : function(ev)
46     {
47         var dom = ev.getTarget();
48         
49         //Roo.log(['enter',dom]);
50         var el = Roo.fly(dom);
51         if (this.currentEl) {
52             //Roo.log(dom);
53             //Roo.log(this.currentEl);
54             //Roo.log(this.currentEl.contains(dom));
55             if (this.currentEl == el) {
56                 return;
57             }
58             if (dom != this.currentEl.dom && this.currentEl.contains(dom)) {
59                 return;
60             }
61
62         }
63         
64         
65         
66         if (this.currentTip.el) {
67             this.currentTip.el.hide(); // force hiding...
68         }    
69         Roo.log(el);
70         if (!el.attr('tooltip') && !el.select("[tooltip]").elements.length) { // parents who have tip?
71             return;
72         }
73         this.currentEl = el;
74         this.currentTip.bind(el);
75         this.currentRegion = Roo.lib.Region.getRegion(dom);
76         this.currentTip.enter();
77         
78     },
79     leave : function(ev)
80     {
81         var dom = ev.getTarget();
82         //Roo.log(['leave',dom]);
83         if (!this.currentEl) {
84             return;
85         }
86         
87         
88         if (dom != this.currentEl.dom) {
89             return;
90         }
91         var xy = ev.getXY();
92         if (this.currentRegion.contains( new Roo.lib.Region( xy[1], xy[0] ,xy[1], xy[0]  ))) {
93             return;
94         }
95         // only activate leave if mouse cursor is outside... bounding box..
96         
97         
98         
99         
100         if (this.currentTip) {
101             this.currentTip.leave();
102         }
103         //Roo.log('clear currentEl');
104         this.currentEl = false;
105         
106         
107     },
108     alignment : {
109         'left' : ['r-l', [-2,0], 'right'],
110         'right' : ['l-r', [2,0], 'left'],
111         'bottom' : ['t-b', [0,2], 'top'],
112         'top' : [ 'b-t', [0,-2], 'bottom']
113     }
114     
115 });
116
117
118 Roo.extend(Roo.bootstrap.Tooltip, Roo.bootstrap.Component,  {
119     
120     
121     bindEl : false,
122     
123     delay : null, // can be { show : 300 , hide: 500}
124     
125     timeout : null,
126     
127     hoverState : null, //???
128     
129     placement : 'bottom', 
130     
131     getAutoCreate : function(){
132     
133         var cfg = {
134            cls : 'tooltip',
135            role : 'tooltip',
136            cn : [
137                 {
138                     cls : 'tooltip-arrow'
139                 },
140                 {
141                     cls : 'tooltip-inner'
142                 }
143            ]
144         };
145         
146         return cfg;
147     },
148     bind : function(el)
149     {
150         this.bindEl = el;
151     },
152       
153     
154     enter : function () {
155        
156         if (this.timeout != null) {
157             clearTimeout(this.timeout);
158         }
159         
160         this.hoverState = 'in';
161          //Roo.log("enter - show");
162         if (!this.delay || !this.delay.show) {
163             this.show();
164             return;
165         }
166         var _t = this;
167         this.timeout = setTimeout(function () {
168             if (_t.hoverState == 'in') {
169                 _t.show();
170             }
171         }, this.delay.show);
172     },
173     leave : function()
174     {
175         clearTimeout(this.timeout);
176     
177         this.hoverState = 'out';
178          if (!this.delay || !this.delay.hide) {
179             this.hide();
180             return 
181         }
182        
183         var _t = this;
184         this.timeout = setTimeout(function () {
185             //Roo.log("leave - timeout");
186             
187             if (_t.hoverState == 'out') {
188                 _t.hide();
189                 Roo.bootstrap.Tooltip.currentEl = false;
190             }
191         }, delay)
192     },
193     
194     show : function ()
195     {
196         if (!this.el) {
197             this.render(document.body);
198         }
199         // set content.
200         //Roo.log([this.bindEl, this.bindEl.attr('tooltip')]);
201         
202         var tip = el.attr('tooltip') || el.select("[tooltip]").first().attr('tooltip');
203         
204         this.el.select('.tooltip-inner',true).first().dom.innerHTML = tip
205         
206         this.el.removeClass(['fade','top','bottom', 'left', 'right','in']);
207         
208         var placement = typeof this.placement == 'function' ?
209             this.placement.call(this, this.el, on_el) :
210             this.placement;
211             
212         var autoToken = /\s?auto?\s?/i;
213         var autoPlace = autoToken.test(placement);
214         if (autoPlace) {
215             placement = placement.replace(autoToken, '') || 'top';
216         }
217         
218         //this.el.detach()
219         //this.el.setXY([0,0]);
220         this.el.show();
221         //this.el.dom.style.display='block';
222         this.el.addClass(placement);
223         
224         //this.el.appendTo(on_el);
225         
226         var p = this.getPosition();
227         var box = this.el.getBox();
228         
229         if (autoPlace) {
230             // fixme..
231         }
232         var align = Roo.bootstrap.Tooltip.alignment[placement];
233         this.el.alignTo(this.bindEl, align[0],align[1]);
234         //var arrow = this.el.select('.arrow',true).first();
235         //arrow.set(align[2], 
236         
237         this.el.addClass('in fade');
238         this.hoverState = null;
239         
240         if (this.el.hasClass('fade')) {
241             // fade it?
242         }
243         
244     },
245     hide : function()
246     {
247          
248         if (!this.el) {
249             return;
250         }
251         //this.el.setXY([0,0]);
252         this.el.removeClass('in');
253         //this.el.hide();
254         
255     }
256     
257 });
258  
259
260