How to use md-nav-bar correctly? - angularjs

I'm using angular material md-nav-bar and i have those problems.
1) I want to add it to the middle of the page.
2) I want to know how to add pages to the nav-items
I have attached an image to show how it looks now
Is there any possible way to do it?
Any help highly appreciate. Thanks,

Here you go - CodePen
To centre the md-nav-bar use layout
To add a md-nav-item use ng-repeat with an array and add to the array
Markup
<div ng-controller="AppCtrl" ng-app="MyApp" layout-fill layout="column" ng-cloak>
<div layout="row" layout-align="center" flex="70">
<md-content class="md-padding">
<md-nav-bar md-selected-nav-item="currentNavItem" nav-bar-aria-label="navigation links">
<md-nav-item ng-repeat="item in navItems" md-nav-click="goto('{{item.value}}')" name="{{item.value}}">{{item.label}}</md-nav-item>
</md-nav-bar>
<span>{{currentNavItem}}</span>
</md-content>
</div>
<div>
<md-button class="md-raised md-primary" ng-click="addItem()">Add Item</md-button>
</div>
</div>
JS
(function() {
'use strict';
angular.module('MyApp',['ngMaterial'])
.controller('AppCtrl', AppCtrl);
function AppCtrl($scope, $element, $compile) {
$scope.currentNavItem = 'page1';
$scope.navItems = [
{value: "page1", label: "Page One"},
{value: "page2", label: "Page Two"},
{value: "page3", label: "Page Three"},
];
$scope.addItem = function () {
$scope.navItems.push(
{
value: "page" + ($scope.navItems.length + 1),
label: "Page" + ($scope.navItems.length + 1)
}
);
}
}
})();

To get the navbar elements to the center of the page you can add the <span flex></span> tags before the start of the first nav-item and the end of the last nav-item.
For your reference:
<md-nav-bar>
<span flex></span>
<md-nav-item>
</md-nav-item>
<md-nav-item>
</md-nav-item>
<span flex></span>
</md-nav-bar>

Related

UI Bootstrap Accordion content not showing on click

