All Bookmarks are redirecting to same element - angularjs

I have three bookmarks, two are on same page and one in different page, when ever I click on the link, it moving to same element and it was't smooth.
The frame works I am using are materializecss, angularjs 1 and ui router
I don't know how to write the code for it.
myapp.controller('ctrl',ctrl);
ctrl.$inject=['$scope', '$location', '$anchorScroll'];
function ctrl($scope, $location, $anchorScroll) {
$scope.scrollTo = function(team) {
$location.hash('team');
$anchorScroll();
};
$scope.scrollTo = function(contact) {
$location.hash('contact');
$anchorScroll();
};
};
<body ng-controller="ctrl">
<div class="container">
<div class="fixed-action-btn toolbar">
<a class="btn-floating btn-large light-blue accent-2 pulse">
<i class="large material-icons">menu</i>
</a>
<ul>
<li class="waves-effect waves-light"><a ui-sref="home">HOME</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo(home/project)">PROJECTS</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo(team)">TEAM</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo(contact)">CONTACT</a></li>
</ul>
</div>
</div>
Any help is appreciate.
Thank you.

You dont need to add multiple scrollTo function in controller, you can use only one function for all like this
myapp.controller('ctrl', ctrl);
ctrl.$inject = ['$scope', '$location', '$anchorScroll'];
function ctrl($scope, $location, $anchorScroll) {
$scope.scrollTo = function(state) {
$location.hash(state);
$anchorScroll();
}
};
And html is
<body ng-controller="ctrl">
<div class="container">
<div class="fixed-action-btn toolbar">
<a class="btn-floating btn-large light-blue accent-2 pulse"> <i class="large material-icons">menu</i> </a>
<ul>
<li class="waves-effect waves-light"><a ui-sref="home">HOME</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo('home/project')">PROJECTS</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo('team')">TEAM</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo('contact')">CONTACT</a></li>
</ul>
</div>
</div>
</body>

Related

UI-Router 1.0.0-beta.2 and UI-Bootstrap 2.1.4 dropdown not closing

I'm using ui-route ui-sref in my links with the navbar using UI-Bootstrap dropdowns and if I use the anchor tag with href, the dropdown closes on click, but the anchor tags with ui-sref does not close the dropdown. I've got the following plnkr with it showing the bug.
Angular Code
angular.module('app', ['ui.bootstrap', 'ui.router'])
.config(appRoute)
.controller('myController', myController);
appRoute.$inject = ['$stateProvider'];
function appRoute($stateProvider) {
$stateProvider.state('index', {
url: '/index',
template: '<h1>indexRoute</h1>'
})
.state('other', {
url: '/other',
template: '<h1>otherRoute</h1>'
})
}
function myController() {
var ctrl = this;
ctrl.title = 'Title';
ctrl.user = 'User#user.com';
ctrl.test = test;
ctrl.test2 = test2;
function test() {
console.log('TEST LINK!')
}
function test2() {
console.log('TEST 2')
}
}
HTML
<body ng-controller="myController as $ctrl" style="{padding-top: 70px;}">
<nav id="isec-menu" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<div class="intelisecure-header">
<span>{{$ctrl.title}}</span>
</div>
</div>
<div class="collapse navbar-collapse navbar-right">
<ul class="nav navbar-nav">
<li id="usermenu" class="dropdown user-menu-dropdown" uib-dropdown="">
<a href="" class="uib-dropdown-toggle username" uib-dropdown-toggle="">
<i class="fa fa-user fa-fw"></i>
{{$ctrl.user}} <span class="caret"></span>
</a>
<ul class="dropdown-menu" uib-dropdown-menu="" role="menu">
<li role="menuitem">
<a href="/index" ng-click="$ctrl.test()">
<i class="fa fa-fw fa-sign-out menu-icon"></i>
<span class="menu-text">index href</span>
</a>
</li>
<li role="menuitem">
<a ui-sref="other" ng-click="$ctrl.test2()">
<i class="fa fa-fw fa-sign-out menu-icon"></i>
<span class="menu-text">other sref</span>
</a>
</li>
<li role="menuitem">
<a href="" ng-click="$ctrl.logout()">
<i class="fa fa-fw fa-sign-out menu-icon"></i>
<span class="menu-text">Logout</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<ui-view>
<div>
test
</div>
</ui-view>
</body>
Not perfectly built, I was trying to see if I could replicate the issue with my
https://plnkr.co/edit/Rz3AbgnYnWI34DjuByY6?p=preview
Apparently this was a known issue and was resolved by updating to UI-Router 1.0.0-beta.3

