preventing ng-click event with angular-material - angularjs

I have a series of toggles inside a custom angular dropdown(s). The problem I am having is, the toggles do toggle, but they close the dropdown as well. How can I prevent this? The dropdowns should still close when double clicking the drawer, that is the expected behavior, but not when the toggle is clicked.
This is the HTML:
<div class="cnt" ng-repeat="item in data">
<div class="menu-item" ng-click="toggle(item.pos);">
<md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> {{item.name}}</span>
<i class="fa fa-chevron-down" ng-class="{'rotate180': item.pos==menuIsOpen, 'rotate-back': !menuIsOpen}"></i>
</md-list>
<div class="sub-menu" ng-animate="'animate'" >
<div ng-repeat='(k,v) in item track by $index'>
<div ng-if="isArray(v)">
<md-menu-item ng-if="menuIsOpen===item.pos" ng-repeat='v1 in v track by $index'>
<md-button>
<div layout="row" flex="">
<md-switch class="md-primary" name="special" ng-model="project.special" required>
<span class="">
<p flex="">{{v1.title}}</p>
</span>
</md-switch>
</div>
</md-button>
</md-menu-item>
</div>
</div>
</div>
</div>
</div>
and the controller has this in it for functionality purposes and data population from json :
$scope.toggle = function(itemPos) {
if ($scope.menuIsOpen === itemPos) {
$scope.menuIsOpen = 0;
}
else {
$scope.menuIsOpen = itemPos;
}
}
$scope.isArray = function(val) {
return Array.isArray(val);
}
spoiler alert:adding md-prevent-menu-close="true" to the md-button didn't help
Here is a CODEPEN to try things out
Thanks guys

You should move your ng-click="toggle(item.pos);" into the <md-list>
<div class="cnt" ng-repeat="item in data">
<div class="menu-item">
<md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex ng-click="toggle(item.pos);">
<span class="title flex" flex=""> {{item.name}}</span>
<i class="fa fa-chevron-down" ng-class="{'rotate180': item.pos==menuIsOpen, 'rotate-back': !menuIsOpen}"></i>
</md-list>
<div class="sub-menu" ng-animate="'animate'" >
<div ng-repeat='(k,v) in item track by $index'>
<div ng-if="isArray(v)">
<md-menu-item ng-if="menuIsOpen===item.pos" ng-repeat='v1 in v track by $index'>
<md-button>
<div layout="row" flex="">
<md-switch class="md-primary" name="special" ng-model="project.special" required>
<span class="">
<p flex="">{{v1.title}}</p>
</span>
</md-switch>
</div>
</md-button>
</md-menu-item>
</div>
</div>
</div>
</div>
</div>

Related

How do I make the card title heights the same when content is different

I've run into this before and just forced it to work with a bunch of custom css but that seems sloppy. This seems completely backwards to how I would expect it to work. The content should flex to match the height, not the header. Any ideas on how to fix this besides custom css? Is there an "angular-material" way to fix it?
<div layout-gt-sm="row" flex="1">
<md-card ng-show="!trackingStored.loading" flex="20">
<md-card-title>
<md-card-title-text layout-align="center center">
<span class="md-headline"> General </span>
</md-card-title-text>
</md-card-title>
<md-divider style="width:100%;"></md-divider>
<md-card-content layout="column" layout-align="center center" flex = "1">
<dl>
<dt ng-show="trackingStored.VehicleStatus">Status</dt>
<dd ng-show="trackingStored.VehicleStatus">{{trackingStored.trackingInfo.VehicleStatus}}</dd>
<dt>Location</dt>
<dd>{{trackingStored.trackingInfo.ConfirmationNumber}}</dd>
<dt>Year</dt>
<dd>{{trackingStored.trackingInfo.VehicleYear}}</dd>
<dt>Make</dt>
<dd>{{trackingStored.trackingInfo.VehicleMake}}</dd>
<dt>Model</dt>
<dd>{{trackingStored.trackingInfo.VehicleModel}}</dd>
<dt>VIN</dt>
<dd>{{trackingStored.trackingInfo.VehicleVIN}}</dd>
<dt ng-show="trackingStored.trackingInfo.DropOffDate.HasValue">Dropped off</dt>
<dd ng-show="trackingStored.trackingInfo.DropOffDate.HasValue">{{trackingStored.trackingInfo.DropOffDate.Value}}</dd>
</dl>
</md-card-content>
</md-card>
<md-card ng-show="trackingStored.trackingInfo.RecentHistory != null && trackingStored.trackingInfo.RecentHistory.length > 0"
flex="80">
<md-card-title >
<md-card-title-text layout-align="center center">
<span class="md-headline"> Maintenance History </span>
</md-card-title-text>
</md-card-title>
<md-divider style="width:100%;"></md-divider>
<md-card-content>
<h4>(12 most recent entries)</h4>
<div layout-gt-xs="row" layout-wrap layout-align="space-between center">
<div ng-repeat="item in trackingStored.trackingInfo.RecentHistory track by $index" flex="50" flex-xs="100" style="width:100%;">
<md-card>
<md-card-title class="customCardHeader">
<md-card-title-text>
<span class="md-headline customCardHeaderText"> {{item.CompletedDate | date: trackingStored.dateFormat}} </span>
</md-card-title-text>
</md-card-title>
<md-divider> </md-divider>
<md-card-content>
<div>{{item.Comments}}</div>
</md-card-content>
</md-card>
</div>
</div>
</md-card-content>
</md-card>

