Change nested views through ng-click in ui.router - javascript

I am trying to insert views inside view. But it is working only at the defined state but when I trying to change the view with the help of ngClick the state lost the path.
It is like
View 1
--Sub View 1.1
------Sub Sub View 1.2
But only one sub view will appear that too based on click.
Code is here
.config(function($stateProvider, $urlRouterProvider) {
//$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login',{
url:'/login',
templateUrl: 'partials/login.html'
})
.state('home',{
url:'/home',
views:{
'':{templateUrl:'partials/home.html'},
'grid#home':{templateUrl:'partials/home-grid.html'},
'list#home':{templateUrl:'partials/home-list.html'},
},
controller: 'homeController'
})
})
And my Controller
.controller('homeController', function($rootScope, $scope, $location){
$rootScope.bodyClass = "backround-img1"
$scope.gridClick = function(){
$scope.Tview = 'grid#home'
}
$scope.listClick = function(){
$scope.Tview = 'list#home'
}
}) ;
and in my Main View i have declared the model as below:
<a ng-Click="gridClick()">Grid</a>
<a ng-Click="listClick()">List</a>
----------------------------------------
<div ui-view="{{Tview}}"></div>

Suggesting you with
$state.go('stateName');
You can use something like this in your controller
$scope.changeView=function()
{
$state.go('new');
}
The config should be
$stateProvider
.state("home", {
url: "/",
templateUrl: "newView.html",
controller: "MainCtrl",
})
.state("new", {
url: "/",
templateUrl: "someOtherView.html",
controller: "MainCtrl",
});
Here is the LIVE for your code

Related

UI Router template is not injected but state changes Changes

