AngularJS not passing ID to UI-View - javascript

What I'm trying to do is create a ui-view for each request in requests.
When the app state = request.detail I'd like to render the "detail" into a UI-view with the id set as the request.id. I cannot figure out how to pass the request.id through angular and name the ui-view which the state renders in dynamically.
For Example if the request.id = 1 I'd like the ui-view to be ui-view="1";
if the request.id=23 , i'd like it's ui-view to be ui-view="23".
Request.js
app.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', { url: '', views: { 'main': { templateUrl: 'static_pages/home.html'}}})
.state('requests', { url: '/requests', views: {'main': { templateUrl: 'requests.html', controller: 'RequestsCtrl'}}})
.state('requests.detail', { url: '/:id', views: {':id': { templateUrl: function($stateParams) {return `/requests/${$stateParams.id}`;}, controller: 'RequestController'}}})
.state('requests.detail.pdf', { url: '.pdf', views: { 'requestpdf': { templateUrl: function($stateParams) {return `/requests/${$stateParams.id}.pdf`;}, controller: 'RequestController'}}})
.state('requests.detail.edit', { url: '/edit', views: {'main2': { templateUrl: function($stateParams) {return `/requests/${$stateParams.id}/edit`;}, controller: 'RequestController'}}})
.state('users', { url: '/users', templateUrl: 'users.html', controller: 'UsersCtrl'})
.state('/users/:id', { url: 'users_show.html', controller: 'UsersCtrl' });
$locationProvider.html5Mode({ enabled: true, requireBase: false });
});
app.controller("RequestsCtrl", ['$scope', '$state', '$stateParams', 'Request', '$location', function($scope, $stateParams, $state, Request, $location ) {
$scope.requests = Request.query();
$scope.request = Request.query();
$scope.deleteRequest = function (request) {
Request.delete({id: request.id})
console.log("deleted" + request.id);
}
}]);
app.controller("RequestController", ['Request', '$scope', '$stateParams', RequestController]);
function RequestController( $scope, $stateParams, Request ) {
$scope.currentRequestId = $stateParams.request.id;
};
Index.html
<div id='requests' class="requests col-xs-5 col-md-5" ng-controller="RequestsCtrl" >
<div ng-repeat="request in requests" class="request">
<div id="full" ui-view="{{request.id}}"></div>
<a ng-click="showRequest(request);">
<span ng-if="request.read == false"> *NEW*</span>
<span class="col-xs-12">Request #{{request.id}}</span><br>
<span class="col-xs-1">{{request.name}}</span>
<span class="col-xs-1">{{request.email}}</span>
<span class="col-xs-4 col-xs-offset-4">{{request.city}}, {{request.state}}, {{request.region}} </span>
</a>
<div>
<div ng-controller="RequestController">
<a ui-sref="requests.detail({id: request.id})" ng-click="showfullreqest()" ng-init="fullrequest = false">View</a>
<a ng-click="deleteRequest(request)" style="float:left;"> Delete </a>
</div>
</div>
</div>
</div>

Related

Implementing a navbar nested view in angular ui router

