sync
[roojs1] / Roo / bootstrap / Menu.js
index a40d84e..47bc169 100644 (file)
@@ -11,6 +11,8 @@
  * Bootstrap Menu class - container for MenuItems
  * @cfg {String} type (dropdown|treeview|submenu) type of menu
  * @cfg {bool} hidden  if the menu should be hidden when rendered.
+ * @cfg {bool} stopEvent (true|false)  Stop event after trigger press (default true)
+ * @cfg {bool} isLink (true|false)  the menu has link disable auto expand and collaspe (default false)
  * 
  * @constructor
  * Create a new Menu
@@ -23,16 +25,18 @@ Roo.bootstrap.Menu = function(config){
     if (this.registerMenu && this.type != 'treeview')  {
         Roo.bootstrap.MenuMgr.register(this);
     }
+    
+    
     this.addEvents({
         /**
          * @event beforeshow
-         * Fires before this menu is displayed
+         * Fires before this menu is displayed (return false to block)
          * @param {Roo.menu.Menu} this
          */
         beforeshow : true,
         /**
          * @event beforehide
-         * Fires before this menu is hidden
+         * Fires before this menu is hidden (return false to block)
          * @param {Roo.menu.Menu} this
          */
         beforehide : true,
@@ -97,10 +101,16 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
     menuItems :false, // stores the menu items..
     
     hidden:true,
-    
         
     parentMenu : false,
     
+    stopEvent : true,
+    
+    isLink : false,
+    
+    container_method : 'getDocumentBody',
+    
+    
     getChildContainer : function() {
         return this.el;  
     },
@@ -137,8 +147,13 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
         
         this.triggerEl.on(Roo.isTouch ? 'touchstart' : 'mouseup', this.onTriggerPress, this);
         
-        this.triggerEl.addClass('dropdown-toggle');
-        
+       
+       if (this.triggerEl.hasClass('nav-item') && this.triggerEl.select('.nav-link',true).length) {
+           // dropdown toggle on the 'a' in BS4?
+           this.triggerEl.select('.nav-link',true).first().addClass('dropdown-toggle');
+       } else if (!this.triggerEl.hasClass('no-dropdown-toggle')) {
+           this.triggerEl.addClass('dropdown-toggle');
+       }
         if (Roo.isTouch) {
             this.el.on('touchstart'  , this.onTouch, this);
         }
@@ -206,7 +221,10 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
         
         var _this = this;
         
-        (function() { _this.hide(); }).defer(500);
+        if(!t.href.length || t.href == '#'){
+            (function() { _this.hide(); }).defer(100);
+        }
+        
     },
     
     onMouseOver : function(e){
@@ -223,7 +241,7 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
     isVisible : function(){
         return !this.hidden;
     },
-     onMouseOut : function(e){
+    onMouseOut : function(e){
         var t  = this.findTargetItem(e);
         
         //if(t ){
@@ -243,12 +261,17 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
      * the element (defaults to this.defaultAlign)
      * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
      */
-    show : function(el, pos, parentMenu){
-        this.parentMenu = parentMenu;
+    show : function(el, pos, parentMenu)
+    {
+        if (false === this.fireEvent("beforeshow", this)) {
+           Roo.log("show canceled");
+           return;
+       }
+       this.parentMenu = parentMenu;
         if(!this.el){
             this.render();
         }
-        this.fireEvent("beforeshow", this);
+        
         this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
     },
      /**
@@ -270,12 +293,21 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
         this.hideMenuItems();
         this.hidden = false;
         this.triggerEl.addClass('open');
+       this.el.addClass('show');
         
-        if(this.el.getWidth() + xy[0] > Roo.lib.Dom.getViewWidth()){
+        // reassign x when hitting right
+        if(this.el.getWidth() + xy[0] >= Roo.lib.Dom.getViewWidth()){
             xy[0] = xy[0] - this.el.getWidth() + this.triggerEl.getWidth();
         }
         
-        if(this.el.getStyle('top').slice(-1) != "%"){
+        // reassign y when hitting bottom
+        if(this.el.getHeight() + xy[1] >= Roo.lib.Dom.getViewHeight()){
+            xy[1] = xy[1] - this.el.getHeight() - this.triggerEl.getHeight();
+        }
+        
+        // but the list may align on trigger left or trigger top... should it be a properity?
+        
+        if(this.el.getStyle('top') != 'auto' && this.el.getStyle('top').slice(-1) != "%"){
             this.el.setXY(xy);
         }
         
@@ -302,15 +334,19 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
      */
     hide : function(deep)
     {
-        
+        if (false === this.fireEvent("beforehide", this)) {
+           Roo.log("hide canceled");
+           return;
+       }
         this.hideMenuItems();
         if(this.el && this.isVisible()){
-            this.fireEvent("beforehide", this);
+           
             if(this.activeItem){
                 this.activeItem.deactivate();
                 this.activeItem = null;
             }
             this.triggerEl.removeClass('open');;
+           this.el.removeClass('show');
             this.hidden = true;
             this.fireEvent("hide", this);
         }
@@ -346,15 +382,22 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
             return;
         }
         
+        if(e.getTarget().nodeName.toLowerCase() !== 'i' && this.isLink){
+            return;
+        }
+        
         if (this.isVisible()) {
             Roo.log('hide');
             this.hide();
         } else {
             Roo.log('show');
-            this.show(this.triggerEl, false, false);
+            this.show(this.triggerEl, '?', false);
+        }
+        
+        if(this.stopEvent || e.getTarget().nodeName.toLowerCase() === 'i'){
+            e.stopEvent();
         }
         
-        e.stopEvent();
     },
        
     
@@ -364,16 +407,11 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
         if (!this.el) { 
             return;
         }
-        //$(backdrop).remove()
+        
         this.el.select('.open',true).each(function(aa) {
             
             aa.removeClass('open');
-          //var parent = getParent($(this))
-          //var relatedTarget = { relatedTarget: this }
-          
-           //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
-          //if (e.isDefaultPrevented()) return
-           //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+         
         });
     },
     addxtypeChild : function (tree, cntr) {
@@ -387,6 +425,12 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
     {
         Roo.log(this.el);
         return this.el;
+    },
+    
+    clear : function()
+    {
+        this.getEl().dom.innerHTML = '';
+        this.menuitems.clear();
     }
 });