A little background: I needed a month picker so I started with md-menu as seen in this code pen
http://codepen.io/anon/pen/MwBMvW?editors=101
The issue I ran into was the menu closing on every click, I wanted the menu to stay open when the year is changed.
What would others think of adding an attribute along the lines of "md-menu-disable-close" to prevent a click from closing a menu?
Changing line 286 in https://github.com/angular/material/blob/master/src/components/menu/js/menuServiceProvider.js would allow for this.
if (!target.hasAttribute('disabled') && !target.hasAttribute('md-menu-disable-close') &&(!closestMenu || closestMenu == opts.parent[0])) {
close();
}
Interested to hear others thoughts or if someone else has another solution.
Thanks
If you need a quick workaround, don't use ng-click and register an onclick event instead and wrap it in $scope.$apply. Right now, coincidentally, I'm battling with the same issue.
Thanks clshortfuse, I was able to implement the method you suggested but it required me to use a setTimeout to wait for the menu to be built. Is there an event i could trigger this off of? I feel as if this may end up being something lost of us hit, is there a case for not having an attribute that disables the close?
$mdOpenMenu(ev);
setTimeout(function () {
$("#preYear").bind('click', function (e) {
scope.$apply(function () {
scope.year = scope.year - 1 ;
scope.setSelectedMonth();
});
e.stopPropagation()
});
$("#nextYear").bind('click', function (e) {
scope.$apply(function () {
scope.year++;
scope.setSelectedMonth();
});
e.stopPropagation()
});
},500);
+1
@ratscrew here's what i did:
http://codepen.io/team/AngularMaterial/pen/BNYppz
It's similar to yours, but I used $timeout instead. I had another issue because I NEEDED ng-click to be created because I have a button within a button that gets triggered so I had to clear it. Since $timeout is part of angular, I don't think there will be a timing issue.
Ideally speaking I would go through every child element and take the ng-click function and "move" it to onClick, but I couldn't figure out how to grab the ng-click function over javascript.
Edit: I didn't try with master and it's failing. Let me see what I can come up with
@ratscrew
New post because my old one wasn't using master:
http://codepen.io/anon/pen/LpPjBr
You need to intercept the click event on md-menu-content. From there you can handle if the event propagates. You can call stopPropagation immediately and handle click events on your own.
I actually replicated md-menu's capture logic. What's interesting is you can do this
angular.element(target).triggerHandler('click');
and it'll call ng-click but not fire md-menu's click capture.
This is a workaround that uses md-menu-disable-close but at least you don't have to fork it for to work. Hopefully somebody will write in support for this in the future.
Thanks @clshortfuse I like your workaround for now
@clshortfuse
Your solutions works great! One minor issue though. Could you explain the purpose of
&& (!closestMenu || closestMenu == opts.parent[0]) equates to false 100% of time for my usage since it always returns an element as it is in a md-menu and opts is undefined. I've removed this for my usage but just curious.
My structure is similar to md-menu -> md-menu-content -> div/directive -> div -> md-menu-item -> md-button.ng-click
@brianpkelley your first element in md-menu-content must be a md-menu-item
So, just add this as your first element:
<md-menu-item ng-show="false"><p></p></md-menu-item>
has anyone already made the restrict: 'A' directive which will work as does clshortfuse's ?:
usage would be something like:
<md-menu-item>
<md-button
ng-click="wontBreak()"
md-menu-disable-close="md-menu-disable-close"
>Don't break</md-button>
</md-menu-item>
@clshortfuse Your code is great, but every time you open menu, new click event added to menu items.
The md-menu component looks for clicks from elements that have one of these attributes ['ng-click', 'ng-href', 'ui-sref']. So, you can work around this issue by creating your own version of ng-click, and using that for any click events inside md-menu, like so:
app.directive('myClick', function ($parse, $rootScope) {
return {
restrict: 'A',
compile: function ($element, attrs) {
var fn = $parse(attrs.myClick, null, true);
return function myClick(scope, element) {
element.on('click', function (event) {
var callback = function () {
fn(scope, { $event: event });
};
scope.$apply(callback);
})
}
}
}
})
...and in your html...
<md-menu>
<md-button>Open Menu</md-button>
<md-menu-content>
<md-button my-click="doSomething()">Click me without closing the menu</button>
</md-menu-content>
</md-menu>
It's not ideal, but it'll get you by for now.
+1
Hi,
So I had a use-case, where I needed md-date-picker in md-menu, but it closes when I click on datepicker. Any workaround for this?
Has the fix gone live with the current release - 1.0.5, it is not fixed in 1.0.4.
Please look at this codepen.
That's an interesting edge case. The fix has gone live, but it won't work for md-date-picker, since you can't place the md-prevent-menu-close attribute on a button inside the md-select control.
I suggested a fix in a separate issue: https://github.com/angular/material/issues/6364
Solved this with the following: Assign onMouseDown event and add event.stopPropagation() to it.
Solved this using ngMouseup instead of ngClick. No stopPropagation() required.
As an update, you can use the md-prevent-menu-close attribute:
<md-button ng-click="clicked()" md-prevent-menu-close="md-prevent-menu-close"></md-button>
Most helpful comment
Solved this using
ngMouseupinstead ofngClick. NostopPropagation()required.