Using a slide-out menu for each tab in <md-tabs> - angularjs

I want to built a slide out menu for my application using angular material.
I have certain tabs, each of which will have a slide-out menu with different content. I have implemented this in the following manner:
<md-tab ng-repeat="tab in categories"
ng-disabled="tab.disabled"
label="{{tab.title}}"
md-on-select="setArray(tab.title,0)">
<!--Include a dropdown of sub-categories here -->
<div layout="row">
<md-menu id="sub-cat-button">
<md-button ng-click="$mdOpenMenu($event)" class="md-icon-button" aria-label="Open sample menu">
<span class="glyphicon glyphicon-menu-down" aria-hidden="true"></span>
</md-button>
<md-menu-content width=6>
<md-menu-item ng-repeat="sub_cat in tab.sub_cat">
<md-button ng-click="setArray(sub_cat,1)">{{sub_cat}}</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
<ol class="breadcrumb" id="breadcrumb">
<li ng-repeat="link in bread">{{link}}</li>
</ol>
<md-sidenav md-component-id="right" class="md-sidenav-right">
<md-button ng-click="openRightMenu()">
<i class="material-icons">keyboard_arrow_right</i>
</md-button>
</md-sidenav>
<md-content>
<md-button ng-click="openRightMenu()">
<span class="glyphicon glyphicon-filter" aria-hidden="true"></span>
</md-button>
</md-content>
</div>
<div class="demo-tab tab{{$index%4}}" id="scrollable-tabs">
<div class="row" infinite-scroll="loadMore()" infinite-scroll-disabled="busy">
<div ng-repeat="p in products">
<h3><div class="well">{{p.id}}</div></h3>
</div>
</div>
<div ng-show="busy">Loading more products....</div>
<br/>
</div>
</md-tab>
The problem here is that, the menu slides out and can be seen only for tab 1. If I go to tab 5 and click on the filter button to open that menu, the menu is not seen slid out with tab 6 , but it has been already slid out for tab 1. you can view it slide out when you go to tab 1.
How do I make it visible for each tab, because the content of the slide out menu is dependent on the tab which is opened?

Related

ng-if inside of md-menu not opening properly

I have an ng-if inside of an <md-menu> tag that toggles more info when the user clicks on the item in the menu. However, when I click on the menu item, the menu closes. When I reopen it, the DOM displays that the extra info is showing but it is not actually being displayed in the menu and the menu has not resized to fit what should be there.
Here is my menu code:
<md-menu>
<md-button aria-label="Open Notifications Menu" ng-click="$mdOpenMenu($event)">
<md-icon md-svg-icon="bell"></md-icon>
</md-button>
<md-menu-content width="5">
<md-menu-item ng-repeat="notification in vm.notificationList">
<div aria-label="Notification" ng-click="vm.showDetails(notification)" md-prevent-menu-close="md-prevent-menu-close">
<div layout="column">
<div flex layout="row" layout-align="start center">
<span flex><b>{{notification.title}}</b></span>
<span style="opacity: 0.5">{{vm.getTime(notification)}}</span>
</div>
<div ng-show="notification.showDetails">
<span style="opacity: 0.7">{{notification.details}}</span>
</div>
</div>
</div>
</md-menu-item>
</md-menu-content>
</md-menu>
Here is the function for the ng-click in typescript:
showDetails(message: any): void {
message.showDetails = !message.showDetails;
}
EDIT
I fixed the problem with the menu closing using md-prevent-menu-close... duh. I've updated the html. The problem is still the same though, the menu does not change size to display the new data.
EDIT
I fixed the problem with the content not showing by removing the md-button and replacing it with a div. I updated the html accordingly. The only problem now is that the menu will not adjust its height to fit the new content neatly.
Is this the kind of thing that you want? - CodePen
Markup
<div ng-controller="AppCtrl as vm" ng-cloak="" ng-app="MyApp">
<md-menu>
<md-button aria-label="Open Notifications Menu" ng-click="$mdOpenMenu($event)">
Bell
</md-button>
<md-menu-content width="5">
<md-menu-item ng-repeat="notification in vm.notificationList" ng-click="vm.showDetails($index)" md-prevent-menu-close="md-prevent-menu-close" aria-label="Notification">
<div layout="column" flex>
<div flex layout="row" layout-align="start center">
<span flex><b>{{notification.title}}</b></span>
<span style="opacity: 0.5">22-08-2016 09:06</span>
</div>
<div ng-if="notification.showDetails">
<span style="opacity: 0.7">{{notification.details}}</span>
</div>
</div>
</md-menu-item>
</md-menu-content>
</md-menu>
</div>
JS
angular.module('MyApp',['ngMaterial', 'ngMessages'])
.controller('AppCtrl', function() {
var vm = this;
vm.notificationList = [
{title: "Read", details: "Enjoy the book", showDetails: false},
{title: "Eat", details: "You're hungry", showDetails: false},
{title: "Dring", details: "Have a pint of lager", showDetails: false}
]
vm.showDetails = function (index) {
vm.notificationList[index].showDetails = !vm.notificationList[index].showDetails;
}
});
Use ng-show not ng-if. ng-if removes elements from the DOM permanently if some condition is no satisfied. ng-show just toggles between whether or not an element is hidden.

