Add dropdown menu inside sidebar with material design? - angularjs

I would like when click on polls , open dropdown menu which include sub categories of pulls.
How i should change my code in order to add this functionality with material design.
In state provider:
$stateProvider
.state('admin', {
/*abstract: true,*/
url: '/admin',
templateUrl: 'app/admin/admin.html',
controller: 'AdminCtrl',
onEnter: function($rootScope) {
$rootScope.title = $rootScope.titleRoot + ' | Admin';
}
});
});
and in .html
<md-sidenav class="md-sidenav-left md-whiteframe-z2" md-component-id="left" md-is-locked-open="$mdMedia('gt-md')">
<md-toolbar class="md-theme-indigo">
<h1 class="md-toolbar-tools">Admin</h1>
</md-toolbar>
<md-content class="" ng-controller="LeftCtrl">
<md-button ng-click="close()" class="md-primary" hide-gt-md>
Close Sidenav Left
</md-button>
<!--<p hide-md show-gt-md>-->
<!--</p>-->
<ul class="sidenav-menu">
<li class="" ng-repeat="section in sections">
<md-button ui-sref="{{section.link}}">
<i class="fa fa-fw {{section.icon}}"></i> {{section.title}}
</md-button>
</li>
</ul>
</md-content>
</md-sidenav>
Inside Controller:
.controller('AdminCtrl', function($scope, $mdSidenav, $timeout, $log) {
$scope.sections = [
{
title: 'User Management',
icon: 'fa-user',
link: 'usermanagement'
},{
title: 'Polls',
icon: 'fa-files-o',
link: 'polls'
}
];
$scope.toggleLeft = function () {
$mdSidenav('left').toggle()
.then(function () {
//$log.debug("toggle left is done");
});
};
})
.controller('LeftCtrl', function($scope, $timeout, $mdSidenav, $log) {
$scope.close = function() {
$mdSidenav('left').close()
.then(function(){
//$log.debug("close LEFT is done");
});
};
});

Since you are using Angular-Material, I suggest you use it's Menu directive: https://material.angularjs.org/latest/#/demo/material.components.menu

Related

Method binding is not working in Angular

I am trying to attached a controller scope method in a directive but when i click in directive button that linked method is not called. Please review code. There is side-nav directive in which i have attached method with select parameter. but when button is clicked method is not called.
index.html
<div class="container" layout="row" flex ng-controller="userController as vm" ng-init="vm.loadUsers()">
<md-sidenav md-is-locked-open="true" class="md-whiteframe-1dp">
<side-nav users="vm.users" select="vm.selectUser(user)"></side-nav>
</md-sidenav>
<md-content id="content" flex>
<user-detail selected="vm.selected" share="vm.share()"></user-detail>
</md-content>
</div>
userController.js
app.controller("userController", ['$scope', 'userService', '$mdBottomSheet', function ($scope, userService, $mdBottomSheet) {
var self=this;
self.users = [];
this.name = "manish";
self.loadUsers = function () {
userService
.loadAllUsers()
.then(function (users) {
self.users = users;
self.selected = users[0];
userService.selectedUser = self.selected;
});
}
self.selectUser = function (user) {
self.selected = user;
userService.selectedUser = self.selected;
}
}]);
directives.js
app.directive("sideNav", function () {
return {
restrict :'AE',
templateUrl: './views/sidenav.html',
scope : {
select : '&',
users : '='
}
}
});
./views/sidenav.html
<md-list>
<md-list-item ng-repeat="user in users">
<md-button ng-click="select({user:user)">
<md-icon md-svg-icon="{{user.avatar}}" class="avatar"></md-icon>
{{user.name}}
</md-button>
</md-list-item>
</md-list>
Try doing it like this:
index.html
<side-nav users="vm.users" select="vm.selectUser"></side-nav>
./views/sidenav.html
<md-button ng-click="select()(user)">

Issue in accessing $scope variable in $mdDialog Controller - AngularJs 1.X.X

