I have a mean stack application where there is a left panel for navigation. One of the tabs have a form, and after I submit the form, I call a function, which after successful completion has a $state.go('secured.dashboard'); which redirects it to another tab(dashboard). This works fine, but on the left panel the previous tab(application form tab) is still highlighted as active. Although, On clicking the tab, the active menu is highlighted correctly.
So, the problem is when I click submit, it redirects to a different tab(dashboard) but on the left-navigation panel, some other tab(application Form) is highlightened, although I change the variable $scope.selectedMenu = "dashboard";. I have added the relevant code snippets from files:
header-template.html
<nav class="navbar-default navbar-side" role="navigation" style="width:200px">
<div class="sidebar-collapse">
<ul class="nav" id="main-menu">
<li>
<a id="page1" ng-class='{"active-menu": selectedMenu == "dashboard"}' ui-sref="secured.dashboard" ng-click='selectedMenu = "dashboard"'><i class="fa fa-dashboard "></i>Dashboard</a>
</li>
<li>
<a id="page2" ng-class='{"active-menu": selectedMenu == "applicationForm"}' ui-sref="secured.applicationForm" ng-click='selectedMenu = "applicationForm"'><i class="fa fa-handshake-o "></i>Application Forms</a>
</li>
<li>
<a id="page3" ng-class='{"active-menu": selectedMenu == "adminprofile"}' ui-sref="secured.adminprofile" ng-click='selectedMenu = "adminprofile"' ng-show="adminUserTrue"><i class="fa fa-user-secret"></i>Administrator</a>
</li>
<li>
<a id="page4" ng-class='{"active-menu": selectedMenu == "managerProfile"}' ui-sref="secured.managerProfile" ng-click='selectedMenu = "managerProfile"' ng-show="isManager"><i class="fa fa-user-secret"></i>Manager</a>
</li>
<li>
<a ng-class='{"active-menu": selectedMenu == "logout"}' href="" ng-click="logout()" ng-click='selectedMenu = "logout"'><i class="fa fa-sign-out fa-fw"></i> Logout</a>
</li>
</ul>
</div>
</nav>
dashboard.js
(function() {
var app = angular.module('dashboard', []);
app.config(['$stateProvider', function($stateProvider) {
$stateProvider.state('secured.dashboard', {
url: '/dashboard',
controller: 'DashboardController',
templateUrl: '/views/dashboard.html'
});
}]);
app.controller('DashboardController', ['$scope', 'AuthService', 'user', '$state', '$http', function($scope, AuthService, user, $state, $http) {
console.log("yes, the controller is here");
$scope.user = user;
AuthService.setUser(user);
$scope.applicationShow = {};
$scope.logout = function() {
AuthService.logout().then(function() {
$scope.user = null;
$state.go('unsecured');
})
}
applicationForm.js
(function() {
var app = angular.module('applicationForm', []);
app.config(['$stateProvider', function($stateProvider) {
$stateProvider.state('secured.applicationForm', {
url: '/applicationForm',
controller: 'applicationFormController',
templateUrl: '/views/applicationForm.html',
params: {
obj: null
}
});
}]);
app.controller('applicationFormController', ['$http', '$scope', '$state', '$uibModal', function($http, $scope, $state, $uibModal) {
console.log($state.params.obj);
if ($state.params.obj == null) {
$scope.application = {
technical: false,
business: false
};
} else {
$scope.application = $state.params.obj;
}
console.log("I am finally the application");
console.log($scope.application);
$scope.submitApplication = function() {
$scope.submitted = true;
console.log("Submit called");
console.log($scope.application.title);
console.log($scope.user.email);
console.log("Yes, i am here!");
console.log($scope.application.userEmail);
$scope.application.state = "SUBMITTED";
$scope.application.heirarchy = $scope.managerjson[$scope.application.managerName].senior;
console.log($scope.application.heirarchy);
var check = 0;
$http.get('/application/applicationlistNum/').then(function(response) {
$scope.application.number = response.data.value.sequence_value;
console.log($scope.application.number);
for (var i = 0, len = $scope.applicationList.length; i < len; i++) {
if ($scope.applicationList[i]._id == $scope.application._id) {
check = 1;
console.log("matched");
break;
}
}
if (check == 1) {
$http.put('/application/applicationlist/' + $scope.application._id, $scope.application).then(function(response) {
refresh();
});
} else {
$http.post('/application/applicationList', $scope.application).then(function(response) {
console.log("Successfully submitted");
refresh();
});
}
swal({
title: "Great!",
text: "We have received your request",
type: "success",
timer: 3000,
confirmButtonText: "Wohoo!"
});
var contactInfo = {
managerEmail: $scope.application.managerName,
selfEmail: $scope.application.userEmail,
name: $scope.managerjson[$scope.application.managerName].name
};
clear();
sendMail(contactInfo);
console.log("changing states");
$scope.selectedMenu = "dashboard";
$state.go('secured.dashboard');
});
};
applicationForm.html
<div class="col-lg-12">
<form class="well form-horizontal" id="contact_form" ng-submit="submitApplication()" name="form">
<fieldset>
<!-- some more fields -->
<div class="form-group">
<label class="col-md-4 control-label"></label>
<div class="col-md-2">
<button type="submit" class="btn btn-primary"> Submit <span class="glyphicon glyphicon-send"></span></button>
<!-- <button class="btn btn-primary" ng-click="submitApplication()"> Submit <span class="glyphicon glyphicon-send"></span></button> -->
</div>
<div>
<button class="btn btn-warning" ng-click="saveApplication()"> Save <span class="glyphicon glyphicon-floppy-disk"></span></button>
</div>
</div>
</fieldset>
</form>
In applicationForm.js change $scope.selectedMenue = 'dashboard' to
$scope.selectedMenu = {name : "dashboard"};
And in your header template
<ul class="nav" id="main-menu">
<li>
<a id="page1" ng-class='{"active-menu": selectedMenu.name == "dashboard"}' ui-sref="secured.dashboard" ng-click='selectedMenu.name= "dashboard"'><i class="fa fa-dashboard "></i>Dashboard</a>
</li>
<li>
<a id="page2" ng-class='{"active-menu": selectedMenu.name== "applicationForm"}' ui-sref="secured.applicationForm" ng-click='selectedMenu.name= "applicationForm"'><i class="fa fa-handshake-o "></i>Application Forms</a>
</li>
<li>
<a id="page3" ng-class='{"active-menu": selectedMenu.name== "adminprofile"}' ui-sref="secured.adminprofile" ng-click='selectedMenu.name= "adminprofile"' ng-show="adminUserTrue"><i class="fa fa-user-secret"></i>Administrator</a>
</li>
<li>
<a id="page4" ng-class='{"active-menu": selectedMenu.name== "managerProfile"}' ui-sref="secured.managerProfile" ng-click='selectedMenu.name= "managerProfile"' ng-show="isManager"><i class="fa fa-user-secret"></i>Manager</a>
</li>
<li>
<a ng-class='{"active-menu": selectedMenu.name== "logout"}' href="" ng-click="logout()" ng-click='selectedMenu.name= "logout"'><i class="fa fa-sign-out fa-fw"></i> Logout</a>
</li>
</ul>
Related
I have two controllers headerController, aboutController.
headerController -> To maintain the navigation and redirection
aboutController -> works when about-us page loads.
My issue is I have to update the headerController variable value when aboutController loads. i.e When about us page loads, the navigation about-us should active, similar to all the pages.
This is my code:
app.service('shareService', function () {
var data;
return {
getProperty: function () {
return data;
},
setProperty: function (value) {
data = value;
}
};
});
app.controller('headerController', function ($scope, shareService) {
$scope.navigation = [
{url: '#!/home', name: 'Home'},
{url: '#!/about-us', name: 'About Us'},
{url: '#!/services', name: 'Services'}
];
var data = shareService.getProperty();
console.log(data);
$scope.selectedIndex = 0;
$scope.itemClicked = function ($index) {
console.log($index);
$scope.selectedIndex = $index;
};
});
app.controller('aboutController', function ($scope, shareService) {
console.log('test');
$scope.selectedIndex = 1;
shareService.setProperty({navigation: $scope.selectedIndex});
});
header.html:
<header ng-controller="headerController">
<div class="header">
<div class="first-half col-md-6">
<div class="row">
<div class="logo">
<img src="assets/img/logo.png" alt=""/>
</div>
</div>
</div>
<div class="second-half col-md-6">
<div class="row">
<div class="social-share">
<ul id="social-share-header">
<li><i class="fa fa-facebook" aria-hidden="true"></i></li>
<li><i class="fa fa-twitter" aria-hidden="true"></i></li>
<li><i class="fa fa-google-plus" aria-hidden="true"></i></li>
</ul>
</div>
</div>
</div>
<nav>
<ul ng-repeat="nav in navigation">
<li class="main-nav" ng-class="{ 'active': $index == selectedIndex }"
ng-click="itemClicked($index)">
{{nav.name}}
</li>
</ul>
</nav>
</div>
</header>
index.html
This is how my template works.
<body ng-app="myApp">
<section class="first-section">
<div ng-include="'views/header.html'"></div>
</section>
<section class="second-section">
<div ng-view></div>
</section>
<section class="last-section">
<div ng-include="'views/footer.html'"></div>
</section>
</body>
Update 1: Added index.html file.
Update 2: Issue explanation: If I run directly to the about us page, then still the home navigation is on active. But it should be About us
What is you are looking for is event based communication between your controllers. This can be easily done using. $rootScope.$on, $rootScope.$emit and $rootScope.$broadcast. Since explaining all three of them in this answer will be overkill. Kindly go through this article
On my website, if you scroll down to the third section that says "Victorious Gaming" and hover over the arrows on the left and right, no text shows up. However, the second time and thereafter you hover over the arrows, the text correctly shows up. Why do they not work the very first time? The same applies to when you hover over the text "Victorious Gaming"
In my Controller, I have:
projectApp.controller("featuredController", ["$rootScope", "$scope", function ($rootScope, $scope) {
$scope.leftArrow = function(){
$(function(){
$(".left-arrow a").hover(function(){
$('.left-info').css('opacity','1');
}, function(){
$('.left-info').css('opacity','0');
});
});
};
$scope.rightArrow = function(){
$(function(){
$(".right-arrow a").hover(function(){
$('.right-info').css('opacity','1');
}, function(){
$('.right-info').css('opacity','0');
});
});
};
$scope.bigWords = function(){
$(function(){
$(".big-word-padding").hover(
function() {
$('.blur-background').fadeOut(700);
$('.big-word-padding').find('h2').css('color','blue');
$('.color-blue').css('color','white');
}, function() {
$('.blur-background').fadeIn(300);
$('.big-word-padding').find('h2').css('color','white');
$('.color-blue').css('color','blue');
});
$(".big-word-padding").hover(
function() {
$('.blur-background').fadeOut(700);
$('.big-word-padding').find('.m-title').css('color','white');
$('.big-word-padding').find('#manga-title').addClass('textShadowM');
$('.big-word-padding').find('.m-title').addClass('textShadowManga');
$('.color-blue').css('color','white');
}, function() {
$('.blur-background').fadeIn(300);
$('.big-word-padding').find('.m-title').css('color','rgb(26, 107, 156)');
$('.big-word-padding').find('#manga-title').removeClass('textShadowM');
$('.big-word-padding').find('.m-title').removeClass('textShadowManga');
$('.color-blue').css('color','blue');
});
});
};
}]);
My HTML:
<div class="ng-container" ng-controller="featuredController">
<div ng-view class="view-animate">
</div>
</div>
External HTML file(templates/featured-proj.html):
<div class="big-feature">
<div class="big-background second-background"></div>
<div class="blur-background second-background"></div>
<div class="big-word">
<div class="big-word-padding" ng-mouseover="bigWords()">
<h2> Victorious <span class="color-blue">Gaming</span></h2>
<h3>UI Developer. Design.</h3>
<hr>
<i class="fa fa-caret-right fa-3x" aria-hidden="true" id="arrow-project"></i>
</div>
</div>
<div class="left-arrow">
<i class="fa fa-angle-left" aria-hidden="true"></i>
</div>
<div class="left-info">
My Art
</div>
<div class="right-arrow">
<i class="fa fa-angle-right" aria-hidden="true"></i>
</div>
<div class="right-info">
Mangahere
</div>
<!-- <ul class="nav navbar-nav navbar-right">
<li><i class="fa fa-shield"></i> Home</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul> -->
<div class="info-vic">
<div class="row-vic">
<div class="left-vic"></div>
<div class="right-vic"></div>
</div>
<div class="row-vic">
<div class="left-vic"></div>
<div class="right-vic"></div>
</div>
<div class="row-vic">
<div class="left-vic"></div>
<div class="right-vic"></div>
</div>
</div>
</div>
And my config for routing:
projectApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/feature', {
templateUrl : 'templates/featured-proj.html'
})
// route for the about page
.when('/feature2', {
templateUrl : 'templates/featured-proj-2.html'
})
// route for the contact page
.when('/feature3', {
templateUrl : 'templates/featured-proj-3.html'
})
.otherwise( { redirectTo: '/feature' } );
}]);
First, you have an extra $(function(){ ... }) wrapper both in leftArrow() and rightArrow().
In addition, the hover effect gets set only when when those functions are called for the first time. During that call, the opacity will not be modified.
I would replace ng-mouseover="leftArrow()" with ng-mouseenter="leftArrowShow()" ng-mouseleave="leftArrowHide()" and then define these functions like:
$scope.leftArrowShow = function() {
$('.left-info').addClass('show');
};
$scope.leftArrowHide = function() {
$('.left-info').removeClass('show');
};
And then, in CSS, have:
.left-info.show {
opacity: 1;
}
rightArrow() would be handled in a similar manner.
My problem probably is simple. I want hide my intro section on all pages less at home.
The problem is that when you hide hiding on every page and when you show shows on every page. I plan to just hide in the home page "/".
html:
<!-- Intro Section -->
<section id="intro" class="intro-section" ng-show="home">
<div class="container">
<div class="row">
<a class="btn btn-default page-scroll scroll_btn floating" href="#slide">
<span class="glyphicon glyphicon-arrow-down"></span>
</a>
</div>
</div>
</section>
JS:
app.controller("employerCtrl", ["$scope", "$location", "$route", function($scope, $location, $route) {
var path = $location.path();
console.log(path);
$scope.home = true;
if(path === "/") {
console.log("Inside");
$scope.home = true;
} else {
console.log("Inside else");
$scope.home = false;
}
}]);
Take home as root scope and make it false in home controller and true in other controllers.
app.controller("homecontroller", ["$scope", "$location", "$route","$rootScope", function($scope, $location, $route,$rootScope) {
$rootScope.home = false;
}]);
app.controller("othercontroller", ["$scope", "$location", "$route","$rootScope", function($scope, $location, $route,$rootScope) {
$rootScope.home = true;
}]);
<section id="intro" class="intro-section" ng-show="home">
<div class="container">
<div class="row">
<a class="btn btn-default page-scroll scroll_btn floating" href="#slide">
<span class="glyphicon glyphicon-arrow-down"></span>
</a>
</div>
</div>
</section>
I have data coming from a server that I want to display. This data is being paginated and also sorted. The relevant part of the controller is as follows:
appControllers.controller('PostsCtrl',
['$scope', 'Restangular', 'messageCenterService',
'$location', '$anchorScroll',
'$filter',
function ($scope, Restangular, messageCenterService,
$location, $anchorScroll, $filter) {
// Get all posts from server.
var allPosts = Restangular.all('api/posts');
allPosts.getList().then(function (posts) {
$scope.posts = posts;
$scope.predicate = 'rank';
$scope.reverse = false;
$scope.itemsPerPage = 10;
$scope.currentPage = 1;
$scope.totalItems = $scope.posts.length;
$scope.pageCount = function () {
return Math.ceil($scope.totalItems / $scope.itemsPerPage);
};
$scope.$watch('currentPage + itemsPerPage',
function () {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.position = (10 * ($scope.currentPage - 1));
$scope.filteredPosts = $scope.posts.slice(begin, end);
$location.hash('top');
// call $anchorScroll()
$anchorScroll();
});
});
Here is the html:
<li class="list-group-item" ng-repeat="post in filteredPosts | orderBy:predicate:reverse">
<div class="row-fluid">
<div class="col-sm-1 ">
<p style="margin-top: 1em">{{($index + 1) + position}}.</p>
</div>
<div class="col-sm-1 v-center">
<i class="fa fa-angle-up"></i> <br />
<small>{{post.votes}}votes</small> <br />
<i class="fa fa-angle-down"></i>
</div>
<div class="col-sm-8">
<h4><a href={{post.url}}>{{post.title}}</a></h4>
<div>
<ul class="list-inline">
<li ng-repeat="tag in post.tags">
<span class="fa fa-tag"></span>
<button ng-click="getTags(tag.id)">{{tag.name}}</button>
</li>
</ul>
<div>
<em>{{ post.created_at | timeAgo}}</em>
by <cite>{{post.author.username}}</cite>
</div>
<div>
<a href ng-click="select(post)">
<span class="fa-stack fa-2x">
<i class="fa fa-comment fa-stack-2x"></i>
<strong class="fa-stack-1x fa-stack-text fa-inverse">
{{post.comments.length}}
</strong>
</span>
</a>
</div>
</div>
<div class="panel" ng-show="isSelected(post)">
<ul class="nav nav-list" ng-repeat="comment in post.comments">
<li class="list-group-item">
<strong><cite>{{comment.author.username}}</cite></strong>
{{comment.updated_at | timeAgo }}
<p>{{comment.message}}</p>
</li>
</ul>
<form name="CommentForm" novalidate role="form" ng-if="user.isLoggedIn" ng-submit="CommentForm.$valid && comment(post)">
<label for="InputComment">Add a Comment</label>
<textarea ng-model="newComment.message" class="form-control" id="InputComment" rows="3" required></textarea>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</li>
<pagination total-items="totalItems" items-per-page="itemsPerPage"
ng-model="currentPage" ng-change="pageChanged()"></pagination>
I need some help with figuring out how to filter the order in which the data is displayed on the page. I have read other questions which ask about sorting but I did not see any where the content is also paginated with angularjs. The question I have is how do I do a live filter considering that I have objects coming back from the server and the content is then paginated?
You could create a paging filter, and combine it with orderBy to simulate filteredPosts.
app.filter('page', function () {
return function (input, start, end) {
return input.slice(start, end);
};
});
Then you can apply both filters in your template.
ng-repeat="post in posts | orderBy:predicate:reverse | page:begin:end"
You can use the orderBy filter also programmatically to sort your array
$scope.posts = posts;
$scope.posts=$filter('orderBy')($scope.posts,'rank',false );
$scope.itemsPerPage = 10;
...
$filter u have already as a dependency in your controller
I have a work and stuck it 2 days. Hope everyone know angularjs help me :).
I need to force a change html when have a change on model. Example:
This is html code:
<!--CAKE LIST-->
<div id="cakelist" ng-controller="CakeListCtrl">
<ul class="thumbnails cake-rack" cakes="cakes" ng-model="cakesModel">
<li class="pull-left cake-unit" ng-repeat="cake in cakes" cake="cake">
<div class="thumbnail">
<a href="{{cake.link}}">
<img ng-src="{{cake.avatar}}" alt="{{cake.title}}" class="img img-rounded img-polaroid" />
</a>
<h5 class="pull-left">
{{cake.title}}
</h5>
Shared
<div class="clearfix"></div>
<ul class="attrs unstyled">
<li>
<div class="pull-left">Mã sản phẩm</div>
<span class="pull-right">{{cake.type}}</span>
</li>
</ul>
</div>
</li>
</ul>
<input type="button" class="btn btn-primary" value="add more cake" class="cake-more" ng-click="addCake()" />
<input type="button" class="btn btn-danger" value="clear cake" class="cake-clear" ng-click="clear()" />
<img alt="Loading" src="/imagesroot/ajax-loader-1.gif" loading-stage="loadingStage" class="cake-loading"/>
</div>
now a have a menu outside of controller:
<div id="cake-catalog" class="cake-catalog">
<ul class="nav">
<li class="active">
<a cake-menu-unit href="sacmscategory50c2302b7ff0a">Nhân vật hoạt hình</a>
</li>
<li>
<a cake-menu-unit href="sacmscategory50c2308717a84">Động vật</a>
</li>
<li>
<a cake-menu-unit href="sacmscategory50c2309da00f6">Tạo hình 3D</a>
</li>
<li>
<a cake-menu-unit href="sacmscategory50c230ba08d9d">Các mẫu hình khác</a>
</li>
</ul>
</div>
I have angular module for add and clear:
var CakeList = angular.module('CakeList', ['ngResource']);
CakeList.service('CakeService', function($rootScope) {
var cakedata = [{avatar:"test", title: "test2"}];
$rootScope.loadCake = false;
var bf = function() { $rootScope.loadCake=true; };
var at = function() { $rootScope.loadCake=false; };
return {
cakes: function() {
bf();
at();
return cakedata;
},
addCake: function() {
bf();
cakedata.push(cake);
at();
},
clear: function() {
cakedata = []; console.log('clear');
}
};
});
CakeList.directive('cakeCatalog', function($rootScope, CakeService) {
var clickfn = function(e) {
e.preventDefault();
CakeService.clear();
};
var nonclickfn = function(e) {
e.preventDefault();
console.log('nonclickfn');
};
return {
restrict: "C",
link: function(scope, element, attrs) {
$rootScope.$watch('loadCake', function(newValue, oldValue) {
if (newValue===true) {
element.find('a').off('click').on('click', nonclickfn);
}
else {
element.find('a').off('click').on('click', clickfn);
}
});
}
};
But when runtime, i put click on a element of menu then the list cake not clear, even i check console.log in console box and see the cakedata really clear!. Can you help me this case ? :)
First of all, the design seems a bit weird by using everywhere $rootScope (among other things). But that's not the cause of the problem. The problem is the $watch which is not correct.
First of all, use loadCake as an object instead of a primitive type:
var loadCake = { loaded: false};
Use the objectEquality parameter in your $watch statement:
$rootScope.$watch('loadCake', function(newValue, oldValue) {
if (!newValue) return;
if (newValue.loaded === true) {
element.find('a').off('click').on('click', nonclickfn);
}
else {
element.find('a').off('click').on('click', clickfn);
}
}, true);