Angular Material: Each md-list-item takes full page width and Sidenav have long scrollbar

I'm trying to create angular material sidenav with list of menu items. When Im running the code on local machine, Each md-list-items takes fullpage width and sidenav have long scroll bar.
But When I run the same code on codepen.io, It displayed correctly.
<section layout="row" ng-controller="AppCtrl">
<md-sidenav class="md-sidenav-left md-whiteframe-z2" md-component-id="left" >
<md-toolbar ng-controller="LeftCtrl">
<div class="md-toolbar-tools">
<h1>Sidenav Right</h1>
<span flex></span>
<md-button class="md-icon-bitton" aria-label="Close Menu" ng-click="close()">
<md-tooltip md-direction="right">Close this menu</md-tooltip>
<md-icon md-font-icon="material-icons">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-content flex role="navigation">
<md-list>
<md-list-item>
<md-button>First Option</md-button>
</md-list-item>
<md-list-item>
<md-button>First Option</md-button>
</md-list-item>
<md-list-item>
<md-button>First Option</md-button>
</md-list-item>
</md-list>
</md-content>
</md-sidenav>
<md-content flex>
<md-toolbar>
<div class="md-toolbar-tools">
<md-button class="md-icon-button" aria-label="Settings" ng-click="toggleLeft()" ng-hide="isOpenLeft()">
<md-icon md-font-icon="material-icons">menu</md-icon>
</md-button>
<h2>
<span>Application Title</span>
</h2>
</div>
</md-toolbar>
</md-content>
</section>
Here is the codepen:http://codepen.io/nhere/pen/yOwJxE
Try to use the following structure
<md-list>
<md-item>
<md-item-content>
[Content Here]
</md-item-content>
</md-item>
</md-list>

sidenav not displaying properly in angularjs material design

This is my code.
<body>
<div ng-controller="MainCtrl as mc">
<md-content>
<md-toolbar md-scroll-shrink>
<div class="md-toolbar-tools">
<span flex="5"></span>
<md-button ui-sref="Home">
example.com
</md-button>
<span flex="20"></span>
<span>something something</span>
<span flex="20"></span>
<md-button ng-show="!login" aria-label="Settings" ui-sref="Login">
Login / Register
</md-button>
<md-button ng-show="login" class="md-icon-button" aria-label="Settings" ng-click="openRightMenu()">
<md-icon class="material-icons">menu</md-icon>
</md-button>
<md-sidenav md-component-id="right" class="md-sidenav-right">
<md-button href="http://google.com">Google</md-button>
</md-sidenav>
</div>
</md-toolbar>
</md-content>
<div ui-view></div>
</div>
</body>
When i click on button to open right side nav it opens but height is same as of toolbar.
How to display sidenav of standard size?
put md-sidenav outside md-content
<div ng-controller="MainCtrl as mc">
<md-content>
</md-content>
<md-sidenav md-component-id="right" class="md-sidenav-right">
<md-button href="http://google.com">Google</md-button>
</md-sidenav>
<div ui-view></div>
if it's inside md-toolbar it will take toolbar height

md-menu inside md-list-item as a second action button