Need to call ng-switch by url or $location

I am trying to use a url to call a tab element. For example, a url like: localhost:9000/widget&view=map will land on the page with the map tab selected and shown the map tab body.
<div class="search-result-tab" ng-init="selectTab='list'">
<ul class="nav tab-header">
<li ng-class="{active: selectTab=='list'}" ng-click="selectTab='list'; changedTab()">
<a href={{listTabURL}}>List</a>
</li>
<li ng-class="{active: selectTab=='map'}" ng-click="selectTab='map'; changedTab()">
<a href={{mapTabURL}}>Map</a>
</li>
</ul>
<div class="tab-body" ng-switch on="selectTab">
<div class="tab-content" ng-switch-when="list">
<div ng-include="'list.html'"></div>
</div>
<div class="tab-content" ng-switch-when="map">
<div ng-include="'map.html'"></div>
</div>
</div>
</div>
Other urls are:
list: localhost:9000/widget&view=list
map: localhost:9000/widget&view=map
Similar question here. One suggestion is to inject the $location service and switch on $location.path, might be worth a try if you are not going to try ui-router (which you really should look into!)
function Ctrl($scope, $location) {
$scope.pagename = function() { return $location.path(); };
};
<div id="header">
<div ng-switch on="pagename()">
<div ng-switch-when="/home">Welcome!</div>
<div ng-switch-when="/product-list">Our products</div>
<div ng-switch-when="/contact">Contact us</div>
</div>
</div>

Angular how to redirect to a tab

