Angular Pages with QueryString - angularjs

I want to create an event page and event detail page in angular. I created my states like this in my app.js
.state('app.event', {
url: "/event",
views: {
'menuContent': {
templateUrl: "views/event.html",
controller: "eventController"
}
}
})
.state('app.eventDetail', {
url: "/eventDetail/:eventId",
views: {
'menuContent': {
templateUrl: "views/eventDetail.html",
controller: "eventDetailController"
}
}
})
I m getting my events in my views/event.html page like this
<div class="list" ng-controller="EventController">
<div class="item item-avatar item-left" ng-repeat="EventName in Events track by $index">
<p>{{ EventName }}</p>
<p>{{ EventId }}</p>
</div>
</div>
My question is how can i redirect my Event page to EventDetail page with event Id ?
And my other question is how can i get that id in my EventDetail page ?

You could use ui-sref like this:
<div class="list" ng-controller="EventController">
<div class="item item-avatar item-left" ng-repeat="EventName in Events track by $index">
<a ui-sref="app.eventDetail({eventId: EventId})">{{ EventName }}</a>
</div>
</div>
Clicking the link for an event should redirect to the details page and then to get the parameter from the url you would use the $stateParams service:
app.controller('eventDetailController', function($scope, $stateParams) {
$stateParams.eventId;
});
I suspect that there may be a few errors in your code. So if you experience any issues with the above, please update your question with the code for both controllers and I'll try to update my answer to account for them.

Related

can't get the value of $stateParams in controller

I am trying to get the value of $stateParams in my controller but it is always undefined but I can see there is a value in my view.
As you can see there are values on each link.
app.js
.state('app.help', {
url: '/help',
views: {
'menuContent': {
templateUrl: 'templates/help.html'
}
}
})
.state('app.help-replies', {
url: '/help/:id',
views: {
'menuContent': {
templateUrl: 'templates/help-replies.html'
}
}
})
html view
this is the where the lists of data displays
<div ng-repeat="x in helpData">
<a class="row responsive-xs" href="#/app/help/{{x.id}}">
<div class="col"><h6>{{x.subject}}</h6></div>
</a>
</div>
this is where the single view of the clicked data in the above view.
<div class="row responsive-xs" ng-init="viewHelpAndReplies()">
<div class="col">
<h5>Subject: {{$scope.help_id}}</h5>
</div>
</div>
controller.js
$scope.viewHelpAndReplies = function(){
console.log($stateParams.id);
}
I think you should use ui-sref to pass data
<div ng-repeat="x in helpData">
<a class="row responsive-xs" ui-sref="app.help-replies({id: x.id})">
<div class="col"><h6>{{x.subject}}</h6></div>
</a>
</div>
and retrieve id with
$scope.id = $stateParams.id;
Okay I think I got what I needed. But I am not sure if this is good, but for me it is okay because it works.
Here's what I do:
I change the href
href="#/app/help/{{x.id}}"
into ng-click and create a function
ng-click="doViewHelp({id:x.id})"
and create function in my controller.js:
$scope.doViewHelp = function(data){
$state.go('app.help-replies');
// some codes...
}
Thanks.

How to use 1 ui-view if there are multiple ui-view elements with the same name?

