10
votes

I'm using Angular Material menubar to show a menu and the sub menu under each menu item. I've added ng-click event to open the submenu. But the menu is still opening on mouse hover on the parent menu item. Not only this, as I have two sub menus, for the first submenu item, the submenu is opening on mouse hover but the second submenu is not opening on mouse hover. How i can stop this menu opening on mouse over. I tried to stop event propagation on mouseenter on the parent menu item. But then at the time of opening second submenu the first submenu is not being hidden. Please help me how to fix it.

<div ng-controller="DemoBasicCtrl as ctrl" ng-cloak="" class="menuBardemoBasicUsage" ng-app="MyApp">

    <md-menu-bar>
      <md-menu>
        <button ng-click="$mdOpenMenu()">
          File
        </button>
        <md-menu-content>
          <md-menu-item>
            <md-menu>
              <md-button ng-click="$mdOpenMenu()">New</md-button>
              <md-menu-content>
                <md-menu-item><md-button ng-click="ctrl.sampleAction('New Document', $event)">Document</md-button></md-menu-item>
              </md-menu-content>
            </md-menu>
          </md-menu-item>
                        <md-menu-item>
            <md-menu>
              <md-button ng-click="$mdOpenMenu()">New</md-button>
              <md-menu-content>
                <md-menu-item><md-button ng-click="ctrl.sampleAction('New Document', $event)">Document</md-button></md-menu-item>
              </md-menu-content>
            </md-menu>
          </md-menu-item>

        </md-menu-content>
      </md-menu>

    </md-menu-bar>

My existing demo code is at demo.

2
have you pasted the full controller code? - Sajeetharan
Actually according to angular material doc, those codes on controller are relevant to the demo. But those are not necessary to use angular material menubar itself. I mean we can ignore those filters, configs & controllers in the demo. - Indranil Mondal
Did you end up finding a solution to this? - adamdport
No, no luck yet. Waiting for angular material to fix it. - Indranil Mondal
You should stop event propagation on mouseenter on the child menu not on the parent. - Adrien

2 Answers

4
votes

Unfortunately Google is not fixing many of the Angular Material 1 issues, in favor of version 2.
I think this could be a way to encourage people to switch to Angular v2...

Anyway - I have solved the hover issue by stopping the event propagation on the menu item. Then adding a "mouse leave" event handler to the submenu container, that closes the current menu.

Controller -

    $scope.noop = function(event){
        event.stopImmediatePropagation();
    };

    $scope.closeSubMenu = function(event){
        mdMenu.hide();
    }

View -

<md-menu-item ng-repeat="item in menu.items" >
    <md-menu-item>
        <md-menu>
            <md-button ng-click="$mdOpenMenu($event)" ng-mouseenter="noop($event)">{{item.title}}</md-button>
            <md-menu-content ng-mouseleave="closeSubMenu($event)" >
                <md-menu-item ng-repeat="subitem in item.items">
                    <md-button ng-click="$location.url(subitem.location)">{{subitem.title}}</md-button>
                </md-menu-item>
            </md-menu-content>
        </md-menu>
    </md-menu-item>
</md-menu-item>
-2
votes

it is very simple here is an answer, if you use bower to install angular-material, you need to:

  1. go to /bower-components/angular-material/modules/js folder
  2. open menu.js in any test editor such as visual code, sublime or atom
  3. go to find this line this.handleMenuItemHover = function(event) {

then use my fix:

this.handleMenuItemHover = function(event) {
if (self.isAlreadyOpening) return;
var nestedMenu = (
  event.target.querySelector('md-menu')
    || $mdUtil.getClosest(event.target, 'MD-MENU')
);
openMenuTimeout = $timeout(function() {
  if (nestedMenu) {
    nestedMenu = angular.element(nestedMenu).controller('mdMenu');
  }
  if (self.currentlyOpenMenu && self.currentlyOpenMenu != nestedMenu)    
 {
    var closeTo = self.nestLevel + 1;
    self.currentlyOpenMenu.close(true, { closeTo: closeTo });

    /******* david zhao: fix codes ******/
    if (!!nestedMenu) {
      self.isAlreadyOpening = true;
      nestedMenu.open();
    }

  } else if (nestedMenu && !nestedMenu.isOpen && nestedMenu.open) {
    self.isAlreadyOpening = true;
    nestedMenu.open();
  }
}, nestedMenu ? 100 : 250);
var focusableTarget = 
 event.currentTarget.querySelector('.md-button:not([disabled])');
focusableTarget && focusableTarget.focus();
};