AngularJs dropdown menu-content covering menu button - angularjs

My dropdown menu content is covering up my dropdown button, any idea how to fix it? I want it to appear directly underneath my dropdown button. I have tried creating a class and style it in CSS as "position: absolute;" but it doesn't work.
Here is my code in angular:
<div ng-controller="Ctrll" ng-app="Fruit">
<div>
<md-menu>
<md-button ng-click="$mdOpenMenu()">Fruits
</md-button>
<md-menu-content class="dropdown" >
<md-menu-item >
<md-button ng-click="apple()">Apple</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="blueberry()">Blueberry </md-button>
</md-menu-item>
</md-menu>
</md-menu-content>
</div>
</div>
here is my Angular app
angular
.module('Fruit',['ngMaterial'])
.controller('Ctrll', function () {
var originatorEv;
this.openMenu = function($mdOpenMenu, ev) {
originatorEv = ev;
$mdOpenMenu(ev);
};
});
I have added it to codepen. Here is how my code looks like in action. http://codepen.io/zcook/pen/YqramL
Also, does anyone know how to change the color of the background of the dropdown menu content?

why can't you change the CSS property of class .md-open-menu-container.md-active?
.md-open-menu-container.md-active{
top: 45px !important;
}
Check this updated codepen

Related

how to change icon in button on click with Angular Js

I have the following code:
<md-button class="md-icon-button" aria-label="Favorite" hide-gt-sm ng-click="openLeftMenu()">
<md-icon><i class="material-icons">menu</i></md-icon>
</md-button>
As you can see, inside md-button tag I have md-icon which contains an i element. I want to change the i tag when I click the button. This icon should change back when I click it again. Simply, I want a toggle effect with two icons and I want to achieve this using Angularjs.
You can use ng-switch, like with password redaction:
<md-button ng-switch="vm.isPasswordVisible" ng-click="vm.isPasswordVisible=!vm.isPasswordVisible" ng-class="md-icon-button">
<md-icon ng-switch-when="false" md-font-library="material-icons"> visibility_off </md-icon>
<md-icon ng-switch-when="true" md-font-library="material-icons"> visibility </md-icon>
</md-button>
You can use the ng-class directive
CODE
<md-button class="md-icon-button" aria-label="Favorite" hide-gt-sm ng-click="toggleButton()">
<md-icon><i ng-class="{'material-icons' : toggle, 'material-icons2' : !toggle}">menu</i></md-icon>
</md-button>
CONTROLLER
$scope.toggleButton = function(){
$scope.toggle = !$scope.toggle;
}
You can use a toggle to do this and use the ng-class directive to select class depending on the toggle. Here's how you'd do it-
<div ng-init="icon='class1'">
<md-button class="md-icon-button" aria-label="Favorite" hide-gt-sm ng-click="openLeftMenu()">
<md-icon>
<i ng-class="icon">menu</i>
</md-icon>
</md-button>
</div>
In your openLeftMenu() function, handle the classes on click.
function openLeftMenu() {
...
if(icon==='class1'){
icon = 'class2';
} else {
icon = 'class1';
}
...
}
Here class1 and class2 are your icon classes.
Use a flag value set it to true/false and after clicking on the button change the value accordingly and use following code.
<md-button class="md-primary md-raised" ng-click="openLeftMenu()">
<md-icon md-font-icon ng-class="
{'zmdi zmdi-upload': vm.flag,
'zmdi zmdi-code': !vm.flag
}"></md-icon>
</md-button>

Best way to implement a toggle button in AngularJS Material

I am looking for a simple solution to implement a toggle button with a custom selected / unselected icon in AngularJS Material.
The functionality should be identical to the md-checkbox (with ng-model for the selection state), but I want to have my own icon displayed for selected / unselected state. md-checkbox does not seem to support custom icons, and md-button lacks the ng-model.
Preferably I would like to avoid implementing a custom directive and only make this work through css. Is this possible with AngularJS Material?
You can define a toggle function to create toggle activity in your controller, like this:
$scope.toggle = function() {
$scope.variable = !$scope.variable
console.log($scope.variable);
}
Button on the html:
<md-button
ng-click="toggle()"
ng-class="{'active': variable, 'disable': !variable}">
After some digging the best solution currently seems to be using an md-button, which allows custom icons, and extending it with ng-click and ng-class like this:
<md-button ng-click="selected = !selected"
ng-class="{'selected-button' : selected}">
This takes care of the selection state. And in CSS I can then set the styles for the selected-button class
Even though the solution is rather simple, I think there should be an out-of-the-box support from Angular Material for a toggle button (or checkbox) with custom icons.
Properly using all classes of Angular Material v1.x
<md-button class="md-icon-button"
ng-click="filterToggle = !filterToggle"
ng-class="{'md-primary md-raised' : filterToggle}">
<md-tooltip md-direction="bottom">Filter</md-tooltip>
<md-icon ng-hide="filterToggle">filter_list</md-icon>
<md-icon ng-show="filterToggle">clear_all</md-icon>
</md-button>
in controller set
$scope.filterToggle = false;
var app = angular.module('app', []);
app.controller('CommentController', function($scope) {
$scope.filterToggle = true;
//start function.
$scope.StartFunc = function() {
$scope.filterToggle = false;
console.log('in pause function.');
};
$scope.CallFunc = function() {
$scope.filterToggle ? $scope.StartFunc() : $scope.PauseFunc();
}
// pause function.
$scope.PauseFunc = function() {
$scope.filterToggle = true;
console.log('in pause function.');
}
})
<link href="https://material.angularjs.org/1.1.2/angular-material.min.css" rel="stylesheet" />
<script src="https://material.angularjs.org/1.1.2/angular-material.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="CommentController">
<md-input-container>
<md-button class="md-icon-button md-primary md-raised" ng-click="CallFunc()">
<md-tooltip md-direction="bottom">Start/Pause Func</md-tooltip>
<md-icon ng-hide="filterToggle" style="background-color:grey;width:auto;">pause</md-icon>
<md-icon ng-show="filterToggle" style="background-color:grey;width:auto;">play_arrow</md-icon>
</md-button>
</md-input-container>
</div>
</div>