Am new to the angular js.
Am implementing a nested ui view but the problem is when checking the current state of a page it returns many objects such that i cant use $state.current to set the ng-show
I would like the navbar shown and hidden in some states.
I have tried
The main index.html page
<html>......
<body ng-app="myapp">
<nav ng-controller="headerCtrl" ng-show="shownav()" >
//here is the navbar code..The shownav is defined on the headerCtrl
</nav>
<div ui-view> </div>
//Angular js, controllers and services links
</body>
</html>
The app.js code
var app = angular.module('myApp', ['ui.router']);
app.controller('headerCtrl',function($scope, $state) {
$scope.shownavbar = function(){
var state = $state.current;
if(state ==='login' ){
return false;
}else{
return true;
}
}
app.config(function($stateProvider, $urlRouterProvider, $httpProvider){
$stateProvider
.state('login', {
url:'/login',
templateUrl: 'templates/index/login/login.html',
controller: 'loginCtrl'
})
.state('dash', {
url: '/dash',
templateUrl:'templates/layout/dashboard.html',
abstract:true
})
.state('dash.call',{
url: '/call',
templateUrl: 'templates/index/calls/calls.html',
controller: 'callCtrl'
})
.state('dash.profile', {
url: '/profile',
templateUrl: 'templates/index/account/profile/profile.html',
controller: 'profileCtrl'
})
});
I would like the navbar hidden for some states like when a user is on the login state
At the headerctrl i have also tried
$scope.shownavbar = function(){
var state = $state.current;
$log.info(state);
}
This returns in the console:
angular.js:13708 Object {name: "", url: "^", views: null, abstract: true}
angular.js:13708 Object {name: "", url: "^", views: null, abstract: true}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
WHAT COULD BE THE PROBLEM
I can think in two ways to solve this.
First solution
EDITED
inside your run() put a function to see when the state is changing and hide or show the navbar.
myApp.run(function ($rootScope, $state) {
$rootScope.navbar = false;
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if (toState.name === 'login') {//toState variable see the state you're going
$rootScope.navbar = false;
} else {
$rootScope.navbar = true;
}
});
});
and change in your ng-show="navbar"
Second solution
the second solution i can think is you use multiple views.
$stateProvider
.state('login', {
url: '/',
views: {
'navbar': {
templateUrl: null,
controller: null
},
'body': {
templateUrl: "views/login.html",
controller: 'LoginController'
}
}
})
.state('home', {
url: '/home',
views: {
'navbar': {
templateUrl: "views/navbar.html",
controller: null
},
'body': {
templateUrl: "views/inicio.html",
controller: null
}
}
});
and in your html views put something similar to this:
<div ui-view="navbar"></div>
<div ui-view="body"></div>

How to properly display header/footer using angularjs and ui-router?