Minimalizing a menu with ng-repeat

I know the question title is a little vague but I don't know what else to call it. Basically, this is my problem:
I have an angular menu with submenus. I have each menu item separate and the submenu items being injected with ng-repeat. That is fine, but the problem is I would like to run the entire menu in one ng-repeat and have the json file hold, not only the submenu items, but the menu items as well. This is what I have:
<div class="cnt">
<div class="menu-item" ng-click="toggle(1); open1=!open1">
<md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item</span>
<i class="fa fa-chevron-down" ng-class="{'rotate180': open1, 'rotate-back': !open1}"></i>
</md-list>
<div class="sub-menu" ng-animate="'animate'" >
<md-menu-item ng-if="menuIsOpen===1" ng-repeat="item in data" >
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</div>
</div>
<div class="menu-item" ng-click="toggle(2); open2=!open2">
<md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item 2</span>
<i class="fa fa-chevron-down" ng-class="{'rotate180': open2, 'rotate-back': !open2}"></i>
</md-list>
<div class="sub-menu" ng-animate="'animate'" >
<md-menu-item ng-if="menuIsOpen===2" ng-repeat="item in data2">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</div>
</div>
</div>
with a json file that looks like this:
$scope.data =
[{
title: 'Home',
icon: 'home',
link: '/page1/'
}, {
title: 'Email Us',
icon: 'envelope',
link: '/page2/'
}, {
title: 'Profile',
icon: 'user',
link: '/page3/'
}, {
title: 'Print',
icon: 'print',
link: '/page4/'
}];
$scope.data2 =
[{
title: 'Home 2',
icon: 'home',
link: '/page1/'
}, {
title: 'Email Us 2',
icon: 'envelope',
link: '/page2/'
}, {
title: 'Profile 2',
icon: 'user',
link: '/page3/'
}, {
title: 'Print 2',
icon: 'print',
link: '/page4/'
}];
As you can see, if I want 2 menu items, I have to build the code for 2 menu items, add the data to the json, and run the bindings. And if I want 3, then I have to do this 3 times. But what if I want 20? Ideally, I would like to have 1 single HTML structure that pulls the data from the json to create as many menu items with as many submenu items as it finds in the json. But I am having problems trying to achieve this:
This is what makes sense in my head:
<div class="cnt" ng-repeat="item in data">
<div class="menu-item" ng-click="toggle({{item.pos}}); open{{item.pos}}=!open{{item.pos}}">
<md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> {{item.name}}</span>
<i class="fa fa-chevron-down" ng-class="{'rotate180': open{{item.pos}}, 'rotate-back': !open{{item.pos}}}"></i>
</md-list>
<div class="sub-menu" ng-animate="'animate'" >
<md-menu-item ng-if="menuIsOpen==={{item.pos}}" >
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.item1[0].linkto}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.item1[0].title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</div>
</div>
</div>
I have a CODEPEN that you can see the working code in.
See this CODEPEN for the desired effect. This is how I have it working now and how it should work ultimately.
Thanks fellas!
This answer is not directly addressing the parsing issue, but a solution to what you are trying to achieve.
Instead of using open{{item.pos}} to identify the menu item, which is resulting in parsing error, use the the menuIsOpen,which holds the position of the toggled item. Based on the desired effect.. codepen sample
script additions
//Not needed
// $scope.open1 = false; //initial value
//$scope.open2 = false; //initial value
//$scope.open3 = false; //initial value
//$scope.open4 = false; //initial value
$scope.toggle = function(itemPos) {
if ($scope.menuIsOpen === itemPos) {
$scope.menuIsOpen = 0;
}
else {
$scope.menuIsOpen = itemPos;
}
}
html : just need toggle the item we pass the position property
<div class="cnt" ng-repeat="item in data">
<div class="menu-item" ng-click="toggle(item.pos);">
<md-list layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> {{item.name}}</span>
<i class="fa fa-chevron-down" ng-class="{'rotate180': item.pos==menuIsOpen, 'rotate-back': !menuIsOpen}"></i>
</md-list>
<div class="sub-menu" ng-animate="'animate'" >
<md-menu-item ng-if="menuIsOpen===item.pos" >
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.item1[0].linkto}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.item1[0].title}} a</p>
</a>
</div>
</md-button>
</md-menu-item>
</div>
</div>
</div>
Let us know
Update : based on your comment, the current setup only deals with item at postion 0 (only 1 item). The JSON (if you do not have control) and you need the item1 item2 etc.. to be displayed you can extend the ng-repeat by going over the entire object and iterate ONLY the ARRAYS. This is not going for the optimal solution just a work around.. sort of..
If there is another array of links inside the array.. this solution will not work.
html
<div class="sub-menu" ng-animate="'animate'" >
<div ng-repeat='(k,v) in item track by $index'>
<div ng-if="isArray(v)">
<md-menu-item ng-if="menuIsOpen===item.pos" ng-repeat='v1 in v track by $index'>
<md-button>
<div layout="row" flex="">
<a ui-sref="{{v1.linkto}}">
<p flex=""><i class="fa fa-{{v1.icon}}"></i> {{v1.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</div>
</div>
</div>
script
$scope.isArray = function(val) {
return Array.isArray(val);
}

open one dropdown at a time while using ngHide/ngShow angular directives

I have a simple dropdown menu that I want to tweak a little. I need help with animating the dropdown so it's scaling down when it opens. But that is not my biggest concern. What I really need help with is opening only one dropdown at a time. So if I open one and another one had already been previously opened, it should close.
I'm using Angular-Material, so I am looking for an Angular Controller or directive solution please, one that uses ngHide/ngShow directives perhaps? Not sure about that part.
This is my HTML
<md-list ng-click="menuIsOpen = !menuIsOpen" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu">
<ul ng-init="menuIsOpen= false" ng-show="menuIsOpen">
<md-menu-item ng-repeat="item in data">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</ul>
</div>
<md-list ng-click="menu2IsOpen = !menu2IsOpen" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item 2</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu">
<ul ng-init="menu2IsOpen= false" ng-show="menu2IsOpen">
<md-menu-item ng-repeat="item in data">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</ul>
</div>
I have a CODEPEN you can checkout. Thanks a lot!
In ng-click, set variable menuIsOpen to ng-click="menuIsOpen = 1" and as ng-show="menuIsOpen === 1 " Do the same thing with other menus.
Example
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<button ng-click="menuIsOpen = 1">About Page</button>
<button ng-click="menuIsOpen = 2">Help page</button>
<button ng-click="menuIsOpen = 3">Info Page</button>
<button ng-click="menuIsOpen = 4">Refrence page</button>
<div class="form-group" ng-show="menuIsOpen===1">
<p>About page</p>
</div>
<div class="form-group" ng-show="menuIsOpen===2">
<p>Help page</p>
</div>
<div class="form-group" ng-show="menuIsOpen===3">
<p>Info</p>
</div>
<div class="form-group" ng-show="menuIsOpen===4">
<p>Refrence</p>
</div>
</div>
<div ng-controller="ListBottomSheetCtrl" class="md-padding bottomSheetdemoBasicUsage" ng-cloak="" ng-app="MyApp">
<div class="cnt">
<md-list ng-click="menuIsOpen = 1" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu">
<ul ng-init="menuIsOpen= false" ng-show="menuIsOpen === 1 ">
<md-menu-item ng-repeat="item in data">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</ul>
</div>
<md-list ng-click="menuIsOpen = 2" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item 2</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu">
<ul ng-init="menu2IsOpen= false" ng-show="menuIsOpen === 2 ">
<md-menu-item ng-repeat="item in data">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</ul>
</div>
</div>
</div>
I solved try following:
<div ng-controller="ListBottomSheetCtrl" class="md-padding bottomSheetdemoBasicUsage" ng-cloak="" ng-app="MyApp">
<div class="cnt" ng-init="menuIsOpen= false; menu2IsOpen= false">
<md-list ng-click="menuIsOpen = !menuIsOpen; menu2IsOpen = false" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu">
<ul ng-show="menuIsOpen">
<md-menu-item ng-repeat="item in data">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</ul>
</div>
<md-list ng-click="menu2IsOpen = !menu2IsOpen; menuIsOpen = false" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item 2</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu">
<ul ng-show="menu2IsOpen">
<md-menu-item ng-repeat="item in data">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</ul>
</div>
</div>
Here is CODEPEN

How to use ng-show and ng-hide in ng-repeat loop

Here i have the code:
<ul dnd-list="list" ng-controller="Modalcontrol">
<li ng-repeat="item in list" ng-click="showAdvanced($event)">
{{item.card_name}}
</li>
</ul>
<span ng-click="$parent.selectedIndex=$index">Add </span>
<md-card class="card" ng-show="$parent.selectedIndex == $index" >
<form name="colorForm" class="addcontdrag" >
<md-input-container>
<label>Add text</label>
</md-input-container>
<span>
<md-button class="md-raised md-primary">Save</md-button>
<i class="material-icons" ng-click="$parent.selectedIndex=$index">clear</i>
</span>
</form>
</md-card>
In this code i want to hide the md-card when i click the close button. Show the md-card by using $parent.selectedIndex=$index. But i dont know how to hide the md-card using this one.
If anyone know please help me.
Thanks Advanced...
You will have to place your md-card inside li tag to get the $index.
<ul dnd-list="list" ng-controller="Modalcontrol">
<li ng-repeat="item in list" ng-click="showAdvanced($event)">
{{item.card_name}}
<span ng-click="$parent.selectedIndex=$index">Add </span>
<md-card class="card" ng-show="$parent.selectedIndex == $index" >
<form name="colorForm" class="addcontdrag" >
<md-input-container>
<label>Add text</label>
</md-input-container>
<span>
<md-button class="md-raised md-primary">Save</md-button>
<i class="material-icons" ng-click="$parent.selectedIndex=$index">clear</i>
</span>
</form>
</md-card>
</li>
</ul>

how to impliment flex with ng-repeat

I am using a panel to display list of user and applying flex with ng-repeat but it's not working plz help me do this and i also want to implement scroll for this panel
this is my code:
<div class="form-group" ng-show="Employee">
<label class="col-xs-2 control-label"></label>
<div class="col-xs-6">
<div class="panel panel-primary panel-default" id="panel3">
<div class="panel-heading swpanel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-target="#collapseThree" href="" class="collapsed">Mobile EmployeeList:</a>
</h4>
</div>
<div id="collapseThree" class="panel-collapse collapse col-xs-6">
<div layout="row" layout-wrap flex >
<div flex="50" ng-repeat="item in mobileEmployeeList">
<input type="checkbox" ng-checked="exists(item.rep_id, selectedEmployeeList)" ng-click="toggle(item.rep_id, selectedEmployeeList)">
{{ item.rep_name }}
<span ng-if="exists(item.rep_id, selectedEmployeeList)"></span>
</input>
</div>
</div>
</div>
</div>
</div>
</div>
it could be like that:
<md-content md-padding>
<md-list id="users-list" class="flex flex-col">
<ul class="flex flex-row full-width" ng-repeat="user in mobileEmployeeList">
<input flex="5" type="checkbox" ng-checked="exists(item.rep_id, selectedEmployeeList)" ng-click="toggle(item.rep_id, selectedEmployeeList)">{{ item.rep_name }}
<span ng-if="exists(item.rep_id, selectedEmployeeList)"></span>
<li flex="25" class="flex flex-col">{{user.name}}</li>
<li flex="25" class="flex flex-col">{{user.username}}</li>
</ul>
</md-list>
</md-content>

Resources