Prevent the closure of the md-menu-bar to ng-click

I have a md-menu-bar like this:
<md-menu-bar>
<md-menu>
<button ng-click="$mdOpenMenu()">
<md-menu-content>
<md-menu-item>
<md-button ng-click="doSomething()">...</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="doSomethingButDoNotClose()">...</md-button>
</md-menu-item>
</button>
</md-menu>
<md-menu-bar>
I need you at the click of md-button with doSomethingButDoNotClose the menu not being closed, how do I proceed?
Pass the event object to your function like this:
<md-button ng-click="doSomethingButDoNotClose($event)">...</md-button>
...and use it inside of your doSomethingButDoNotClose function:
$scope.doSomethingButDoNotClose = function (event) {
...
event.preventDefault();
}
The preventDefault function stops the default event actions from occurring and (hopefully) will prevent the menu from closing (I haven't tested with md-button though).

AngularJS menu - remember which item was clicked and set active

I have a menu, but unfortunately, when I click an item, it's not being remembered (i.e. highlighted gray).
<div ng-controller="DropdownCtrl as ctrl">
<md-menu>
<md-button aria-label="Menu" class="md-icon-button" ng-click="ctrl.openMenu($mdOpenMenu, $event)">
<i class="material-icons">menu</i>
</md-button>
<md-menu-content width="4" ng-model="selected">
<md-menu-item>
<md-button href="home" ria-label="Home">
Home
</md-button>
</md-menu-item>
<md-menu-divider></md-menu-divider>
<md-menu-item>
<md-button href="about" ria-label="About">
About
</md-button>
</md-menu-item>
<!--<md-menu-divider></md-menu-divider>-->
<md-menu-item>
<md-button href="areas" ria-label="Areas">
Speciality Areas
</md-button>
</md-menu-item>
<md-menu-item>
<md-button href="clients" ria-label="Clients">
Clients
</md-button>
</md-menu-item>
<md-menu-item>
<md-button href="blog" ria-label="Blog">
Blog
</md-button>
</md-menu-item>
<md-menu-item>
<md-button href="latest" ria-label="Latest">
Latest
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
</div>
As you can see from the screenshot above, I have clicked "Clients" already, I am on the "clients" page, yet the "Clients" item isn't highlighted!!!
Can anyone share some tips on how to do this in the most lightweight manner?
Here's my controller javascript:
(function () {
'use strict';
angular
.module('app')
.controller('DropdownCtrl', DropdownCtrl);
function DropdownCtrl($scope, $meteor, $mdDialog) {
var vm=this;
vm.date = new Date();
var originatorEv;
vm.openMenu = function($mdOpenMenu, ev) {
originatorEv = ev;
$mdOpenMenu(ev);
};
vm.selected = function(ev){
console.log(ev);
}
};
})();
Solution 1 - The ugly (but fast) one
In order for your menu to be highlighted, you need to tell it to highlight. For this, you need:
Define a css class for highlighted menu button (e.g. .is-active)
Define a function that returns true or false depending on whether a path that you've sent is the current page
In your html, assign the css class defined in point 1 depending on what the current path is
For instance:
<md-button href="clients" ng-class="{'is-active': vm.isCurrentPage('/clients')}">
Clients
</md-button>
And the javascript function:
function isCurrentPage( path ) {
return path === $location.path();
}
Solution 2 - The good (but a bit more complex) one
Save the state of your menu in a service. Thus, you will have access to the state of your application (the current page, previous pages, etc.) from anywhere in your app. The benefit from this approach is that services are singletons in angular and any change that you do to the menu will affect the same object (menu service), thus the state of your app will always be synchronized.

Angular material menu opening on mouse hover

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.
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>
it is very simple here is an answer, if you use bower to install angular-material, you need to:
go to /bower-components/angular-material/modules/js folder
open menu.js in any test editor such as visual code, sublime or atom
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();
};

Resources