This is my index.html:
<body>
<div ui-view></div>
</body>
This is my app.js:
angular.module('sample', [
'auth0',
'ngRoute',
'sample.home',
'sample.header',
'sample.login',
'ui.router',
'angular-storage',
'angular-jwt'
])
.config(function myAppConfig($stateProvider, $urlRouterProvider, $routeProvider, authProvider, $httpProvider, $locationProvider,
jwtInterceptorProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'login/login.html',
controller: 'LoginCtrl'
}).state('root', {
url: '/',
abstract: true,
views: {
'header': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}
}).state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'home/home.html'
}
},
data: {
requiresLogin: true
}
})
$urlRouterProvider.otherwise('/');
authProvider.init({
domain: AUTH0_DOMAIN,
clientID: AUTH0_CLIENT_ID,
loginUrl: '/login'
});
jwtInterceptorProvider.tokenGetter = function(store) {
return store.get('token');
}
$httpProvider.interceptors.push('jwtInterceptor');
})
.run(function($rootScope, auth, store, jwtHelper, $location, $state, $stateParams) {
$rootScope.$on('$locationChangeStart', function() {
if (!auth.isAuthenticated) {
var token = store.get('token');
if (token) {
if (!jwtHelper.isTokenExpired(token)) {
auth.authenticate(store.get('profile'), token);
} else {
$location.path('/login');
}
}
}
});
})
.controller('AppCtrl', function AppCtrl($scope, $location) {
$scope.$on('$routeChangeSuccess', function(e, nextRoute) {
if (nextRoute.$$route && angular.isDefined(nextRoute.$$route.pageTitle)) {
$scope.pageTitle = nextRoute.$$route.pageTitle + ' | Auth0 Sample';
}
});
})
If I do login & the root that's commented out, everything works fine. But I need to put in a header and footer (the files are correct) and when I try the root + root.home, I get a blank screen with no errors on the browser's console either.
I'm trying to go off of a few examples from online (such as this one) but none are working out so I don't know what I'm doing wrong.
Right now my header/footer.html just say header/footer.html while home has a button on it.
Added the full app.js in case that helps. Each html (footer/header/home) just has
<h1>Home</h1>
<div ui-view></div>
Edit: index.html
<body>
<div ui-view="header"></div>
<div ui-view></div>
<div ui-view="footer"></div>
</body>
app.js
.state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
}
},
data: {
requiresLogin: true
}
})
I believe your issue here is your route is looking for a view named container not a class.
<div ui-view="container"></div>
Since it can't find a view named that it does not insert anything in the view.
Or you can just change your view route to be:
views: {
'#': {
templateUrl: 'home/home.html'
}
Which will tell it to insert that HTML in the first unnamed view it finds.
You can find a break down of how nested views work with UI-Router here
Assuming your home.html looks like this:
<div ui-view="header"></div>
<div ui-view="footer"></div>
your route should be something like
views: {
'header#home': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer#home': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}

Tab with different controllers

In my angular.js app I have a profile view with various tabs, each one a nested view with it's own controller. What I want to do is to be able to click back and forth different tabs but always remaining in the profile view.
But every time I click on one of the tabs, e.g "nested_view_1" with url "/nested_view_1" and templateUrl: "nested_view_1.html", it changes the path to "/nested_view_1" and renders a blank page (because I didn't specified a "/nested_view_1" in my $routeProvider). Only when I click back, it shows my selected tab content inside my view
May be a problem that I'm using ui.router and ng-route at the same time.
here is my app.js file:
var app = angular.module('app', ['ngRoute', 'ui.router','ui.bootstrap','ui.bootstrap.tpls'])
app.config(['$routeProvider', '$stateProvider' ,function ($routeProvider, $stateProvider) {
$routeProvider
.when('/', {
templateUrl: '/app/views/home.html',
controller: 'HomepageCtrl'
})
.when('/articles', {
templateUrl: 'app/views/articles/index.html',
controller: 'ArticlesCtrl'
})
.when('/articles/:id', {
templateUrl: 'app/views/articles/show.html',
controller: 'ShowArticleCtrl'
})
... other routes ...
$stateProvider
.state('profile', {
abstract: true,
url: '/profile',
templateUrl: "app/views/users/profile.html",
controller: 'UserShowCtrl'
})
.state('nested_view_1', {
url: '/nested_view_1',
views: {
"tabContent": {
templateUrl: 'app/views/users/sales.html',
controller: 'UserSalesAreaCtrl'
}
}
})
.state('nested_view_2', {
url: "/nested_view_2",
views: {
"tabContent": {
templateUrl: 'app/views/users/buys.html',
controller: 'UserAreaCtrl'
}
}
})
.... all the way to nested view 4, in my case
}])
my view:
<ul class="nav nav-tabs mt-50" >
<li ng-repeat="t in tabs" class="nav-item" heading="{{t.heading}}" active="t.active">
<a ui-sref="{{t.route}}" style="font-weight: 200;" class="nav-link" ng-class="{'active'}" >
{{ t.heading }}
</a>
</li>
<div ui-view="tabContent"></div>
</ul>
my UserShowCtrl
angular.module('app').controller('UserShowCtrl', ['$scope', 'user', '$routeParams', '$location', '$state',
function ($scope, user, $routeParams, $location, $state) {
$scope.tabs = [
{ heading: 'nested_view_1', route:'nested_view_1', active:true },
{ heading: 'nested_view_2', route:'nested_view_2', active:false },
{ heading: 'nested_view_3', route:'nested_view_3', active:false },
{ heading: 'nested_view_4', route:'nested_view_4', active:false }
];
}]);
Prefix your nested routes with the parent route parent.
$stateProvider
.state('profile', {
abstract: true,
url: '/profile',
templateUrl: "app/views/users/profile.html",
controller: 'UserShowCtrl'
})
.state('profile.nested_view_1', {
url: '/nested_view_1',
views: {
"tabContent": {
templateUrl: 'app/views/users/sales.html',
controller: 'UserSalesAreaCtrl'
}
}
})
.state('profile.nested_view_2', {
url: "/nested_view_2",
views: {
"tabContent": {
templateUrl: 'app/views/users/buys.html',
controller: 'UserAreaCtrl'
}
}
})

UI-Router $stateParams With Master Detail Pattern

I need a Master Detais pattern for my web site. In index lots of thumbnails and every thumbnail link to their detailed page. I make a progress but does not get to work. Its load thumbnails on index oage but when I click to thumbnails its load blank page.
Index:
<body ui-view="viewA">
<div class="row" ui-view="viewB">
<div class="col s12 m6 l4" ng-repeat = "manga in mangas">
<div class="row">
<div class="col s5">
<a ui-sref="icerikDetails({id:manga.id})" class="thumbnail">
<img src="/kapaklar/{{manga.kapak}}">
</a>
JS:
angular.module('nasuh',["ui.router"])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('index', {
url: "/",
views: {
"viewA": { templateUrl: "index.html",
controller: "indexCtrl",}
}})
$stateProvider
.state('icerik', {
url: "/icerik",
views: {
"viewB": { templateUrl: "icerik.html",
controller: "mmgCtrl",},
}})
$stateProvider
.state('icerikDetails', {
url: "/icerik/:id",
template: "<div>{{details }}</div>",
controller: "mmgCtrl",
resolve: {
getData : function(MY, $stateParams, $filter){
return MY.isimler.then(function(res){
return $filter('filter')(res.data, {id: $stateParams.id}, true)[0];
});}
}
})
$urlRouterProvider.otherwise("/");
})
factory and controllers:
.factory('MY', function($http){
var factory = {};
var url = '/uzak/remote.php?callback=JSON_CALLBACK';
factory.isimler = $http.get(url);
return factory;
})
.controller('indexCtrl', function($scope, MY) {
MY.isimler.success(function(alHemen){
$scope.mangas = alHemen;
});
})
.controller('mmgCtrl', function($scope, getData) {
$scope.manga = getData.then(function(data){
$scope.details = data;
});})
I am not sure what you are trying to achieve, but at least I tried to convert your snippets into something working.
There is a working example
To get more understanding, do read these:
Nested States and Nested Views
Multiple Named Views
These are states, with a hiererchy. Index is super root, and details is super child:
$stateProvider
.state('index', {
url: "/",
views: {
"": {
templateUrl: "index.tpl.html",
controller: "indexCtrl",
}
}
})
.state('icerik', {
parent: "index",
url: "^/icerik",
views: {
"viewA": {
templateUrl: "icerik.html",
controller: "indexCtrl",
},
}
})
.state('icerik.icerikDetails', {
url: "/icerik/:id",
template: "<div>{{manga}}</div>",
controller: "mmgCtrl",
resolve: {
getData: function(MY, $stateParams, $filter) {
return MY.isimler.then(function(res) {
return $filter('filter')(res.data, {
id: $stateParams.id
}, true)[0];
});
}
}
})
$urlRouterProvider.otherwise("/");
These will be new controllers and factory:
.factory('MY', function($http) {
var factory = {};
//var url = '/uzak/remote.php?callback=JSON_CALLBACK';
var url = 'data.json';
factory.isimler = $http.get(url);
return factory;
})
.controller('indexCtrl', function($scope, MY) {
MY.isimler.success(function(alHemen) {
$scope.mangas = alHemen;
});
})
.controller('mmgCtrl', function($scope, getData) {
//$scope.manga = getData.then(function(data){
// $scope.details = data;
// });
$scope.manga = getData;
})
And an example of templates "index.tpl.html":
<div >
<h2> this is index view</h2>
icerik
<div ui-view="viewA"></div>
</div>
and "icerik.html":
<div class="row" >
<div class="col s12 m6 l4" ng-repeat="manga in mangas">
<div class="row">
<div class="col s5">
<a ui-sref="icerik.icerikDetails({id:manga.id})" class="thumbnail">
img src="/kapaklar/{{manga.kapak}}"
</a>
</div>
</div>
</div>
<hr>
<div ui-view=""></div>
</div>
Check it here

How do I load UI-router ui-view templates that are nested 3 states deep?

I am attempting to design the routing and nested views in my app several levels deep in order to replace parts of the app based on a route. I'm able to load the login page, and it seems the layout view loads as well, however, I can't seem to get the nested <ui-view /> tags to work. Can someone please tell me how I'm doing this wrong, or if there is a more idiomatic way in Angular to accomplish the same functionality.
app.js
(function() {
'use strict';
angular
.module('webApp', [
'ui.router',
])
.config(config)
.run(run);
config.$inject = ['$stateProvider', '$urlRouterProvider'];
function config($stateProvider, $urlRouterProvider, ngClipProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('app', {
abstract: true,
url: '/',
template: '<ui-view/>'
})
.state('app.login', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl as login',
url: ''
})
.state('app.main', {
url: 'room',
templateUrl: 'views/layout.html'
})
.state('app.main.foo', {
url: '',
views: {
'header#app.main': {
templateUrl: 'partials/header.html',
controller: 'HeaderCtrl as header'
},
'sidebar#app.main': {
templateUrl: 'partials/sidebar.html',
controller: 'SidebarCtrl as sidebar'
},
'main#app.main': {
templateUrl: 'partials/main.html',
controller: 'MainCtrl as main'
},
'subHeader': {
templateUrl: '<div><div ui-view="bottomHeader"></div></div>',
controller: 'SubHeaderCtrl',
controllerAs: 'subHeader'
},
'subSidebar': {
templateUrl: '<div><div ui-view="bottomSidebar"></div></div>',
controller: 'SubSidebarCtrl',
controllerAs: 'subSidebar'
},
'bottomHeader': {templateUrl: '<div>FOO</div>'},
'bottomSidebar': {templateUrl: '<div>BAR</div>'}
},
resolve: {
isAuthenticated: ['Auth', function(Auth) {
return Auth.isAuthenticated();
}]
}
})
.state('app.main.foo.bar', {
url: '/:id',
views: {
'main#': {
templateUrl: 'partials/main.html'
},
'mainOne#': {
templateUrl: 'partials/main-one.html',
controller: 'MainOneCtrl as mainOne'
},
'mainTwo#': {
templateUrl: 'partials/main-two.html',
controller: 'MainTwoCtrl as mainTwo'
},
'mainThreee#': {
templateUrl: 'partials/main-three.html',
controller: 'MainThreeCtrl as mainThree'
}
}
});
}
run.$inject = ['Auth'];
function run(Auth) {
Auth.stateChangeError();
Auth.loginSuccess();
Auth.loginFailure();
Auth.checkSession();
}
}());
index.html
<!DOCTYPE html>
<html lang="en" ng-app="webApp">
<head>
<title>FooBar</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/main.css" />
<script src="/js/all.js"></script>
</head>
<body ui-view>
</body>
</html>
layout.html
<div ui-view="header"></div>
<div class="app">
<div class="getting-started">
</div>
<div ui-view="sidebar"></div>
<div ui-view="main"></div>
</div>
header.html
<header class="header">
<div ui-view="subHeader"></div>
<div class="trigger-button">
<button class="trigger">
<i class="icon-account"></i>
</button>
</div>
</header>
main.html
<div>
<div ui-view="mainOne"></div>
<div ui-view="mainTwo"></div>
<div ui-view="mainThree"></div>
</div>
sidebar.html
<div>
<div ui-view="subSidebar"></div>
</div>
There is a working plunker, showing your scenario
I've made few changes in your state definition:
$stateProvider
.state('app', {
abstract: true,
url: '/',
template: '<ui-view/>'
})
.state('app.login', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl',
controllerAs: 'login',
url: ''
})
We are using controller and controllerAs syntax
.state('app.main', {
url: 'room',
templateUrl: 'views/layout.html'
})
No absulte naming, we target our parent, relative is enough, more readable
.state('app.main.foo', {
url: '',
views: {
'header': {
templateUrl: 'partials/header.html',
controller: 'HeaderCtrl',
controllerAs: 'header',
},
'sidebar': {
templateUrl: 'partials/sidebar.html',
controller: 'SidebarCtrl',
controllerAs: 'sidebar',
},
'main': {
templateUrl: 'partials/main.html',
controller: 'MainCtrl',
controllerAs: 'main',
}
},
resolve: {
isAuthenticated: ['Auth', function(Auth) {
return Auth.isAuthenticated();
}]
}
})
main state is in our parent, do not redefine it
.state('app.main.foo.bar', {
url: '/:id',
views: {
'mainOne': {
templateUrl: 'partials/main-one.html',
controller: 'MainOneCtrl',
controllerAs: 'mainOne',
},
'mainTwo': {
templateUrl: 'partials/main-two.html',
controller: 'MainTwoCtrl',
controllerAs: 'mainTwo',
},
'mainThreee': {
templateUrl: 'partials/main-three.html',
controller: 'MainThreeCtrl',
controllerAs: 'mainThree',
}
}
});
Check it here

Categories

Resources