I have a page which has got 5 tabs. There is another page which contains the links pointing to these tabs. Whenever a user clicks a link on this page, corresponding tab should be opened on angular application page.
The tab are working fine when user manunally clicks on a tab but I am unable to find how can I select a tab by default.
Add in app.js:
$routeProvider.when('/trend', {
templateUrl:'partials/trend.html'
}).when('/deepdive', {
templateUrl:'partials/deepdive.html'
}).when('/driversNdrainers', {
templateUrl:'partials/DriversNDrainers.html'
}).when('/timeline', {
templateUrl:'partials/timeline.html'
}).otherwise("/trend");
index page:
<div header></div>
<div class="row">
<div class = "col-md-12" ng-include="'partials/home.html'"></div>
</div>
<div footer></div>
The home controller creates the tabs dynamically.
Home.html
<div class="" fade-in ng-controller="HomeCtrl">
<ul class="nav nav-pills">
<li ng-class="tabClass(tab)" ng-repeat="tab in tabs" tab="tab"><a href="{{tab.link}}" id="{{tab.id}}"
ng-click="setSelectedTab(tab)">{{tab.label}}</a></li>
</ul>
<div ng-view></div>`enter code here`
Controller:
var homectrl = myApp.controller('HomeCtrl', ['$scope', '$routeParams', '$location','$state', function ($scope, $routeParams,$location,$state) {
$scope.tabs = [
{ link : '#/trend', label : 'Trend', id: "trendLink"},
{ link : '#/deepdive', label : 'Deep Dive' , id:"deepdriveLink"},
{ link : '#/driversNdrainers', label : 'Drivers & Drainers', id:"ddLink" },
{ link : '#/timeline', label : 'Timeline' , id: "timelineLink"},
{ link : '#/zoomin', label : 'Zoom In', id: "zoominLink" }
];
$scope.selectedTab = $scope.tabs[0];
$scope.setSelectedTab = function(tab) {
$scope.selectedTab = tab;
};
$scope.tabClass = function(tab) {
return $scope.selectedTab == tab? "active": "";
};
angular.element(document).ready(function () {
$.each($scope.tabs,function(i){
if(this.link==location.hash){
$scope.setSelectedTab(this);
//$state.go("/trend");
return;
}
});
});
}]);
What I see here is that the tab is selected but the content inside tab is not loaded.
Your code inside jQuery is not executed in Angular's digest cycle. Try adding $scope.$apply(); right after $scope.setSelectedTab(this);
To understand why you should do this read: "Scope Life Cycle" at https://docs.angularjs.org/guide/scope
Here is the solution you can refer to stackblitz
I had to do some modification in its function to achieve the result as per my requirement.
modified solution:
moveToSelectedTab(tabName: string) {
for (let i = 0; i < document.querySelectorAll('[aria-selected]').length; i++) {
let element = document.querySelectorAll('[aria-selected="false"]')[i];
if (element != undefined) {
if ((<HTMLElement>document.querySelectorAll('[aria-selected="false"]')[i]).innerHTML == tabName) {
(<HTMLElement>document.querySelectorAll('[aria-selected="false"]')[i]).click();
}
}
}}
HTML
<ul class="nav nav-tabs" id="editorTab" role="tablist">
<li class="nav-item active" role="presentation">
<a class="nav-link active" id="bannerArea-tab" data-toggle="tab" href="#bannerArea" role="tab"
aria-controls="bannerArea" aria-selected="true">General Information</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="cardArea-tab" data-toggle="tab" href="#cardArea" role="tab"
aria-controls="cardArea" aria-selected="false">Banner Content</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="mainArea-tab" data-toggle="tab" href="#mainArea" role="tab"
aria-controls="mainArea" aria-selected="false">Main Content</a>
</li>
</ul>
<div class="tab-content" id="editorTabContent">
<div class="tab-pane fade show active col-sm-12" id="bannerArea" role="tabpanel" aria-labelledby="bannerArea-tab">
<div class="form-group">
</div>
<div class="text-right margin-top-xl">
<button class="btn-icon-confirm" (click)="moveToSelectedTab('Banner Content')">Next<i class="material-icons">arrow_forward</i></button>
</div>
</div>
<div class="tab-pane fade show active col-sm-12" id="cardArea" role="tabpanel" aria-labelledby="cardArea-tab">
<div class="form-group">
</div>
<div class="text-right margin-top-xl">
<button class="btn-icon-confirm" (click)="moveToSelectedTab('Main Content')">Next<i class="material-icons">arrow_forward</i></button>
</div>
</div>
<div class="tab-pane fade col-sm-12" id="mainArea" role="tabpanel" aria-labelledby="mainArea-tab">
<div class="text-right margin-top-xl">
<button class="btn-icon-confirm" (click)="moveToSelectedTab('General Information')"><i class="material-icons">check</i></button>
</div>
</div>
</div>

Scope variables don't reflect in template

