I'm trying to have md-tabs or md-nav-tabs within a md-menu. Yes I know it is not good practice, but it does what I need, perfectly, if only it would stay open as the tabs are clicked.
So I found some answers here. https://github.com/angular/material/issues/4334 but the $timeout
isn't working right. Is there a solution to get this working? Is there an alternative. I really like animation of the sliding line under the horizontal buttons, and it is bonus points with the other animations.
So here is the code:
$scope.openMenu = function($mdOpenMenu, $event) {
var menu = $mdOpenMenu($event);
$timeout(function() {
var menuContent = document.getElementById('durationcontent');
function hasAnyAttribute(target, attrs) {
if (!target) return false;
for (var i = 0, attr; attr = attrs[i]; ++i) {
var altForms = [attr, "data-" + attr, "x-" + attr];
for (var j = 0, rawAttr; rawAttr = altForms[j]; ++j) {
if (target.hasAttribute(rawAttr)) {
return true;
}
}
}
return false;
};
function getClosest(el, tagName, onlyParent) {
if (el instanceof angular.element) el = el[0];
tagName = tagName.toUpperCase();
if (onlyParent) el = el.parentNode;
if (!el) return null;
do {
if (el.nodeName === tagName) {
return el;
}
} while (el = el.parentNode);
return null;
};
menuContent.parentElement.addEventListener('click', function(e) {
console.log('clicked');
var target = e.target;
do {
if (target === menuContent) return;
if (hasAnyAttribute(target, ["ng-click", "ng-href", "ui-sref", "md-nav-click"]) || target.nodeName == "MD-TAB" || target.nodeName == "BUTTON" || target.nodeName == "LI") {
var closestMenu = getClosest(target, "MD-MENU");
if (!target.hasAttribute("disabled") && (!closestMenu || closestMenu == opts.parent[0])) {
if (target.hasAttribute("md-menu-disable-close")) {
event.stopPropagation();
angular.element(target).triggerHandler('click');
}
return; //let it propagate
}
break;
}
} while (target = target.parentNode);
}, true);
});
};
}]);
I made a few tweaks to look for the right directives. It's original author, @clshortfuse github says it "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."
<md-menu ng-repeat="shoe in shoes">
<button ng-click="$mdOpenMenu()">
{{shoe.type}}
</button>
<md-menu-content>
<div ng-include="shoe.template"></div>
<p>the size is {{shoe.size}}</p>
</md-menu-content>
</md-menu>
and within the template
<md-tabs md-stretch-tabs="always" md-selcted="1">
<!-- ; $event.stopPropagation(); -->
<md-tab ng-repeat="w in shoe.wearers" label="{{$index +1}}" md-menu-disable-close="md-menu-disable-close" ng-click="openMenu($mdOpenMenu, $event)">
<md-content>{{w}}</md-content>
</md-tab>
</md-tabs>
I want the ux, of the horizontal sliding bar menu more than anything. I'm open to other suggestions, anything will help.
And, of course, here is the plunker: http://plnkr.co/edit/JhDhwkhO9RwLcuzDKU0v?p=preview