fb3b0649cee6dda6101fd89bf6e66f9a0bc5fdfa
[roojs1] / Roo / bootstrap / Menu.js
1 /*
2  * - LGPL
3  *
4  * menu
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.Menu
10  * @extends Roo.bootstrap.Component
11  * Bootstrap Menu class - container for MenuItems
12  * @cfg {String} type (dropdown|treeview|submenu) type of menu
13  * 
14  * @constructor
15  * Create a new Menu
16  * @param {Object} config The config object
17  */
18
19
20 Roo.bootstrap.Menu = function(config){
21     Roo.bootstrap.Menu.superclass.constructor.call(this, config);
22     if (this.registerMenu) {
23         Roo.bootstrap.MenuMgr.register(this);
24     }
25     this.addEvents({
26         /**
27          * @event beforeshow
28          * Fires before this menu is displayed
29          * @param {Roo.menu.Menu} this
30          */
31         beforeshow : true,
32         /**
33          * @event beforehide
34          * Fires before this menu is hidden
35          * @param {Roo.menu.Menu} this
36          */
37         beforehide : true,
38         /**
39          * @event show
40          * Fires after this menu is displayed
41          * @param {Roo.menu.Menu} this
42          */
43         show : true,
44         /**
45          * @event hide
46          * Fires after this menu is hidden
47          * @param {Roo.menu.Menu} this
48          */
49         hide : true,
50         /**
51          * @event click
52          * Fires when this menu is clicked (or when the enter key is pressed while it is active)
53          * @param {Roo.menu.Menu} this
54          * @param {Roo.menu.Item} menuItem The menu item that was clicked
55          * @param {Roo.EventObject} e
56          */
57         click : true,
58         /**
59          * @event mouseover
60          * Fires when the mouse is hovering over this menu
61          * @param {Roo.menu.Menu} this
62          * @param {Roo.EventObject} e
63          * @param {Roo.menu.Item} menuItem The menu item that was clicked
64          */
65         mouseover : true,
66         /**
67          * @event mouseout
68          * Fires when the mouse exits this menu
69          * @param {Roo.menu.Menu} this
70          * @param {Roo.EventObject} e
71          * @param {Roo.menu.Item} menuItem The menu item that was clicked
72          */
73         mouseout : true,
74         /**
75          * @event itemclick
76          * Fires when a menu item contained in this menu is clicked
77          * @param {Roo.menu.BaseItem} baseItem The BaseItem that was clicked
78          * @param {Roo.EventObject} e
79          */
80         itemclick: true
81     });
82     this.menuitems = new Roo.util.MixedCollection(false, function(o) { return o.el.id; });
83 };
84
85 Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
86     
87    /// html : false,
88     //align : '',
89     triggerEl : false,  // is this set by component builder? -- it should really be fetched from parent()???
90     type: false,
91     /**
92      * @cfg {Boolean} registerMenu True (default) - means that clicking on screen etc. hides it.
93      */
94     registerMenu : true,
95     
96     menuItems :false, // stores the menu items..
97     
98     hidden:true,
99     
100     parentMenu : false,
101     
102     getChildContainer : function() {
103         return this.el;  
104     },
105     
106     getAutoCreate : function(){
107          
108         //if (['right'].indexOf(this.align)!==-1) {
109         //    cfg.cn[1].cls += ' pull-right'
110         //}
111         
112         
113         var cfg = {
114             tag : 'ul',
115             cls : 'dropdown-menu' ,
116             style : 'z-index:1000'
117             
118         }
119         
120         if (this.type === 'submenu') {
121             cfg.cls = 'submenu active';
122         }
123         if (this.type === 'treeview') {
124             cfg.cls = 'treeview-menu';
125         }
126         
127         return cfg;
128     },
129     initEvents : function() {
130         
131        // Roo.log("ADD event");
132        // Roo.log(this.triggerEl.dom);
133        
134         this.triggerEl.on('click', this.onTriggerPress, this);
135         this.triggerEl.addClass('dropdown-toggle');
136         this.el.on(Roo.isTouch ? 'touchstart' : 'click'   , this.onClick, this);
137
138         this.el.on("mouseover", this.onMouseOver, this);
139         this.el.on("mouseout", this.onMouseOut, this);
140         
141         
142     },
143     findTargetItem : function(e){
144         var t = e.getTarget(".dropdown-menu-item", this.el,  true);
145         if(!t){
146             return false;
147         }
148         //Roo.log(t);         Roo.log(t.id);
149         if(t && t.id){
150             //Roo.log(this.menuitems);
151             return this.menuitems.get(t.id);
152             
153             //return this.items.get(t.menuItemId);
154         }
155         
156         return false;
157     },
158     onClick : function(e){
159         Roo.log("menu.onClick");
160         var t = this.findTargetItem(e);
161         if(!t){
162             return;
163         }
164         Roo.log(e);
165         /*
166         if (Roo.isTouch && e.type == 'touchstart' && t.menu  && !t.disabled) {
167             if(t == this.activeItem && t.shouldDeactivate(e)){
168                 this.activeItem.deactivate();
169                 delete this.activeItem;
170                 return;
171             }
172             if(t.canActivate){
173                 this.setActiveItem(t, true);
174             }
175             return;
176             
177             
178         }
179         */
180        
181        if(t.isContainer){
182            return;
183        }
184        
185         Roo.log('pass click event');
186         
187         t.onClick(e);
188         
189         this.fireEvent("click", this, t, e);
190         
191         this.hide();
192     },
193      onMouseOver : function(e){
194         var t  = this.findTargetItem(e);
195         //Roo.log(t);
196         //if(t){
197         //    if(t.canActivate && !t.disabled){
198         //        this.setActiveItem(t, true);
199         //    }
200         //}
201         
202         this.fireEvent("mouseover", this, e, t);
203     },
204     isVisible : function(){
205         return !this.hidden;
206     },
207      onMouseOut : function(e){
208         var t  = this.findTargetItem(e);
209         
210         //if(t ){
211         //    if(t == this.activeItem && t.shouldDeactivate(e)){
212         //        this.activeItem.deactivate();
213         //        delete this.activeItem;
214         //    }
215         //}
216         this.fireEvent("mouseout", this, e, t);
217     },
218     
219     
220     /**
221      * Displays this menu relative to another element
222      * @param {String/HTMLElement/Roo.Element} element The element to align to
223      * @param {String} position (optional) The {@link Roo.Element#alignTo} anchor position to use in aligning to
224      * the element (defaults to this.defaultAlign)
225      * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
226      */
227     show : function(el, pos, parentMenu){
228         this.parentMenu = parentMenu;
229         if(!this.el){
230             this.render();
231         }
232         this.fireEvent("beforeshow", this);
233         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
234     },
235      /**
236      * Displays this menu at a specific xy position
237      * @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based)
238      * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
239      */
240     showAt : function(xy, parentMenu, /* private: */_e){
241         this.parentMenu = parentMenu;
242         if(!this.el){
243             this.render();
244         }
245         if(_e !== false){
246             this.fireEvent("beforeshow", this);
247             
248             //xy = this.el.adjustForConstraints(xy);
249         }
250         //this.el.setXY(xy);
251         //this.el.show();
252         this.hideMenuItems();
253         this.hidden = false;
254         this.triggerEl.addClass('open');
255         this.focus();
256         this.fireEvent("show", this);
257     },
258     
259     focus : function(){
260         return;
261         if(!this.hidden){
262             this.doFocus.defer(50, this);
263         }
264     },
265
266     doFocus : function(){
267         if(!this.hidden){
268             this.focusEl.focus();
269         }
270     },
271
272     /**
273      * Hides this menu and optionally all parent menus
274      * @param {Boolean} deep (optional) True to hide all parent menus recursively, if any (defaults to false)
275      */
276     hide : function(deep){
277         
278         this.hideMenuItems();
279         if(this.el && this.isVisible()){
280             this.fireEvent("beforehide", this);
281             if(this.activeItem){
282                 this.activeItem.deactivate();
283                 this.activeItem = null;
284             }
285             this.triggerEl.removeClass('open');;
286             this.hidden = true;
287             this.fireEvent("hide", this);
288         }
289         if(deep === true && this.parentMenu){
290             this.parentMenu.hide(true);
291         }
292     },
293     
294     onTriggerPress  : function(e)
295     {
296         
297         Roo.log('trigger press');
298         //Roo.log(e.getTarget());
299        // Roo.log(this.triggerEl.dom);
300         if (Roo.get(e.getTarget()).findParent('.dropdown-menu') || Roo.get(e.getTarget()).findParent('.user-menu')) {
301             return;
302         }
303         
304         if (this.isVisible()) {
305             Roo.log('hide');
306             this.hide();
307         } else {
308             this.show(this.triggerEl, false, false);
309         }
310         
311         
312     },
313     
314          
315        
316     
317     hideMenuItems : function()
318     {
319         //$(backdrop).remove()
320         Roo.select('.open',true).each(function(aa) {
321             
322             aa.removeClass('open');
323           //var parent = getParent($(this))
324           //var relatedTarget = { relatedTarget: this }
325           
326            //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
327           //if (e.isDefaultPrevented()) return
328            //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
329         })
330     },
331     addxtypeChild : function (tree, cntr) {
332         var comp= Roo.bootstrap.Menu.superclass.addxtypeChild.call(this, tree, cntr);
333           
334         this.menuitems.add(comp);
335         return comp;
336
337     },
338     getEl : function()
339     {
340         Roo.log(this.el);
341         return this.el;
342     }
343 });
344
345  
346