I am trying to make a nested views, here is the plunker https://embed.plnkr.co/oRMnMW4QoWwhSkm9maHf/. The state changes but the template not changes.
Can anyone correct me what have I done wrong
Goto Link > Second Nested .
On Clicking the button , state changes successfully but the content is not injected. I want the link page content to be replaced by the second-nested content
Try to put abstract:true on the 'father' root like:
var routerApp = angular.module('routerApp', ['ui.router','ncy-angular-breadcrumb']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home/list');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
abstract: true,
templateUrl: './partial-home.html'
})
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: './partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
.state('home.second', {
url: '/second',
templateUrl: './second.html',
});
});
routerApp.run(['$rootScope', '$state', function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function (event, toState) {
console.log("state Change")
});
}]);
but Remember .. if you put abstract: true .. the url is not a real one .. it's a prefix .. or as i call it .. a father of other routing ..so you can not call it in the .otherwise()
And in your link (and routing) of the second view .. just remove the .list ... so like this:
.state('home.second', { //<-- HERE .. REMOVE THE .list
url: '/second',
templateUrl: './second.html',
});
and in the link:
// AND HERE ..
<a ui-sref="home.second" class="btn btn-danger">Second Nested</a>
Answer is pretty simple - you are initializing 3rd level of nesting states but in ./partial-home-list.html you've didn't add ui-view directive.
Add <ui-view></ui-view> in ./partial-home-list.html and you will see that it works as you defined.
If you want to display home.list.second as separate page then define second state like this
.state('home.second', {
url: '/home/list/second',
templateUrl: 'second.html',
});
Remember to update ui-sref to home.second on button
--
Just to get nested breadcrumb I have not "nice" solution but will work.
-- Partial home list html
<div ng-if="state.current.name != 'home.list.second'">
<ul>
<li ng-repeat="dog in dogs">{{ dog }}</li>
</ul>
<div ncy-breadcrumb></div>
<a ui-sref="home.list.second" class="btn btn-danger">Second Nested</a>
</div>
<ui-view></ui-view>
App js
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: 'partial-home-list.html',
controller: function($scope, $state) {
$scope.state = $state;
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
.state('home.list.second', {
url: '/second',
templateUrl: 'second.html',
});

In Angular ui-router, for nested state, corresponding template is not rendering?

I want to show tab(profile+setting), like the following image, but when i click on any tabs, corresponding template is not loading. In customerinfo.view.html I tried to change <div ui-view="{{tab.view}}"></div> to <div ui-view></div> it causing me infinite digest cycle.
I am able to change the url, When first time we hit the url http://localhost:3000/home/#/updatecustomer/3/ following time opens, when click on profile, url change to http://localhost:3000/home/#/updatecustomer/3/profile, but corresponding template(profile.html) is not loading, same is happening for setting
I go through this stackoverflow question, but no help
Module definition
(function() {
'use strict';
var app = angular.module('app', ['ui.router', 'ngCookies', 'ui.bootstrap']);
app.config(function config($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/',
controller: 'HomeController',
templateUrl: 'home/home.view.html',
})
.state('home.updatecustomer', {
url: 'updatecustomer/:customerId/',
controller: 'TabsDemoCtrl',
templateUrl: 'addcustomer/customerinfo.view.html',
})
.state('home.updatecustomer.profile', {
url: 'profile',
controller: 'ProfileCtrl',
templateUrl: 'addcustomer/profile.html',
}))
.state('home.updatecustomer.setting', {
url: 'setting',
controller: 'SettingCtrl',
templateUrl: 'addcustomer/setting.html',
})
customer.js
(function () {
'use strict';
var app = angular.module('app');
app.controller('TabsDemoCtrl', TabsDemoCtrl);
TabsDemoCtrl.$inject = ['$scope', '$state'];
function TabsDemoCtrl($scope, $state){
$scope.customer = 3;
$scope.tabs = [
{ title:'profile', view:'profile', active:true },
{ title:'setting', view:'setting', active:false }
];
}
})();
customerinfo.view.html
<uib-tabset active="active">
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">
<div ui-view="{{tab.view}}"></div>
</uib-tab>
</uib-tabset>
profile.js
(function () {
'use strict';
var app = angular.module('app') ;
app.controller('ProfileCtrl', ProfileCtrl);
ProfileCtrl.$inject = ['$scope'];
function ProfileCtrl($scope){
$scope.profile="Profile 123";
}
})() ;
profile.html
profile
Setting.js
(function () {
'use strict';
var app = angular.module('app') ;
app.controller('SettingCtrl', SettingCtrl);
SettingCtrl.$inject = ['$scope'];
function SettingCtrl($scope){
$scope.setting="setting 1213";
}
})() ;
setting.html
setting
Edit:
1) The first thing-- the naming of your urls. Instead of http://localhost:3000/home/#/updatecustomer/3/ the url should be http://localhost:3000/#/updatecustomer/3/
2) You want the tabs to be children of your home state. Do this by setting abstract: true.
$stateProvider
.state('home', {
abstract: true,
controller: 'HomeController',
templateUrl: 'home/home.view.html'
})
3) The url for your routes must begin with a /.
.state('home.your-splash-view', {
url: '/home',
controller: 'HomeCtrl',
templateUrl: 'home/splash.view.html'
})
.state('home.updatecustomer', {
url: '/updatecustomer/:customerId/',
controller: 'TabsDemoCtrl',
templateUrl: 'addcustomer/customerinfo.view.html'
})
.state('home.updatecustomer.profile', {
url: '/profile',
controller: 'ProfileCtrl',
templateUrl: 'addcustomer/profile.html'
});
4) Consider navigating states with theui-sref directive.
Something like:
<uib-tab ui-sref='home.updatecustomer.profile'> ... </ui-tab>
Related:
what is the purpose of use abstract state?
Why give an "abstract: true" state a url?

Switch between views based on some condition