I have part of an angular app setup as follows:
<section >
<div ng-controller="setHeaderCtrl" class="navbar navbar-default header">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#collapsed-bar">
<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 brand-text" ui-sref="index">
<span class="sports-text">Sports</span>
<span class="gully-text">Gully</span>
</a>
</div>
<div class="collapse navbar-collapse" id="collapsed-bar">
<ul class="nav navbar-nav navbar-left" ng-if="searchingAway">
<li class="local-search-cont">
<input type="text" class="local-type-top" placeholder="Search">
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li ng-if="!userObject">
<a ng-click="showLogin()" class="navbar-txt-block" style="cursor: pointer;">
Login
</a>
</li>
<li ng-if="userObject.user">
<a class="navbar-txt-block" ui-sref="home" style="cursor: pointer;">
Home
</a>
</li>
<li ng-if="userObject">
{{userObject}}
<a class="navbar-txt-block" style="cursor: pointer;">
{{userDetails.first_name}} {{userDetails.last_name}}
</a>
</li>
</ul>
</div>
</div>
</div>
</section>
and my setHeaderCtrl is as follows:
app.controller('setHeaderCtrl',['$scope', '$rootScope', '$http', '$state', 'Page', '$modal',
function($scope, $rootScope, $http, $state, Page, $modal){
$rootScope.$on('userSet', function(){
var authKey = $rootScope.authKey;
$http.defaults.headers.common.Authorization = 'Token '+authKey;
$http.get('/loginCheck/').success(function(data){
$scope.userObject = data;
$scope.userDetails = data.user;
});
});
$scope.userObject = {}
$http.get('/loginCheck/').success(function(data){
$scope.userObject.user = data;
$scope.userDetails = data.user;
console.log($scope.userDetails);
}).error(function(data, status){
if(status == 401){
$scope.userObject.user = undefined;
}
});
$rootScope.$on('setAwayHeader', function(){
$scope.searchingAway = true;
});
$rootScope.$on('setIndexHeader', function(){
$scope.searchingAway = false;
});
$scope.showLogin = function(){
$modal.open({
windowClass: 'modal fade login-modal',
templateUrl: '/static/partials/modals/loginModal.html',
controller: 'loginCtrl'
})
}
}
])
My problem is such that the {{userObject}} or {{userDetails}} never displays. I can guarantee that there's a response from the server because console.log shows the correct data.
The expression ng-if="userObject" is not good, it always true. Replace it by boolean, or by userObject property: ng-if="userObject.user". Jsfiddle

AngularJS using $watch in controllers

So I have been reading this article which suggests using $watch in your controllers is bad.
I am trying to take the advice. I have controller that looks like this:
.controller('NavigationController', ['$rootScope', '$scope', function ($rootScope, $scope) {
var self = this;
// Get our current user
self.user = $rootScope.user;
// Watch
$scope.$watch(function () {
// Return our user
return $rootScope.user;
}, function (user) {
// Set our user to the new user
self.user = user;
});
}]);
and my HTML looks like this:
<div class="account-header" ng-controller="NavigationController as controller" ng-cloak ng-show="controller.user.authenticated">
<div class="container">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-account">
<div class="collapse navbar-collapse" id="account-menu">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown" dropdown>
<a class="dropdown-toggle" dropdown-toggle>{{ controller.user.userName }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a ui-sref="teams">Team settings</a></li>
<li><a ui-sref="account">Account settings</a></li>
<li><a ui-sref="logout">Sign out</a></li>
</ul>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
</div>
You can see that I am only showing the account menu when the user is logged in. After reading the article, I am struggling to see how I can actually change my controller.
Does anyone have any suggestions?
Update 1
Some of you have said because it is in the rootscope, I don't have to do anything. I can just use user in the HTML and it should work fine.
I tested this like this:
<div class="account-header" ng-cloak ng-show="user.authenticated">
<div class="container">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-account">
<div class="collapse navbar-collapse" id="account-menu">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown" dropdown>
<a class="dropdown-toggle" dropdown-toggle>{{ user.userName }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a ui-sref="teams">Team settings</a></li>
<li><a ui-sref="account">Account settings</a></li>
<li><a ui-sref="logout">Sign out</a></li>
</ul>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
</div>
and it did work.
Now what I want to do is add another menu item, this item is only shown if there are any kits. But I would rather not do a API call on every state change, so the only thing I can see is to amend something when a kit is either added or deleted.
But I am not sure what is the best way to do this.
When the user changes broadcast a 'userLoggin' event on the $rootScope. Then listen for that event in your controller.
Or $emit the event on $rootScope and in the controller listen on the $rootScope by injecting it.
$rootScope.$on('userLoggin' function() {
// React to user change.
})

Resources