I'm trying to add an accordion element, but clicking on one accordion header results in nothing (in my application I can actually see the content transition in and then transition out, as if it encountered some condition instructing it to collapse).
I've managed to extract the behaviour in the following codepen:
https://codepen.io/deepdown22/pen/LYNQYeb
<div ng-app="plunker" ng-cloak>
<div ng-controller="MainCtrl">
<h1>Hello {{name}}</h1>
<p>Start editing and see your changes reflected here!</p>
{{groups}}
<uib-accordion close-others="true">
<div uib-accordion-group class="panel-default" ng-repeat="group in groups" is-open="group.open">
<uib-accordion-heading>
{{group.title}}
</uib-accordion-heading>
{{group.content}}
</div>
</uib-accordion>
</div>
</div>
angular.module('plunker', ['ui.bootstrap']);
angular.module('plunker').controller('MainCtrl', function($scope) {
$scope.name = 'Plunker';
$scope.groups = [
{'title': 'a', 'content': 'b'},
{'title': 'c', 'content': 'd'}
];
});
I'm sure I'm doing something wrong, but I can't put my finger on what.
First check out the documentation for uib-accordion (https://angular-ui.github.io/bootstrap/). You are using it wrong.
Not <div uib-accordion> it is <uib-accordion>
Codepen is useless without the css

ng-click not responding when HTML added by JavaScript

ng-click is not working as it should. I tried looking at documentation and tutorials but couldn't find the reason.
I have a JavaScript variable storing html template. which by using
document.getElementById('someId').innerHTML = emptypage;
where emptypage is a JavaScript variable, is implemented inside a div with id=someId.
My Code:
var emptypage=` <md-toolbar `+ this.createID() +` class="md-accent
soopsObject" ng-app="vdApp">
<span class="example-spacer ng-controller="vdNav">
<md-sidenav class="md-sidenav-left" md-component-id="left" md-
disable-backdrop md-whiteframe="4">
<md-content layout-margin>
<p>
About
</p>
<p>
Contact
</p>
<md-button ng-click="toggleLeft()" class="md-accent">
Close
</md-button>
</md-content>
</md-sidenav>
<div>
<md-button ng-click="toggleLeft()">
<md-icon>menu</md-icon> Menu
</md-button>
</div>
</span>
</md-toolbar>`;
My Controller:
var nav=angular.module("vdApp", []);
nav.controller("vdNav", function($scope, $mdSidenav) {
alert("inside leftToggle");
$scope.toggleLeft = buildToggler('left');
function buildToggler(componentId){
return function(){
$mdSidenav(componentId).toggle();
};
}
});
Even alert isn't working.
What am I doing wrong? Any help or suggestion is appreciated.

how to create a collapsable/expandable open-locked sidenav with angular material

I want to have a sidenav with angular material which has 2 states: collapsed (only icons of the items are shown) and expanded (labes + icons shown). The example behaviour is shown at the RDash Dashboard, which is unfortunetally done with bootstrap.
Since the default sidenav of angular material does not provide that feature, I wanted to do it myself.
I have 2 ideas on how to do it:
1) using 2 different side-navs: one for collapsed, one for expanded. Then switching open-locked between them or just hiding/showing always one at a time.
2) using only 1 sidenav. somehow programmatically change the width, and the items of the sidenav and keeping it open-locked.
My favourite approach would be 2, but I want to know if there are any better ways to achieve that kind of sidenav with angular material?
I think approach 2 is the best - CodePen
Markup
<div ng-controller="AppCtrl" layout="column" style="height:500px;" ng-cloak="" class="sidenavdemoBasicUsage" ng-app="MyApp">
<section layout="row" flex="">
<md-sidenav class="md-sidenav-left" md-component-id="left" md-whiteframe="4" id="leftSideNav">
<md-toolbar class="md-theme-indigo" layout="row">
<h1 class="md-toolbar-tools">Sidenav Left</h1>
<span flex></span>
<md-button ng-click="toggleExpand()">{{toggleExpandButtonLabel}}</md-button>
</md-toolbar>
<md-content layout-padding="">
<md-button ng-click="close()" class="md-primary">
Close Sidenav Left
</md-button>
</md-content>
</md-sidenav>
<md-content flex="" layout-padding="">
<div layout="column" layout-align="top center">
<div>
<md-button ng-click="toggleLeft()" class="md-primary">
Toggle left
</md-button>
</div>
</div>
</md-content>
</section>
</div>
JS
angular
.module('MyApp',['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
.controller('AppCtrl', function ($scope, $timeout, $mdSidenav, $log, $element) {
$scope.toggleLeft = buildToggler('left');
$scope.toggleExpandButtonLabel = "Expand";
var sideNav = angular.element($element[0].querySelector('#leftSideNav'));
$scope.toggleExpand = function () {
if ($scope.toggleExpandButtonLabel == "Expand") {
sideNav.css("width", "500px")
}
else {
sideNav.css("width", "320px")
}
$scope.toggleExpandButtonLabel = ($scope.toggleExpandButtonLabel == "Expand") ? "Collapse" : "Expand";
}
$scope.close = function () {
$mdSidenav('left').close();
$scope.toggleExpandButtonLabel = "Expand";
sideNav.css("width", "320px")
};
function buildToggler(navID) {
return function() {
$mdSidenav(navID)
.toggle()
.then(function () {
$log.debug("toggle " + navID + " is done");
});
}
}
});

Angular controller loads but ng-repeat doesn't show

I'm learning angularJS and I'm having an issue trying to use ng-repeat.I know that the template and controller are loading because I did a console.log(self.post) test that shows the single post that I expect from the demoSuggestions and the template loads the comCtrl.post.title that I expect. But the ng-repeat='comment in comCtrl.post.comments doesn't show anything. Any ideas as to what I'm doing wrong?
HTML
<script type='text/ng-template' id='/suggestions.html'>
<div class='row' ng-controller='commentsController as comCtrl'>
<div class='col-xs-12'>
<div class='commentTitle'>
<h3 class='text-center'>{{comCtrl.post.title}}</h3>
</div><!--End of commentTitle-->
</div><!--End of col-->
</div><!--End of row-->
<div class='row' ng-repeat='comment in comCtrl.post.comments'>
<div class='col-xs-12 col-sm-10 col-sm-offset-1'>
<div class='commentContainer'>
<div class='row'>
<div class='col-xs-3 col-sm-2 col-md-1'>
<div class='thumbsUp'>
<i class="fa fa-thumbs-up" ng-click='comCtrl.upVote($index)'></i>
<span>{{comment.upvotes}}</span>
</div><!--End of thumbsUp-->
</div><!--End of col-->
<div class='col-xs-9 col-sm-10 col-md-11'>
<div class='commentBody'>
<span>{{comment.body}}</span>
</div><!--End of commentBody-->
</div><!--End of col-->
</div><!--End of row-->
</div><!--End of commentContainer-->
</div><!--End of col-->
</div><!--End of row-->
<div class='row'>
<div class='col-xs-12'>
<form id='comment' ng-submit="addComment()" style="margin-top: 50px">
<h3> Submit Your Comment </h3>
<div class="form-group">
<input type="text" class="form-control" placeholder="Place comment here" ng-model="body"></input>
</div><!--End of form-group-->
<button type="submit" class="btn btn-danger">Suggest</button>
</form>
</div><!--End of col-->
</div><!--End of row-->
</script>
Module & config
var suggestionApp = angular.module('suggestionBox', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/home.html',
})
.when('/suggestion/:id',{
templateUrl:'/suggestions.html'
})
.otherwise({
redirectTo:'/'
});
}]);
Controller & Service
.controller('commentsController',['$routeParams','suggestions', function($routeParams, suggestions){
var self = this;
var swap = 1;
self.post = suggestions.posts[$routeParams.id];
console.log(self.post)
self.addComment = function() {
self.post.comments.push({
body:self.body,
upvotes:0
});
};
self.upVote=function(index){
if(swap)
{
self.post.comments[index].upvotes += 1;
$('.thumbsUp .fa').eq(index).css('color','red');
swap=0;
}
else
{
self.post.comments[index].upvotes -= 1;
$('.thumbsUp .fa').eq(index).css('color', 'black');
swap=1;
}
};
}])
.factory('suggestions', [function(){
var demoSuggestions = {
posts: [
{
title: 'Term limits on congress',
avatar:'https://upload.wikimedia.org/wikipedia/commons/7/7a/US_Navy_040521-N-9909C-006_Established_by_the_American_Battle_Monuments_Commission,_the_memorial_honors_all_military_veterans_of_World_War_II.jpg',
upvotes: 15,
comments: [
{body:'love the idea',upvotes:0},
{body:'let\'s make this happen', upvotes:0},
]
},
{
title: 'Every two years a popular vote on two issues that passes into law without Congress.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/3/3e/The_Marine_Corps_War_Memorial_in_Arlington,_Va.,_can_be_seen_prior_to_the_Sunset_Parade_June_4,_2013_130604-M-MM982-036.jpg',
upvotes: 9,
comments: [
{body:'Only if the judicial branch still rules on its constitutionality.', upvotes:0},
{body:'Do you really think people would come out to vote?', upvotes:0},
{body:'I\'d be down for this',upvotes:0}
]
},
{
title: 'Create a biometric scanner for all those entering the country.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/e/ea/Washington_Monument_-_01.jpg',
upvotes: 7,
comments:[
{body:'Seriously, not cost effective', upvotes:0},
],
},
{
title: 'Become more isolationist and bring our troops back home.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/3/3b/Bunker_hill_2009.JPG',
upvotes: 3,
comments: [
{body:'sounds a little grim',upvotes:0}
],
}
]
};
return demoSuggestions;
}]);
If you look at the first two divs with the class row, you will notice, that the first div has a ng-controller attached (and displaying your title) and the second one has no controller attached (and displays nothing).
As your ng-repeat is not a child-element of your row with the controller, you cannot use your controller there. You could solve that if you move the ng-controller up one element so it will be on the parent of all your rows.