I have a html structure like so,
<div class="content-wrapper">
<div class="content">
Click me
</div>
<div ui-view="content-view">Template goes here</div>
</div>
<div class="content-wrapper">
<div class="content">
Click me
</div>
<div ui-view="content-view">Template goes here</div>
</div>
Two content-wrapper divs with both a ui-view called content-view.
And my state config looks like this,
$stateProvider
.state('home', {
url: ''
})
$stateProvider
.state('content-view', {
url: '',
views: {
"content-view": {
template: '<div>Content</div>',
}
},
})
See it in action here > http://plnkr.co/edit/997KbH9beLLHClM0IKb9?p=preview
If a user clicks on one of two ui-sref elements both the ui-view 'content-view` elements get triggered and inject the template.
What I would like to see is that only the ui-view in the content-wrapper element that gets clicked gets triggered.
Hiding one or the other element wouldn't be a good solution, because then the views will still have to load all the data in them. So I think my best bet is to target the specific ui-view in the same content-wrapper element.
* Update *
I've updated my plunker > http://plnkr.co/edit/997KbH9beLLHClM0IKb9?p=preview
I create several rows with content divs in them. Each row has 1 ui-view element. If a user clicks on one of the links it places the template in each view. While I want to target the view that's inside the content wrapper that the user clicked on.
Instead of nested views you can use directive here as you have repeating same objects so nested views do not help you that much...
just define a directive which is only for templating (of course you can extend its feature by your needs)..,
app.directive('contentTemplate', function() {
return {
restrict: 'E',
template: '<div class="content-view">{{vm.movie.title || "No Movie"}} is selected</div>',
scope: {
movie: '='
},
controller: ContentTemplateController,
controllerAs: 'vm',
bindToController: true
}
})
function ContentTemplateController() {
// your directive controller if you need it
}
then bind your selected content with directive then whenever you change movie content of directive will be changed as well...
<div class="content-wrapper" ng-repeat="movieGroup in movieGroups">
<div class="content" ng-repeat="movie in movieGroup">
<button ng-click="movieGroup.selectedMovie = movie;">{{ movie.title }}</button>
</div>
<content-template movie="movieGroup.selectedMovie"></content-template>
</div>
Creating independent ui-view states with the same name is simply not possible with the current model that ui-router has provided. The closest possible implementation is probably ui-router-extras's sticky module. You can create multiple independent(sticky) states by taking advantage of multiple named views in a state.
DEMO
Javascript
app = angular.module('myApp', [
'ui.router',
'ct.ui.router.extras'
]);
app.controller('mainCtrl', ['$scope',
function($scope){}
])
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('main', {
url: '/'
})
.state('main.sub1', {
sticky: true,
views: {
'sub1#': {
template: 'sub1<ui-view />'
}
}
})
.state('main.sub1.part1', {
template: '.part1'
})
.state('main.sub2', {
sticky: true,
views: {
'sub2#': {
template: 'sub2<ui-view />'
}
}
})
.state('main.sub2.part1', {
template: '.part1'
});
});
HTML
<div class="content-wrapper">
<div class="content">
<a ui-sref="main.sub1">main.sub1</a> |
<a ui-sref="main.sub1.part1">main.sub1.part1</a>
</div>
<div ui-view="sub1">Template goes here</div>
</div>
<div class="content-wrapper">
<div class="content">
<a ui-sref="main.sub2">main.sub2</a> |
<a ui-sref="main.sub2.part1">main.sub2.part1</a>
</div>
<div ui-view="sub2">Template goes here</div>
</div>

Issue with refreshing page

