9 * @class Roo.bootstrap.Menu
10 * @extends Roo.bootstrap.Component
11 * Bootstrap Menu class - container for MenuItems
12 * @cfg {String} type type of menu
16 * @param {Object} config The config object
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);
28 * Fires before this menu is displayed
29 * @param {Roo.menu.Menu} this
34 * Fires before this menu is hidden
35 * @param {Roo.menu.Menu} this
40 * Fires after this menu is displayed
41 * @param {Roo.menu.Menu} this
46 * Fires after this menu is hidden
47 * @param {Roo.menu.Menu} this
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
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
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
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
82 this.menuitems = new Roo.util.MixedCollection(false, function(o) { return o.el.id; });
85 Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component, {
89 triggerEl : false, // is this set by component builder? -- it should really be fetched from parent()???
92 * @cfg {Boolean} registerMenu True (default) - means that clicking on screen etc. hides it.
96 menuItems :false, // stores the menu items..
102 getChildContainer : function() {
106 getAutoCreate : function(){
108 //if (['right'].indexOf(this.align)!==-1) {
109 // cfg.cn[1].cls += ' pull-right'
113 cls : 'dropdown-menu' ,
114 style : 'z-index:1000'
118 if (this.type === 'submenu') {
119 cfg.cls = 'submenu active'
124 initEvents : function() {
126 // Roo.log("ADD event");
127 // Roo.log(this.triggerEl.dom);
128 this.triggerEl.on('click', this.onTriggerPress, this);
129 this.triggerEl.addClass('dropdown-toggle');
130 this.el.on(Roo.isTouch ? 'touchstart' : 'click' , this.onClick, this);
132 this.el.on("mouseover", this.onMouseOver, this);
133 this.el.on("mouseout", this.onMouseOut, this);
137 findTargetItem : function(e){
138 var t = e.getTarget(".dropdown-menu-item", this.el, true);
142 //Roo.log(t); Roo.log(t.id);
144 //Roo.log(this.menuitems);
145 return this.menuitems.get(t.id);
147 //return this.items.get(t.menuItemId);
152 onClick : function(e){
153 Roo.log("menu.onClick");
154 var t = this.findTargetItem(e);
160 if (Roo.isTouch && e.type == 'touchstart' && t.menu && !t.disabled) {
161 if(t == this.activeItem && t.shouldDeactivate(e)){
162 this.activeItem.deactivate();
163 delete this.activeItem;
167 this.setActiveItem(t, true);
174 Roo.log('pass click event');
178 this.fireEvent("click", this, t, e);
182 onMouseOver : function(e){
183 var t = this.findTargetItem(e);
186 // if(t.canActivate && !t.disabled){
187 // this.setActiveItem(t, true);
191 this.fireEvent("mouseover", this, e, t);
193 isVisible : function(){
196 onMouseOut : function(e){
197 var t = this.findTargetItem(e);
200 // if(t == this.activeItem && t.shouldDeactivate(e)){
201 // this.activeItem.deactivate();
202 // delete this.activeItem;
205 this.fireEvent("mouseout", this, e, t);
210 * Displays this menu relative to another element
211 * @param {String/HTMLElement/Roo.Element} element The element to align to
212 * @param {String} position (optional) The {@link Roo.Element#alignTo} anchor position to use in aligning to
213 * the element (defaults to this.defaultAlign)
214 * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
216 show : function(el, pos, parentMenu){
217 this.parentMenu = parentMenu;
221 this.fireEvent("beforeshow", this);
222 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
225 * Displays this menu at a specific xy position
226 * @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based)
227 * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
229 showAt : function(xy, parentMenu, /* private: */_e){
230 this.parentMenu = parentMenu;
235 this.fireEvent("beforeshow", this);
237 //xy = this.el.adjustForConstraints(xy);
241 this.hideMenuItems();
243 this.triggerEl.addClass('open');
245 this.fireEvent("show", this);
251 this.doFocus.defer(50, this);
255 doFocus : function(){
257 this.focusEl.focus();
262 * Hides this menu and optionally all parent menus
263 * @param {Boolean} deep (optional) True to hide all parent menus recursively, if any (defaults to false)
265 hide : function(deep){
267 this.hideMenuItems();
268 if(this.el && this.isVisible()){
269 this.fireEvent("beforehide", this);
271 this.activeItem.deactivate();
272 this.activeItem = null;
274 this.triggerEl.removeClass('open');;
276 this.fireEvent("hide", this);
278 if(deep === true && this.parentMenu){
279 this.parentMenu.hide(true);
283 onTriggerPress : function(e)
286 Roo.log('trigger press');
287 //Roo.log(e.getTarget());
288 // Roo.log(this.triggerEl.dom);
289 if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
292 if (this.isVisible()) {
296 this.show(this.triggerEl, false, false);
305 hideMenuItems : function()
307 //$(backdrop).remove()
308 Roo.select('.open',true).each(function(aa) {
310 aa.removeClass('open');
311 //var parent = getParent($(this))
312 //var relatedTarget = { relatedTarget: this }
314 //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
315 //if (e.isDefaultPrevented()) return
316 //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
319 addxtypeChild : function (tree, cntr) {
320 var comp= Roo.bootstrap.Menu.superclass.addxtypeChild.call(this, tree, cntr);
322 this.menuitems.add(comp);