I am new to angular and ionic, my app information goes like this: I have a splash screen on which I have my login page,followed by home screen.Now the problem is if the user has logged in once,then whenever the app is closed and opened again it shows the login screen,instead it should show home screen. How do I achieve that. I have tried many solutions, but none of them worked. Kindly help.
var kit = angular.module('starter', ['ionic','ionic.service.core', 'ngCordova']);
kit.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('start', {
url: '/',
templateUrl: 'templates/start.html',
controller: 'StartController'
})
.state('home', {
url: '/home',
templateUrl: 'templates/home.html',
controller: 'HomeController'
})
.state('scrollView', {
url: '/scroll',
templateUrl: 'templates/ScrollEx.html',
controller: 'ScrollExController'
})
.state('check', {
url: '/check',
templateUrl: 'templates/check.html',
controller: 'CheckController'
})
$urlRouterProvider.otherwise('/');
});
In your login page's controller, I assume this is StartController, you can use something like:
// Note you need $location for navigation here:
app.controller('StartController', ['$rootScope', '$scope', '$location', /*...*/
function ($rootScope, $scope, $location /*...*/) {
// Test condition, just an example:
if (sessionStorage.user.id) {
$location.path('/home');
}
// Controller code goes here
});
This is assuming you condition is sessionStorage.user.id.
Angular's $location will handle router navigation elegantly for you.
Source: AngularJS: $location

Trying to use nested views in angularjs with ui-router get a blank page

My setup
app/learning/learning.js
angular.module('meanApp')
.config(function($stateProvider) {
$stateProvider
.state('learning',{
templateUrl: 'app/learning/learning.html',
url: '/learning',
controller: 'LearnCtrl',
views: {
'list': {
templateUrl: 'app/learning/learning.list.html',
controller: function($scope){ }
},
'magic': {
templateUrl: 'app/learning/learning.magic.html',
controller: function($scope){ }
}
}
});
});
app/learning/learning.html
<h1>Learning</h1>
<div ui-view="list"></div>
<div ui-view="magic"></div>
app/learning/learning.list.html
<p>A list</p>
app/learning/learning.magic.html
<h2>Magic</h2>
when I navigate to /learning I get a blank page, I'm not sure what I'm doing wrong so any help would be greatly appreciated.
You shouldn't load the base template inside state when there are nested ui-view,
Define the base template inside views.
Route Code
angular.module('meanApp')
.config(function($stateProvider) {
$stateProvider
.state('learning',{
url: '/learning',
views: {
'': {
templateUrl: 'app/learning/learning.html',
controller: 'LearnCtrl'
},
'list#learning': { //you missed state name here
templateUrl: 'app/learning/learning.list.html',
controller: function($scope){ }
},
'magic#learning': { //you missed state name here
templateUrl: 'app/learning/learning.magic.html',
controller: function($scope){ }
}
}
});
});
This could Help you, Thanks.
The problem was that I was trying to load the base template inside state and I missed out the state name as Pankaj said, so the solution is...
angular.module('meanApp')
.config(function($stateProvider) {
$stateProvider
.state('learning',{
url: '/learning',
views: {
'': {
templateUrl: 'app/learning/learning.html',
controller: 'LearnCtrl'
},
'list#learning': { //you missed state name here
templateUrl: 'app/learning/learning.list.html',
controller: function($scope){ }
},
'magic#learning': { //you missed state name here
templateUrl: 'app/learning/learning.magic.html',
controller: function($scope){ }
}
}
});
});

opening a modal in a route in AngularJS with angular-ui-bootstrap

I am trying to do what was essentially answered here Unable to open bootstrap modal window as a route
Yet my solution just will not work. I get an error
Error: [$injector:unpr] Unknown provider: $modalProvider <- $modal
My app has the ui.bootstrap module injected - here is my application config
var app = angular.module('app', ['ui.router', 'ui.bootstrap','ui.bootstrap.tpls', 'app.filters', 'app.services', 'app.directives', 'app.controllers'])
// Gets executed during the provider registrations and configuration phase. Only providers and constants can be
// injected here. This is to prevent accidental instantiation of services before they have been fully configured.
.config(['$stateProvider', '$locationProvider', function ($stateProvider, $locationProvider) {
// UI States, URL Routing & Mapping. For more info see: https://github.com/angular-ui/ui-router
// ------------------------------------------------------------------------------------------------------------
$stateProvider
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
.state('transactions', {
url: '/transactions',
templateUrl: '/views/transactions',
controller: 'TransactionsCtrl'
})
.state('login', {
url: "/login",
templateUrl: '/views/login',
controller: 'LoginCtrl'
})
.state('otherwise', {
url: '*path',
templateUrl: '/views/404',
controller: 'Error404Ctrl'
});
$locationProvider.html5Mode(true);
}])
I have reduced my controller to the following:
appControllers.controller('LoginCtrl', ['$scope', '$modal', function($scope, $modal) {
$modal.open({templateUrl:'modal.html'});
}]);
Ultimately, what I am hoping to achieve is when login is required not actually GO to the login page, but bring up a dialog.
I have also tried using the onEnter function in the ui-router state method. Couldn't get this working either.
Any ideas?
UPDATE
Ok - so as it turns out, having both ui-bootstrap.js AND ui-bootstrap-tpls breaks this - After reading the docs I thought you needed the templates to work WITH the ui-bootstrap. though it seems all the plunkers only load in the ..tpls file - once I removed the ui-bootstrap file my modal works...Am i blind? or doesn't it not really say which one you need in the docs on github? -
Now i just need to figure out how to prevent my url from actually going to /login, rather than just show the modal :)
update 2
Ok, so by calling $state.go('login') in a service does this for me.
Hi I had a hard time getting through the similar problem.
However, I was able to resolve it.
This is what you would probably need.
app.config(function($stateProvider) {
$stateProvider.state("managerState", {
url: "/ManagerRecord",
controller: "myController",
templateUrl: 'index.html'
})
.state("employeeState", {
url: "empRecords",
parent: "managerState",
params: {
empId: 0
},
onEnter: [
"$modal",
function($modal) {
$modal.open({
controller: "EmpDetailsController",
controllerAs: "empDetails",
templateUrl: 'empDetails.html',
size: 'sm'
}).result.finally(function() {
$stateProvider.go('^');
});
}
]
});
});
Click here for plunker. Hope it helps.
I'm working on something similar and this is my solution.
HTML code
<a ui-sref="home.modal({path: 'login'})" class="btn btn-default" ng-click="openModal()">Login</a>
State configuration
$stateProvider
// assuming we want to open the modal on home page
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
// create a nested state
.state('home.modal', {
url: ':path/'
});
Home controller
//... other code
$scope.openModal = function(){
$modal.open({
templateUrl: 'path/to/page.html',
resolve: {
newPath: function(){
return 'home'
},
oldPath: function(){
return 'home.modal'
}
},
controller: 'ModalInstanceController'
});
};
//... other code
Finally, the modal instance controller.
This controller synchronizes the modal events (open/close) with URL path changes.
angular.module("app").controller('ModalInstanceController', function($scope, $modalInstance, $state, newPath, oldPath) {
$modalInstance.opened.then(function(){
$state.go(newPath);
});
$modalInstance.result.then(null,function(){
$state.go(oldPath);
});
$scope.$on('$stateChangeSuccess', function () {
if($state.current.name != newPath){
$modalInstance.dismiss('cancel')
}
});
});
You may create a state with the same templateUrl and controller as your page where you want to show the modal, adding params object to it
$stateProvider
.state('root.start-page', {
url: '/',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl'
})
.state('root.login', {
url: '/login',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl',
params: {
openLoginModal: true
}
})
And in controller of the page, use this parameter to open the modal
.controller("StartPageCtrl", function($scope, $stateParams) {
if ($stateParams.openLoginModal) {
$scope.openLoginModal();
}
I found a handy hint to get this working. There are probably caveats, but it works for me. You can pass a result still but I have no need for one.
Using finally instead of the then promise resolve sorted this for me. I also had to store the previous state on rootScope so we knew what to go back to.
Save previous state to $rootScope
$rootScope.previousState = 'home';
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams){
$rootScope.previousState = from.name;
})
State using onEnter
$stateProvider.state('contact', {
url: '/contact',
onEnter: function ($state, $modal, $rootScope){
$modal.open({
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
}).result.finally(function(){
$state.go($rootScope.previousState);
})
}
});

Categories

Resources