Having problem with my angular app, when I refresh page it doesn't show me correct page. It looks like the way I pass parameter to the page is not right.
So I have my state in the ui-router:
.state('stateDashboard', {
url: '/dashboard',
templateUrl: '/templates/dashboard.html',
controller: 'dashboardController'
})
In the page where I have list of Dashboards:
<div class="tile" ng-repeat="d in dashList" ng-class="[d.tileColour, d.tileSize]" ui-sref="stateDashboard" ng-click="setDashboard(d.id)">
<div class="tile-body">
<i class="fa fa-dashboard"></i>
</div>
<div class="tile-object">
<div class="name">
{{d.name}}
</div>
</div>
</div>
where setDashboard(id) sett id to $rootScope.dashId
and in my controller to display dashboard I have:
Dashboards.getDashboard({ id: $rootScope.dashId }).$promise.then(function (result) {
$rootScope.model = result;
}
So now when I refresh the page $rootScope.dashId is undefined so doesn't display page correctly. How can I fix it?
Add your dashId to the URL so you can pass it when changing dashboard and/or refreshing the page. So avoid calling setDashboard because it will only have effect until you reload the page.
.state('stateDashboard', {
url: '/dashboard/:dashId',
templateUrl: '/templates/dashboard.html',
controller: 'dashboardController'
})
Now inside your controller you can get it like this. No need to use the $rootScope.
Dashboards.getDashboard({ id: $stateParams.dashId }).$promise.then(function (result) {
$rootScope.model = result;
}

change background and color of li using ui-sref-active

I want to change the background-color and color of the li element when it is active. Below is my html page and there are links in the html page which are bind to the states in js file.. How can i change the color of span and whole background of li using ui-sref-active
.state ('home', {
url: "/home",
abstract: true,
templateUrl:"app/templates/home.html",
controller: "WallCtrl"
})
.state('home.updates', {
url: "/updates",
views: {
'menuContent': {
templateUrl: "app/templates/updates.html"
}
}
})
.state('home.discover', {
url: "/discover",
views: {
'menuContent':{
templateUrl: "app/templates/discover.html",
controller: "DiscoverCtrl"
}
}
})
.state('MyFollowList',{
url:'/myfollowlist',
templateUrl:'app/templates/myfollow.html',
controller: 'MyFollowCtrl',
resolve: {
product_list: function ($http, ApiService, $log) {
$log.log("url entered :"+ url)
var result = $http.get(url+ ApiService.get_url('get_list')).success(function (data) {
$log.log("data resolved: "+ JSON.stringify(data))
return data;
}).error(function (err) {
$log.log(err)
return err;
});
return result;
}
}
})
.activeClass{
background:rgb(251,251,251);;
color:rgb(217,52,7);
}
<div class="lists">
<ul list-style-type="none" class="user_Lists">
<li class="item" menu-close ui-sref-active="activeClass"><a ui-sref="home.updates"> <div class="HomeiconImg"></div><span>Home</span> </a></li>
<li class="item" menu-close ui-sref-active="activeClass"><a ui-sref="home.discover"> <div class="DiscovericonImg"></div><span> Discover</span></a></li>
<li class="item" menu-close ui-sref-active="activeClass"><a ui-sref="#">
<div class="ActivityiconImg"></div> <span>My Activity</span></a></li>
<li class="item"menu-close ui-sref-active="activeClass" ><a ui-sref="MyFollowList"> <div class="FollowiconImg"></div><span>My Follow List </span></a></li>
<hr>
<li class="item" menu-close>Invite Friends</li>
<li class="item"menu-close>Mock Search</li>
<li class="item" menu-close>Logout </li>
</ul>
I'm new to this. But while doing R&d got this
Please have a look in this, there is a discussion related to this.
Angular-ui-router: ui-sref-active and nested states
Hopefully it could be helpful to you.
I guess there is already opened issue for this on github Issue that it is not working with abstract and child states.
For alternative solution you can check .
Stackoverflow this question.
It uses a way to comeout from problem
In view:-
ng-class="{activeClass: $state.includes('posts')}"
In controller:-
$scope.$state = $state;
You can check the class dynamically, and add your styles, with the help of hasClass - complete reference
http://docs.angularjs.org/api/angular.element

routeProvider in angularJS not acting right

Within my view I am outputting links. When I go to click a link it triggers the otherwise method in my routeProvider and ends up redirecting back to home. I need it to redirect indiv id and I need to be able to grab project.id from my view within my controller. May I please have some assistance. I'm kind of stuck.
My view:
<div class="container clearfix">
<div class="pagename sixteen columns fadeInUp animated">
<h1 style="font-family: Merriweather">Portfolio</h1>
</div>
</div>
<div class="container clearfix" ng-controller="portfolioController">
<ul style="padding-left: 20pt" class="large-block-grid-4 align-center">
<li class="part" ng-repeat="project in projects">
<a href="#/indiv?id={{ project.id }}">
<img src="{{ project.screenshot_uri }}" alt="">
</a>
<br><br>
<h4>{{ project.project_name }}</h4>
<p>{{ project.description }}</p>
</li>
</ul>
</div><br><br>
My app data:
var app = angular.module("app", ['ngRoute']).config(function($httpProvider, $routeProvider) {
$routeProvider.when('/home', {
templateUrl: 'index.php/projects/projects/home',
controller: 'homeController'
});
$routeProvider.when('/portfolio', {
templateUrl: 'index.php/projects/projects/portfolio',
controller: 'portfolioController'
});
$routeProvider.when('/indiv:id', {
templateUrl: 'index.php/projects/projects/indiv',
controller: 'indiv_controller'
});
$routeProvider.when('/contact', {
templateUrl: 'index.php/projects/projects/contact',
controller: 'contactController'
});
$routeProvider.otherwise({ redirectTo: '/home' });
});
app.factory('pull_projects', function($http) {
return {
get_projects: function(callback) {
$http.get('index.php/projects/pull_projects').success(callback);
}
};
});
app.controller('portfolioController', function($http, $location, $scope, pull_projects) {
pull_projects.get_projects(function(results) {
$scope.projects = results;
});
});
app.controller('contactController', function($http, $location, $scope) {
});
app.controller('indiv_controller', function($http, $location, $scope, $routeParams) {
alert($routeParams.id);
});
app.controller('homeController', function($http, $location, $scope) {
});
Seems the problem is that you are defining the angular routing url and the url in the markup slightly different.
Route:
In the route url you are defining /indiv:id. However, this would match a url where the id was part of the indiv part. So, http://host/indiv123.
So, I would suggest changing this to: /indiv/:id. This will then match urls like this: http://host/indiv/123.
Markup:
In the HTML you are declaring the url as #/indiv?id={{ project.id }}. This will produce the url: /indiv?id=123.
To match our new angular route we need the template to be #/indiv/{{ project.id }} so that we produce a url like /indiv/123.
Hope this helps.
You should use :
ng-href="#/indiv?id={{ project.id }}"
instead of
href="#/indiv?id={{ project.id }}"
This ensures that {{ project.id }} is correctly resolved before it is used as a link.
This occurs because Angular not always gets the chance to intercept the data binding requests before the browser attempts to resolve href and src (<img src="">) attributes. Accordingly, you should use ng-src for images.

Resources