I'm using $mdDialog and I specified a Controller which is present in another js file.
Parent Js Controller:
$scope.AddDesignationPrompt = function(ev) {
$mdDialog.show({
controller: 'AddDesignationPromptController',
templateUrl: './Employee/Views/AddDesignation.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
fullscreen: true // Only for -xs, -sm breakpoints.
})
.then(function(answer) {
$scope.GetPriliminaryData();
}, function() {
$scope.status = 'You cancelled the dialog.';
});
};
Dialog Controller:
app.controller('AddDesignationPromptController', function ($scope, $rootScope, $mdDialog, $window, HTTPService) {
$scope.loadUpData = {
State: [],
Department: [],
Designation: []
};
HTTPService.getPriliminaryRegData().then(function (result) {
if ((result != undefined) && (result != null)) {
$scope.loadUpData = {
State: [],
Department: result.Result.Department,
Designation: []
};
console.log("Inside");
console.log($scope.loadUpData);
}
});
console.log("Outside");
console.log($scope.loadUpData);
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.answer = function(answer) {
$mdDialog.hide(answer);
};
});
View:
<md-dialog aria-label="Mango (Fruit)">
<form ng-cloak>
<md-toolbar>
<div class="md-toolbar-tools">
<h2>New Department</h2>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon md-svg-src="./Employee/images/Close.svg" aria-label="Close dialog"></md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<div class="md-dialog-content">
<p>Enter the New Department</p>
<div class="controlItem">
<md-select ng-model="select.designation" ng-change="onDesignationChange(select.designation)" tabindex="9">
<md-option ng-repeat="key in loadUpData.Designation" value="{{key.DesignationId}}">{{key.Name}}</md-option>
</md-select>
</div>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">
<span flex></span>
<md-button ng-click="answer('not useful')">
Not Useful
</md-button>
<md-button ng-click="answer('useful')">
Useful
</md-button>
</md-dialog-actions>
</form>
</md-dialog>
Its coming in controller level, but its not loading in md-select. Kindly assist me how to load the collection in the View.
You are looping over loadUpData.Designation which is always set to empty array [], so nothing will be ever displayed. The only data that is populated in your HTTPService promise resolve is loadUpData.Department, but you never print it in your HTML.
if you have Designation in result, than populate it, something like:
HTTPService.getPriliminaryRegData().then(function (result) {
if (result && result.Result) {
$scope.loadUpData = {
State: [],
Department: result.Result.Department,
Designation: result.Result.Designation
};
console.log("Inside");
console.log($scope.loadUpData);
}
});

Angular UI-Router: nested views

