Showing HTML Elements based on current Angular Route - angularjs

I am trying to add three additional list items based on the routeProvider. If the reports route is navigated to, I want to use ng-show to make three more list items visible. I want them to remain visible unless the create user or manage user route is navigated to. The new list items are access reports and details reports.
HTML:
<ul class="nav nav-pills nav-stacked">
<li>
Create User
</li>
<li>
Manage Users
</li>
<li>
Reports
</li>
</ul>
routeProvider.js
adminApp.config(function($routeProvider) {
$routeProvider
.when('/createUser', {
templateUrl : 'app/components/admin/views/createUserView.html',
controller : 'createUserController'
})
.when('/manageUsers', {
templateUrl : 'app/components/admin/views/manageUsersView.html',
controller : 'manageUsersController'
})
.when('/editUser', {
templateUrl : 'app/components/admin/views/editUserView.html',
controller : 'manageUsersController'
})
.when('/reports', {
templateUrl : 'app/components/admin/views/reportsView.html',
controller : 'reportsController'
})
.when('/reports', {
templateUrl : 'app/components/admin/views/accessReportsView.html',
controller : 'reportsController'
})
.when('/reports', {
templateUrl : 'app/components/admin/views/detailsReportView.html',
controller : 'reportsController'
})
I am trying to do something like this:
<ul class="nav nav-pills nav-stacked">
<li>
Create User
</li>
<li>
Manage Users
</li>
<li>
Reports
</li>
<!--show this list item if the route is /reportsView or /accessReportsView orsummaryReportsView-->
<li>
<a ng-show="" href="#reports"> Access Reports</a>
</li>
</ul>
Link git repo if needed

Seems like as per you current configuration you should have #/ in your anchors href attribute
<ul class="nav nav-pills nav-stacked">
<li>
Create User
</li>
<li>
Manage Users
</li>
<li>
Reports
</li>
</ul>

Related

Angular ui-router nested states without nested views

Let's say I have a films app. It has Home/About/Films pages. Films page has subcategories: Comedy/Drama. Currently, I'm struggling with navigation. The Goal is when I click Home - it should render home. About - about. Films - render all films (for example simple cards with title/genre/year). When I click Films->Comedy - it should use the same controller as Films, render exactly same template but only comedy films. Moreover, navigation should be active with Films and Comedy.
I've created plunker to demonstrate first approach https://plnkr.co/edit/d0Db18ZJYtQx6aJEZ3xa?p=preview
So my first approach was:
.state('layout.films', {
url: '/films',
controller: 'FilmsCtrl as films',
template: '<div>All films</div>'
})
.state('layout.films.genre', {
url: '/:genre',
controller: 'FilmsCtrl as films',
template: '<div>{{ films.genre }} films</div>'
})
and this layout:
<div class="layout">
<ul>
<li><a ui-sref-active="_active" ui-sref="layout.home">home</a></li>
<li><a ui-sref-active="_active" ui-sref="layout.about">about</a></li>
<li>
<a ui-sref-active="_active" ui-sref="layout.films">films</a>
<ul>
<li><a ui-sref-active="_active" ui-sref="layout.films.genre({genre: 'comedy'})">comedy</a></li>
<li><a ui-sref-active="_active" ui-sref="layout.films.genre({genre: 'drama'})">drama</a></li>
</ul>
</li>
</ul>
<hr>
<div ui-view></div>
</div>
But that doesn't work. Turns out to be that nested states requires nested views. I was sad. And tried second approach: https://plnkr.co/edit/3YWAoLcPU3fd2FdebWpD?p=preview
I created only one films state:
.state('layout.films-genre', {
url: '/films/:genre?',
controller: 'FilmsCtrl as films',
template: '<div>{{ films.genre }} films</div>'
})
And fixed layout to work with this:
<a ui-sref-active="_active" ui-sref="layout.films-genre">films</a>
<ul>
<li><a ui-sref-active="_active" ui-sref="layout.films-genre({genre: 'comedy'})">comedy</a></li>
<li><a ui-sref-active="_active" ui-sref="layout.films-genre({genre: 'drama'})">drama</a></li>
</ul>
Seems working. It even highlights menu items properly (wow). But actually... I can't change state from films->comedy to films. Next thought was to change the link to the all films:
<a ui-sref-active="_active" ui-sref="layout.films-genre({genre: ''})">films</a>
But now it doesn't highlight root menu item (films) when I click one of the genres. What should I do to implement desired behavior?
If I understand your question correctly, you want to have a page that can render a specific genre of films?
If so, I think you should look up stateParams. This way you could have a menu that all directs to the same child view, but sends different parameters. Then sort the list of movies accordingly to the params being sent.
It would look something like this:
.state('layout.films-genre', {
url: '/films',
controller: 'FilmsCtrl as films',
template: '<div> Template goes here </div>'
params: { genre: 'all' } // as default if I remember correctly
})
You might aswell find the answer to your question here:
How to pass parameters using ui-sref in ui-router to controller

add active class to menu item clicked add remove from others

I want to add isActive class to an item menu when user click on this item, and remove isActive class from all others items.
I am trying to compare the id, this is the angularJS code:
$rootScope.isActive = function(idVal, event){
return idVal === event.target.id;
}
This is a part from Menu Html code:
<ul class="sidebar-nav">
<li>
<a ui-sref="" id='101' ng-class="{active: isActive($event, 101)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Rules
</a>
<ul class='dropdown sidebar-nav-dropdown' >
<li>
Transaction Mapping
</li>
<li>
File Setup
</li>
<li>
Code Setup
</li>
</ul>
</li>
<li>
<a href="#" id='102' ng-class="{active: isActive($event, 102)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Administrative Rules
</a>
<ul class='dropdown sidebar-nav-dropdown'>
<li>
<a ui-sref="admin.mapping-rules">Transaction Mapping</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">File Setup</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">Code Setup</a>
</li>
</ul>
</li>
</ul>
Thanks,
First of all, you shouldn't use the root scope. You should use the scope of the controller associated to that view.
Second, your code doesn't make much sense. $event can be used as a parameter of a function called... to react to an event:
ng-click="doSomething($event)"
But with ng-class, there is no $event.
All you need to have in your scope is the ID (or name, or whatever identifies a menu item) of the selected menu item:
$scope.selectedMenuItem = null;
When an item is clicked, you need to change the selected menu item:
ng-click="selectMenuItem(101)"
$scope.selectMenuItem(item) {
$scope.selectedMenuItem = item;
}
Then to associated a css class with the selected menu item, you simply need
ng-class="{active: selectedMenuItem === 101}"
That said, if all your links navigate to a given router state, you don't even need that selectedMenuItem. All you need is to add the active class if the current router state is the one the that the link allows navigating to (assuming $state is on your scope):
ng-class="{active: $state.includes('admin.mapping-rules')}

UI Router - Set parent to active for all child states when ui-sref is given as link to one child

Hi I have created a AngularJS application. I'm using UI-router.
I have one main menu and then sub menu.
Main menu I have something like
<ul class="nav nav-pills">
<li ng-class="{'active':$state.includes('home')}"><a ui-sref="home.main1">Home</a></li>
<li ui-sref-active="active"><a ui-sref="dashboard.dash1">Dashboard</a></li>
<li ui-sref-active="active"><a ui-sref="report">Reports</a></li>
</ul>
For one main menu home I have sub menu as
<ul class="nav nav-tabs" role="tablist">
<li ui-sref-active="active"><a ui-sref="home.main1">Main 1</a></li>
<li ui-sref-active="active"><a ui-sref="home.main2">Main 2</a></li>
</ul>
And for main menu dashboard i have sub menu as
<ul class="nav nav-tabs" role="tablist">
<li ui-sref-active="active"><a ui-sref="dashboard.dash1">Dashboard 1</a></li>
<li ui-sref-active="active"><a ui-sref="dashboard.dash2">Dashboard 2</a></li>
</ul>
In the above, the sub menus becomes active as per URL. but the parent menu is not becoming active.
In dashboard, I set ui-sref-active but the problem is the ui-sref**I set to **dash1 state. So dashboard state becomes active only when dash1 is active, not dash2.
In home I tried using ng-class as you can see. But it's not working.
Here is the plnkr Demo.
How to set the parent state active whenever child is active?
<li ng-class="{'active':$state.includes('home')}">
The expression you're using with ng-class above is evaluated in the context of the current $scope. Your controller doesn't define anything on the $scope, so the expression fails.
You can do this to make it work (plunkr):
app.controller('testCtrl', function($scope, $state) {
console.log($state.current.name);
$scope.$state = $state;
});
The merits of putting a service on the scope are debatable.

Automatically load a view from the controller after a timer in AngularJS

Basically, what I am attempting to do is create a Slideshow. The reason why I am using Angular for this is to get the benifits from templating and hopefully load only one template to the page at a time.
I have my data in a JSON file which the controller gets:
JSON:
{
"prop_title" : "Hyde Lane, Hyde",
"prop_postcode" : "SP2 7AP",
"prop_price" : "",
"prop_image" : "",
"prop_desc" : "",
"template" : "views/prop-thumbs.html",
"info_image" : "",
"duration" : "4000"
},
Controller:
function AppCtrl($scope, $http) {
//GET THE JSON FILE
$http.get('json/pages.json').success(function (data) {
//ASSIGN THE PAGES TO THE SCOPE
$scope.pages = data;
//LOOP THROUGH THE DATA AND ASSIGN THE VIEW
for (var i = $scope.pages.length - 1; i >= 0; i--) {
};
});
}
As you can see from my JSON file, each element contains the view file to use, and the duration that it needs to stay on screen for. Also, as you can see in my controller, I have begun creating a for loop that will hopefully contain my code that will assign view on a timer. Is this possible? Whats the easiest and best way to do this?
Any help seriously appreciated, I have pretty tried everything now!
as Mark Rajcok pointed in the comments, you will probably need to use a $timeout
Here is what I would have done : http://jsfiddle.net/DotDotDot/zbg57/
The html part is quite simple, I just tell angular to include what is in the whatToInclude variable :
<div ng-include='whatToInclude'></div>
On the controller side, I initialize the data with a template and a counter, then I define a nextSlide function, which will call the next template with the timeout passed in parameter. I call this function to start the loop with the initials parameter (0s timeout, first element of the data)
$scope.whatToInclude='tpl1.html';
$scope.count=0;
$scope.nextSlide=function(timeOut){
$timeout(function(){
$scope.whatToInclude=$scope.data[$scope.count].template
$scope.count+=1
if($scope.count>=$scope.data.length)
$scope.count=0
$scope.nextSlide($scope.data[$scope.count].duration)
},timeOut);
};
$scope.nextSlide(0)
I think this can be a good start for a slideshow ;)
Have fun
I made a tutorial with a similar goal in mind:
https://www.youtube.com/watch?v=9COtsDovNpM
Basically store the views in an array of some sort and then based on a variable display that template. Angular will not load the template until ng-show='true' so they won't load all at once but as their clicked or cycled through.
Code example from my tutorial.
Replace ng-switch with whatever works for you.
The common premise is "show this template when that is equal to true".
<div class="tabbable tabs-left">
<ul class="nav nav-tabs">
<li ng-class="{active: main.active.tab == 'info'}">
<a ng-click='main.active.tab = "info"'>Settings</a>
</li>
<li ng-class="{active: main.active.tab == 'categories'}">
<a ng-click='main.active.tab = "categories"'>Categories</a>
</li>
<li ng-class="{active: main.active.tab == 'pages'}">
<a ng-click='main.active.tab = "pages"'>Pages</a>
</li>
<li ng-class="{active: main.active.tab == 'locations'}">
<a ng-click='main.active.tab = "locations"; main.locationgroup = {}'>Locations</a>
</li>
<li ng-class="{active: main.active.tab == 'experts'}">
<a ng-click='main.active.tab = "experts";'>Experts</a>
</li>
<li ng-class="{active: main.active.tab == 'resources'}">
<a ng-click='main.active.tab = "resources"'>Resources</a>
</li>
</ul>
<div class="tab-content">
<div ng-switch='main.active.tab'>
<div
ng-switch-when='info'
ng-include='"/apps/series/views/tabs/info.html"'></div>
<div
ng-switch-when='categories'
ng-include='"/apps/series/views/tabs/categories.html"'></div>
<div
ng-switch-when='pages'
ng-include='"/apps/series/views/tabs/pages.html"'></div>
<div
ng-switch-when='locations'
ng-include='"/apps/series/views/tabs/locations.html"'></div>
<div
ng-switch-when='experts'
ng-include='"/apps/series/views/tabs/experts.html"'></div>
<div
ng-switch-when='resources'
ng-include='"/apps/series/views/tabs/resources.html"'></div>
</div>
</div>
</div>

AngularJS - Change class on list when clicked

I am just getting started with Angular and am still trying to get a feel for how it works. I have 2 questions about a list with ng-repeat. I will post my code first.
HTML
<div class="row">
<div class="span2">
<ul class="nav nav-pills nav-stacked">
<li ng-repeat="class in classes | orderBy:orderProp" ng-class="activeClass">
<a ng-click="loadRoster(class)">{{class.class_name}}</a>
</li>
</ul>
</div>
<div class="span2">
<ul class="nav nav-pills nav-stacked">
<li ng-repeat="student in students | orderBy:orderProp">
<a ng-click="enterPassword(student)">{{student.student_name}}</a>
</li>
</ul>
</div>
</div>
Controller
function ClassListCtrl($scope, $http) {
$scope.loadedList=[];
$scope.students=[];
$scope.activeClass='';
$scope.orderProp = 'alphabetical';
$http.get('data/class.json').success(function(data) {
$scope.classes = data;
});
$scope.loadRoster=function(classlist){
$scope.selectedClass=classlist;
$scope.activeClass='active';
if($scope.loadedList[classlist.class_id]== undefined){
$http.get('data/class_'+classlist.class_id+'.json').success(function(data){
$scope.loadedList[classlist.class_id]=data;
$scope.students=data;
});
}
$scope.students=$scope.loadedList[classlist.class_id];
}
$scope.studentClick=function(student){
}
}
Ok, this pulls the data just fine. I can click on a class and it loads the students in that class. To cut down on AJAX calls, I store those that are clicked and if that class is clicked again, it will fetch it from memory instead of making the call. This is fine as class rosters are static for the most part.
I am trying to have it load a default class roster (the first alphabetically) and mark just that list item as active.
Secondly, when they click a list item, I want to change that list item to active, and change the class of the other ones back to nothing. I am not sure how to do that either. As it stands, none are active now, but when I click one, all become active.
in Html ng-class, if class_id matches $scope.activeClass set class of li to "active"
<li ng-repeat="class in classes | orderBy:orderProp" ng-class="{'active':class.class_id == activeClass}">
in Controller when $scope.loadRoster is called set $scope.activeClass to class_id of the class passed to function
$scope.loadRoster=function(classlist){
$scope.selectedClass=classlist;
$scope.activeClass=classlist.class_id;
for your default active class just set $scope.activeClass to class_id of the class

Resources