How to add ng-click handler dynamically

I tried to add ng-click on a button generated before (dynamic), but didn't work well. Also I tried already all solutions found on this forum and no one work well.
My html code:
<body class="max_height" ng-app="myApp">
<div class="container max_height" ng-controller="myCtrl">
<div id="play" tabindex="0" ng-init="init()" ng-keydown="keyDown($event)">
{{ content }}
</div>
</div>
<script src="js/angular.min.js"></script>
<script src="js/script.js"></script>
</body>
My AngularJS code:
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $compile) {
$scope.init = function() {
var el = '<button class="btn" id="start" data-ng-click="startAnimation()">Start</buttom>';
var element = angular.element(document.querySelector('#play'));
var generated = element.html(el);
$compile(generated)($scope);
}
$scope.startAnimation = function(){
console.log("click");
}
});
My error is "RangeError: Maximum call stack size exceeded" and this is generated by $compile(generated)($scope); . Another problem, derived from the first, is that if I make one click on button then the function startAnimation will me executed hundreds of times.
Please give me a solution. Where is the mistake.
Issue is with this line of code:
$compile(generated)($scope);
Instead it should be:
$compile(generated.contents())($scope);
You can assign the function to a scope variable and depending on your business logic assign appropriate functions to your ng-click. In the below example $scope.addGeoFence() is added to the ng-click of "Add GeoFence" list-item
$scope.layout = [
{name: 'Home', icon: 'home'},
{name: 'Add Geofence',
icon: 'add_location',
click: $scope.addGeoFence}
];
$scope.addGeoFence = function() {
console.log("calling addGeoFence()");
}
<md-list>
<md-list-item ng-repeat="snav in layout">
<md-button class="md-raised" ng-click="(snav.click)()" flex>
<md-icon md-font-library="material-icons">{{snav.icon}}
</md-icon>
<span>{{snav.name}}</span>
</md-button>
</md-list-item>
</md-list>

Resources