I have two col layout with header and footer. Header has page navigation (GetStarted, Component). Of the 2 columns, one is for sidenav and other is for main content.
When "GetStarted" nav is active, sidenav is populated with respective links (overview, examples)
When "Component" nav is active, sidenav is populated with respective links (checkbox, alert)
Upon clicking "Overview" link area is populated with its data
<ul class="nav nav-tabs">
<li role="presentation" class="active">Default</li>
<li role="presentation">Disabled</li>
</ul>
<section class="content__main__tab__content col-xs-12 col-sm-12 col-md-12 col-lg-12">
<form id="checkbox--default">
<div class="input__checkbox--default" id="checkbox--default">
<!-- <div class="form-group"> -->
<fieldset>
<legend>Default</legend>
<label for="gi-checkbox">Checkbox Label
<div class="checkbox-input-wrapper group__input-wrapper">
<input type="checkbox" class="checkbox" id="gi-checkbox">
</div>
</label>
</fieldset>
<!-- </div> -->
</div>
</form>
</section>
Main content has 2 nav tabs for checbox states (default & disable). By clicking the "default" its content must be displayed and same goes for disabled. I'm new to angular and I kinda got first level nested view working. But couldn't the whole thing working. here is the code sample
index.html
<body ng-app="mendouiApp" id="mendo__home" data-spy="scroll" data-target=".scrollspy">
<nav class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" ui-sref="home"><img src="images/gi-logo.png" alt="logo"/></a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a ui-sref="home">Get Started</a></li>
<li><a ui-sref="components">Components</a></li>
</ul>
</div><!-- /.nav-collapse -->
</div><!-- /.container -->
</nav><!-- /.navbar -->
<div class="wrapper" ui-view></div> <!--/.container-->
component.html
<div class="content__wrapper">
<div class="row">
<div class="content__secondary content__secondary--l scrollspy">
<ul id="sidenav-fixed-l" class="nav hidden-xs hidden-sm affix-top" data-spy="affix">
<li>
<h5>COMPONENTS</h5>
</li>
<li ng-repeat="item in componentsList">
<a ui-sref="{{item.link}}" ng-cloak>{{item.name}}</a>
</li>
</ul>
</div>
<div ui-view></div>
</div> <!--/.row-->
</div> <!--/.content-wraper-->
app.js
(function(){
var mendouiApp = angular.module('mendouiApp', ['ui.router', 'ui.router.stateHelper']);
mendouiApp.constant('COMPONENTS_LIST', {
name: 'sidenav',
templateUrl: '../components/components.list.html',
abstract: true,
children: [{
name: 'alerts',
url: '/alerts',
templateUrl: '../components/alerts/alerts.html'
}]
});
mendouiApp.config(function($stateHelperProvider, $urlRouterProvider, $locationProvider, $urlMatcherFactoryProvider, COMPONENTS_LIST) {
$urlMatcherFactoryProvider.strictMode(false);
$urlRouterProvider.otherwise('/home');
$locationProvider.hashPrefix('!');
$stateHelperProvider
.state('home', {
url: '/home',
templateUrl: '../gettingstarted.html',
controller: 'getStartedController'
})
.state('layouts', {
url: '/layouts',
templateUrl: '../layouts.html'
})
.state('screenpatterns', {
url: '/screenpatterns',
templateUrl: '../screenpatterns.html'
})
.state('yogi', {
url: '/yogi',
templateUrl: '../yogi.html'
})
.state('components', {
url: '/components',
templateUrl: '../components.html',
controller: 'componentsController'
})
.state(COMPONENTS_LIST, {
keepOriginalNames: true
})
.state('components.button', {
url: '/button',
templateUrl: '../components/button/button.html'
}) .state('components.checkbox', {
url: '/checkbox',
templateUrl: '../components/checkbox/checkbox.html'
})
.state('components.forms', {
url: '/forms',
deepStateRedirect: true,
sticky: true,
views: {
'': { templateUrl: '..forms.html' },
'inline#components.forms': {
templateUrl: '../components/forms/form-inline/forminline.html'
},
'default#components.forms': {
templateUrl: '../components/forms/form-default/formdefault.html'
},
'multicolumn#components.forms': {
templateUrl: '../components/forms/form-multicolumn/formmulticolumn.html'
}
}
});
// use the HTML5 History API
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
mendouiApp.controller('componentsController', ['$scope', '$state', 'sideNavService', function($scope, $state, sideNavService, COMPONENTS_LIST){
$scope.componentsList = sideNavService.components;
$scope.componentsnav = COMPONENTS_LIST.children;
$scope.go = function(tab) {
$state.go(tab.name);
}
}]);
mendouiApp.controller('getStartedController', ['$scope', '$state', 'sideNavService', 'fixedSideNavService', function($scope, $state, sideNavService, fixedSideNavService ){
$scope.getstartedList = sideNavService.getstarted;
}]);
/*** This is for the external url reference ***/
mendouiApp.run(function($rootScope, $state, $stateParams, $window, fixedSideNavService, copyToClipBoardService) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams, $state, $stateParams) {
if (toState.external) {
event.preventDefault();
$window.open(toState.url, '_self');
}
});
$rootScope.$on('$viewContentLoaded', function(event){
fixedSideNavService.fixedsidenav();
copyToClipBoardService.copytoclipboard();
});
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$state.transitionTo('home');
});
})();
service.js
angular.module('mendouiApp').service('sideNavService', function() {
return {
"getstarted" : [
{
"name" : "Overview",
"link" : "home.overview"
}
{
"name" : "Summary",
"link" : "home.overview"
}
],
"components" : [
{
"name" : "Alerts",
"link" :"components.alert"
},
{
"name" : "Button",
"link" :"components.button"
},
{
"name" : "Button Groups",
"link" :"components.buttongroup"
},
{
"name" : "Button Icons",
"link" :"components.buttonicons"
},
{
"name" : "Checkbox",
"link" :"components.checkbox"
},
{
"name" : "Datepicker",
"link" :"components.datepicker"
},
{
"name" : "Forms",
"link" : "components.forms"
}
]
};
});
Your question was a bit messy, but after a while playing with I could understand I made this fiddle: http://jsfiddle.net/canastro/c4kt2myc/2/ I hope it works as you were expecting.
The main thing to focus on here is:
.state("root.components.button", {
url: '/components/button',
views: {
'main#': {
template: `
<div>
<a ui-sref="root.components.button.default">default</a>
<a ui-sref="root.components.button.disabled">disabled</a>
<div ui-view="buttonsContent"></div>
</div>
`
}
}
})
.state("root.components.button.default", {
url: '/components/button/default',
views: {
'buttonsContent#root.components.button': {
template: 'root.components.button.default'
}
}
})
.state("root.components.button.disabled", {
url: '/components/button/disabled',
views: {
'buttonsContent#root.components.button': {
template: 'root.components.button.disabled'
}
}
})
In the first level you have a abstract route so you can always have your basic layout present.
Then in the Started / Components routes, you load content into the main and side ui-views.
In all of the Started and Component child routes you just override the main views.
And finally, in the last level you need to say you want to fill the content of a ui-view created in the previous state, by doing something like VIEWNAME#STATENAME.

$mdDialog not working