I have got the code below in my project and I have got this problem. When I will add the md-menu component into my dynamically generated (ng-repeat) md-list component, it will show this error in JS console:
Error: Invalid HTML for md-menu: Expected two children elements.
My HTML code:
<md-card>
<md-card-content>
<h2>Menu</h2>
<md-subheader class="md-no-sticky">List</md-subheader>
<md-list-item ng-repeat="playlist in playlists" ng-click="someAction()">
<p>{{playlist[1]}}</p>
<md-menu>
<md-icon aria-label="Action" ng-click="$mdOpenMenu($event)" class="md-secondary md-hue-3 material-icons">create</md-icon>
<md-menu-content>
<md-menu-item><md-button ng-click="">Edit</md-button></md-menu-item>
<md-menu-item><md-button ng-click="">Remove</md-button></md-menu-item>
</md-menu-content>
</md-menu>
</md-list-item>
</md-card-content>
</md-card>
Can you help me to solve this issue please?
I think, that the problem is when the code is builded, it looks different and then md-menu component has got 2 child inside (2 button), but I don't know, how to resolve this.
Here is the builded code:
<md-list-item class="md-with-secondary ng-scope md-clickable" tabindex="-1" role="listitem" ng-repeat="playlist in playlists">
<button tabindex="0" ng-click="someAction()" class="md-no-style md-button md-ink-ripple" ng-transclude="">
<div class="md-list-item-inner ng-scope">
<p class="ng-binding">test</p>
<md-menu class="md-menu ng-scope">
<md-menu-content>
<md-menu-item role="menuitem">
<button tabindex="0" type="button" ng-click="" class="md-button md-ink-ripple" ng-transclude="">
<span class="ng-scope">Edit</span>
</button>
</md-menu-item>
<md-menu-item role="menuitem">
<button tabindex="0" ng-click="" class="md-button md-ink-ripple" ng-transclude="">
<span class="ng-scope">Remove</span>
</button>
</md-menu-item>
</md-menu-content>
</md-menu>
</div>
<div style="" class="md-ripple-container"></div>
<div style="" class="md-ripple-container"></div>
</button>
<button tabindex="0" ng-click="$mdOpenMenu($event)" class="md-secondary-container md-icon-button md-button md-ink-ripple" ng-transclude="">
<md-icon tabindex="-1" aria-label="Open Chat" class="md-hue-3 material-icons ng-scope ng-isolate-scope">create</md-icon>
</button>
</md-list-item>
I also couldn't use md-menu inside md-list-item as a second action button when I was using Angular Material 1.0.0 RC1 but when I upgraded both js and css of Angular Material to 1.1.0 RC4 it worked. The working code is something like this and please notice the "md-secondary" class needs to be assigned to "md-menu":
<md-list flex>
<md-subheader class="md-no-sticky">sub header</md-subheader>
<md-list-item ng-click="goToPerson(person.name, $event)" class="md-2-line" ng-repeat="user in userManagement.users">
<img alt="{{ 'person.name' }}" ng-src="https://pixabay.com/static/uploads/photo/2014/03/25/16/54/user-297566_960_720.png" class="md-avatar"/>
<div class="md-list-item-text">
<h3>{{ user.firstName }} {{ user.lastName }} </h3>
<p>{{ user.email }} </p>
</div>
<md-menu md-position-mode="target-right target" class="md-secondary">
<md-button aria-label="Open demo menu" class="md-icon-button" ng-click="$mdOpenMenu($event)">
<md-icon md-menu-origin>menu</md-icon>
</md-button>
<md-menu-content width="4">
<md-menu-item ng-repeat="item in [1, 2, 3]">
<md-button ng-click="ctrl.announceClick($index)">
<div layout="row" flex>
<p flex>Option {{item}}</p>
<md-icon md-menu-align-target md-svg-icon="call:portable-wifi-off" style="margin: auto 3px auto 0;"></md-icon>
</div>
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
</md-list-item>
</md-list>
Every md-menu must specify exactly two child elements. The first
element is what is left in the DOM and is used to open the menu. This
element is called the trigger element.
https://material.angularjs.org/latest/api/directive/mdMenu
I think your ng-click="$mdOpenMenu($event)" needs to be on a md-button element, not the md-icon
go to source code of angular-material.js and add/modify that part... I will generate menu as secondary-item outside the item.
// Check for a secondary item and move it outside
if ( secondaryItem && (
isMdMenu(secondaryItem) ||
secondaryItem.hasAttribute('ng-click') ||
( tAttrs.ngClick &&
isProxiedElement(secondaryItem) )
)) {
tEl.addClass('md-with-secondary');
tEl.append(secondaryItem);
}
function isMdMenu(el) {
var nodeName = el.nodeName.toUpperCase();
return nodeName == "MD-MENU";
}

FAB Speed Dial and Simple dropdown menu not working

I've followed the demo as given in the angular material site.
https://material.angularjs.org/latest/#/demo/material.components.menu
I'm facing a problem where the simple dropdown menus and speed dials are just static and not initalized.
Can't seem to figure out what I am missing.
<div layout="column">
<md-content class="md-padding" layout="column">
<div class="lock-size" layout="row" layout-align="center center">
<md-fab-speed-dial md-open="false" md-direction="up"
ng-class="md-fling">
<md-fab-trigger>
<md-button aria-label="menu" class="md-fab md-warn">
<i class="fa fa-car"></i>
</md-button>
</md-fab-trigger>
<md-fab-actions>
<md-button aria-label="twitter" class="md-fab md-raised md-mini">
<i class="fa fa-car"></i>
</md-button>
<md-button aria-label="facebook" class="md-fab md-raised md-mini">
<i class="fa fa-car"></i>
</md-button>
<md-button aria-label="Google hangout" class="md-fab md-raised md-mini">
<i class="fa fa-car"></i>
</md-button>
</md-fab-actions>
</md-fab-speed-dial>
</div>
</md-content>
</div>
I changed the ng-class attribute on the <md-fab-speed-dial> tag to simply class, and it works now. Have a look at this link from the Angular Material site.
In your case, you should have:
<md-fab-speed-dial md-open="false" md-direction="up" class="md-fling">

Resources