$mdDialog not working with custom template.
here's the code:
HTML:
<md-button class="md-icon-button" ng-click="commentPrompt($event)">
<p>button
</p>
</md-button>
JS:
var app = angular.module('BetaApp', ['ngMaterial', 'firebase']);
app.controller('SideNavController', function($scope, $mdDialog) {
$scope.commentPrompt = showDialog;
function showDialog($event){
var parentEl = angular.element(document.body);
$mdDialog.show({
parent: parentEl,
targetEvent: $event,
templateUrl: 'comment.html',
controller: DialogController
});
};
function DialogController($scope, $mdDialog) {
$scope.closeDialog = function() {
$mdDialog.hide();
}
}
});
COMMENT.HTML:
<md-dialog>
<span>test
</span>
<md-button ng-click="closeDialog()" class="md-primary">
<p>close</p>
</md-button>
</md-dialog>
change this
md-button class="md-icon-button" ng-click="commentPrompt($event)">
to
md-button class="md-icon-button" ng-click="showDialog($event)">

Pushing item to array after close md-dialog not working

Array does not refresh after pushing item through md-dialog, though I can save the item normally.
I tried to test which level I could push an item into the array manually and I could do so until $scope.showAddUsuario(), after that I can't push an item, even manually:
Usuario.html
<div flex-gt-sm="100" flex-gt-md="100" ng-controller="UsuarioCtrl">
<h2 class="md-title inset">Usuario</h2>
<md-card>
<md-list>
...
</md-list>
</md-card>
<md-button class="md-fab" aria-label="Add" ng-click="showAddUsuario($event)">
<md-icon md-svg-icon="content:ic_add_24px" aria-label="Plus"></md-icon>
</md-button>
</div>
md-dialog:
<md-dialog aria-label="Form">
<md-content class="md-padding">
<form name="userForm">
<div layout layout-sm="column">
<md-input-container flex> <label>Nome</label> <input ng-model="item.nome"> </md-input-container>
</div>
<div layout layout-sm="column">
<md-input-container flex> <label>E-mail</label> <input ng-model="item.email"> </md-input-container>
</div>
<div layout layout-sm="column">
<md-input-container flex> <label>Senha</label> <input ng-model="item.senha"> </md-input-container>
</div>
</form>
</md-content>
<div class="md-actions" layout="row">
<span flex></span>
<md-button ng-click="cancel()"> Cancel </md-button>
<md-button ng-click="saveUsuario(item)" class="md-primary"> Save </md-button>
</div>
</md-dialog>
Controller:
app.controller('UsuarioCtrl', function ($scope, $http, $mdDialog, $interval, $timeout) {
$scope.items = [];
$http({
method : 'GET',
url : 'UsuarioServlet'
})
.success(
function(data, status, headers,
config) {
$scope.items = data;
}).error(
function(data, status, headers,
config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
$scope.saveUsuario = function(item) {
$scope.items.push({id:100, nome:item.nome, email:item.email, senha:item.senha, status:1});
};
$scope.showAddUsuario = function(ev) {
$mdDialog.show({
controller: 'UsuarioCtrl',
templateUrl : 'CrudUsuario.html',
targetEvent : ev,
locals : {
item : null
}
})
};
});
Only now do I see that you were using $mdDialog and not $modal. So this answer will most likely not apply to your case.
You do however seem to be missing a .finally() part in your code.
From the manual ( https://material.angularjs.org/latest/api/service/$mdDialog )
$mdDialog
.show( alert )
.finally(function() {
alert = undefined;
});
So you could try that.
Otherwise, have you considered using $modal instead?
You don't seem to be handling the return of information from your modal.
(function (){
'use strict';
function myCtrl($modal){
var vm = this;
vm.myArray = [];
...
function openModal(){
var modalInstance = $modal.open({
templateUrl: 'path/to/modal/view.html',
controller: 'MyModalCtrl as vm',
size: 'lg',
resolve: {
data: function(){
return dataThatYouWantToSendFromHereToYourModal;
}
}
});
modalInstance.result.then(function (result){
vm.myArray.push(result);
});
}
...
}
...
})();
The modalIntsance.result.then will trigger when you in your modal-controller (in this case MyModalCtrl) issues a $modalInstance.close(sendThisDataBackToCallingController) call.
So the modal-controller should look along the lines of
...
function MyModalCtrl($modalInstance, data){
...
function init(){
doSomethingWithDataThatYouGotFromTheCallingController(data);
}
...
function save(){
var dataToSendBack = {...};
$modalInstance.close(dataToSendBack);
}
...
}
...
That should get you going in the right direction.
Thanks for the comments! The documentation say to use that:
}).then(function(item) {
$scope.items.push({id:100, nome:item.nome, email:item.email, senha:item.senha, status:1});
});
Works fine!
I solve this problem ,Please replace $mdDialog.show() as
$mdDialog.show({
controller: function (){
this.parent = $scope;
},
templateUrl: 'dialog1.tmpl.html',
scope:$scope.$new(),
targetEvent : ev,
bindToController: true,
clickOutsideToClose:true,
fullscreen: useFullScreen
})

Resources