AngularJS routing multiple ui-views for the same URL? - javascript

I need multiple ui-views for one URL (my homepage). The limitation for ui-routing is that I can't have multiple <div ui-view></div> but they have to be in their nested states.
<div class="left-div">
<div ui-view></div>
<button ui-sref="1"></button>
<button ui-sref="2"></button>
<button ui-sref="3"></button>
</div>
<div class="right-div">
<button ui-sref="3"></button>
<div ui-view></div>
</div>
How do I make it so that ui-sref=1 and ui-sref=2 will update the ui-view inside:
<div class="left-div"></div>
and ui-sref=3 will update the ui-view inside <div class="right-div"></div>
The issue I encountered when I used ui-router was that upon changes from ui-sref from 1 -> 3 or 2 -> 3 the ui-view of left-div will disappear because the URL changes.
How do I approach this?
EDIT- My current state views
chatApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home')
$stateProvider
.state('friend', {
url: '/friend',
templateUrl: 'friend.html'
})
.state('group', {
url: '/group',
templateUrl: 'group.html'
})
.state('search', {
url: '/search',
templateUrl: 'search.html'
})
.state('home', {
url: '/search',
templateUrl: 'search.html'
})
.state('public', {
url: '/public',
views: {
'publicView': { templateUrl: 'private-chat.html' }
}
});
<div class="col-md-3 left-col-friends" ng-controller="friendListCtrl">
<div class="friends-list-navigation">
<div class="option-wrapper">
<div class="col-xs-3 home-option" ui-sref="public"><i class="fa fa-home fa-2x"></i></div>
<div class="col-xs-3 friend-option" ui-sref="friend"><i class="fa fa-user fa-2x"></i></div>
<div class="col-xs-3 group-option" ui-sref="group"><i class="fa fa-users fa-2x"></i></div>
<div class="col-xs-3 search-option" ui-sref="search"><i class="fa fa-search fa-2x"></i></div>
</div>
</div>
<div class="friends-list-display">
<div ui-view></div>
</div>
</div>
<div class="col-md-9 middle-col-chat" ng-controller="publicCtrl">
<div class="bubble-frame-public">
<div ui-view="publicView"></div>
</div>
<div class="input-fields-wrapper" emoji-form emoji-message="emojiMessage">
<div class="col-md-8">
<textarea class="col-md-4" id="messageInput" ng-model="emojiMessage.messagetext"></textarea>
</div>
<div class="col-md-3">
<button class="btn btn-default btn-send-public-msg" ng-click="emojiMessage.replyToUser()"><i class="fa fa-paper-plane"></i></button>
<button class="btn btn-default" id="emojibtn">
<i class="fa fa-smile-o"></i>
</button>
<button class="btn btn-default"><i class="fa fa-video-camera"></i></button>
</div>
</div>
</div>

I'm taking a guess that the publicView is the view you're wanting to stay unchanged while the other views are changing. Here's one way to tackle it.
$stateProvider
.state('home', {
url: '/home',
views: {
'#': {
templateUrl: 'search.html'
},
'publicView#': {
templateUrl: 'private-chat.html'
}
}
})
.state('home.friend', {
views: {
'#': {
templateUrl: 'friend.html'
}
}
})
.state('home.group', {
views: {
'#': {
templateUrl: 'group.html'
}
}
});
The default URL is /home. When it's accessed, publicView is populated with private-chat.html and the unnamed ui-view is populated with search.html.
For the friend and group states, they leave the publicView alone and they don't use new URLs, which is what I think you're going for. This is accomplished by making them children states of home and by specificying absolutely which views should be altered.

Related

Use nested states as tabs in ui-router

The documentation seems a little sparse on this particular case, however I'm working off of the "Multiple Views About Page" section of this tutorial, which is supported by this SO post.
I'm trying to convert one of my pages to a parent state that renders each tab as child states. The syntax below doesn't throw an error, however only the tab headers are rendering, none of the content. I've set breakpoints in the init functions in the child controllers and nothing fires, and I'm not getting any errors back in the console. I've also created a breakpoint in the $stateChangeError callback and am getting nothing in there as well.
parent state
<div class="container">
<h2> <i class="fa fa-user"></i> Click to Call Settings for {{user.fullName}}</h2>
<uib-tabset active="active" id="usersettings">
<uib-tab index="0" heading="SIP Settings">
<div ui-view="sipSettings"></div>
</uib-tab>
<uib-tab index="1" heading="Favorites">
<div ui-view="favorites"></div>
</uib-tab>
</uib-tabset>
</div>>
favoritesPartial.html (edited for the sake of space)
<form name="favoritesForm">
<div ng-repeat="favorite in pbxFavorites" id="favoritesContainer">
</div>
</form>
<div class="form-footer">
<button type="button" class="btn btn-white" ng-click="$root.goBack()">Go Back</button>
<button type="submit" class="btn btn-primary" ng-click="saveFavorites()">Save Favorites</button>
</div>
sipSettingsPartial.html (edited for the sake of space)
<form name="sipSettingsForm">
<div class="row">
<div class="form-footer">
<button type="button" class="btn btn-white" ng-click="$root.goBack()">Go Back</button>
<button type="submit" class="btn btn-primary" ng-click="savePbxSettings()">Save Settings</button>
</div>
</form>
state provider
.state('clickToCall', {
url: '/clickToCall',
templateUrl: 'app/components/clickToCall/clickToCall.html',
controller: 'ClickToCallController',
controllerAs: 'vm',
parent: 'app',
authenticate: true,
resolvePolicy: {when:'LAZY', async: 'WAIT'},
resolve:{
security:['$q', '$rootScope', 'parentResolves', 'routeErrors', function($q, $rootScope, parentResolves, routeErrors){
if($rootScope.isLoggedIn()){
return $q.resolve();
} else {
return $q.reject(routeErrors.NO_ACCESS);
}
}]
},
params:{
'user':''
},
view:{
'sipSettings#clickToCall': {
templateUrl: 'app/components/clickToCall/sipSettingsPartial.html',
controller: 'SipSettingsController'
},
'favorites#clickToCall':{
templateUrl: 'app/components/clickToCall/favoritesPartial.html',
controller: 'FavoritesController'
}
}
})
folder structure
screen shot
Stupid typo...... named the section view instead of views, also left the templateUrl in the parent state. The following config works:
.state('clickToCall', {
url: '/clickToCall',
controller: 'ClickToCallController',
controllerAs: 'vm',
parent: 'app',
authenticate: true,
resolvePolicy: {when:'LAZY', async: 'WAIT'},
resolve:{
security:['$q', '$rootScope', 'parentResolves', 'routeErrors', function($q, $rootScope, parentResolves, routeErrors){
if($rootScope.isFirmAdmin2 || $rootScope.isCloud9){
return $q.resolve();
} else {
return $q.reject(routeErrors.NO_ACCESS);
}
}]
},
params:{
'user':''
},
views:{
'':{
templateUrl: 'app/components/clickToCall/clickToCall.html'
},
'sipSettings#clickToCall': {
templateUrl: 'app/components/clickToCall/sipSettingsPartial.html',
controller: 'SipSettingsController'
},
'favorites#clickToCall':{
templateUrl: 'app/components/clickToCall/favoritesPartial.html',
controller: 'FavoritesController'
}
}
})

Angular ui.router Reload Template

First of all, I'm sorry for a long question, but it just has to be like that. Unfortunately...
I have a couple of templates and a couple of routing logic, all linked in separate files. For some reason the template I want to load (which depends on the region selected), doesn't load its region template. It loads, if I click it second time. Please note I have tried ever solution from this topic:
Reloading current state - refresh data
Nothing worked for me.
I have managed to resolve one (another region) of them by placing "{reload:true}" inline in the html code, like this:
<a data-ui-sref="uk-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
Now I did the same for another template and it is not working. This is my html:
<div class="btn us-btn" data-ng-controller="carCtrlUs">
<script type="text/ng-template" id="careersTplUs.html">
<div class="closer">
<span class="close-me" data-ng-click="ok()">X</span>
</div>
<uib-accordion close-others="true">
<div uib-accordion-group class="modal-body modone panel-default pull-right" is-open="false">
<uib-accordion-heading>
<p class="car-heading">Sales Department <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</p>
</uib-accordion-heading>
<ul>
<li><a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a></li>
<li><a data-ui-sref="us-crm" data-ui-sref-opts="{reload:true}">Client Relationship Manager</a></li>
</ul>
</div>
<div class="modal-body modtwo panel-default pull-right" uib-accordion-group is-open="false">
<uib-accordion-heading>
<p class="car-heading">Marketing Department <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</p>
</uib-accordion-heading>
<ul>
<li><a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Web Developer</a></li>
<li><a data-ui-sref="us-crm" data-ui-sref-opts="{reload:true}">Marketing Coordinator</a></li>
</ul>
</div>
</uib-accordion>
<div class="show-me" ui-view></div>
</script>
<button class="btn" ng-click="open()" data-ui-sref="us-intro">United States</button>
</div>
app.js:
var app = angular.module('carApp', ['ngAnimate', 'ngSanitize', 'ui.bootstrap', 'ui.router']);
controller, for this template:
app.controller('carCtrlUs', function($scope, $http, $uibModal) {
$http.get('json/jobs-us.json').then(function(response) {
$scope.placeholder = response.data.default;
$scope.specs = response.data.specs;
$scope.open = function() {
var modalContent = $uibModal.open({
templateUrl: 'careersTplUs.html',
controller : 'modalContentCtrlUs',
controllerAs: '$ctrl',
size: 'lg',
backdropClass: 'backdropOver',
openedClass: 'modal-opened',
resolve: {
items: function() { return $scope.specs; },
items2: function() { return $scope.placeholder;}
}
})
console.log($scope.placeholder);
console.log($scope.specs);
console.log($scope.specs.web-dev);
}
});
});
app.controller('modalContentCtrlUs', function($scope, $uibModalInstance, items, items2) {
$scope.specs = items;
$scope.placeholder = items2;
$scope.ok = function() {
$uibModalInstance.close();
}
});
factory.js:
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state("us-intro", {
url:"/intro",
templateUrl: "templates/us/start.html"
})
$stateProvider
.state("us-web", {
url: "/web-developer/",
templateUrl: "templates/us/web-developer.html",
})
.state("us-crm", {
url: "/crm/",
templateUrl: "templates/us/crm.html"
})
/*next .state*/
}]);
Template:
<div ng-repeat="(k, v) in specs.webdev">
<h3>{{::v["job-title"]}}</h3>
<p>{{::v["job-body"]}}</p>
United States Apply Here:
<p>{{::v["job-apply"]}}</p>
</div>
As you can see I'm using ui-bootstrap (modal and accordion, since it is all in a modal window).
What can I do to make it refresh instantly? I'm stuck for days on this and it is frustrating... What am I doing wrong here?
EDIT: Please note that I know "::" is for one-way data binding. I've tried without it and the result is the same. I can probably resolve this by placing the data in question in the .json file, but that would really be an ugly hack.
<div ng-repeat="(k, v) in specs.webdev">
<h3>{{::v["job-title"]}}</h3>
<p>{{::v["job-body"]}}</p>
United States Apply Here:
<p>{{::v["job-apply"]}}</p>
</div>
The "::" avoid data binding to reduce digest cycle. Try to remove them.
<a data-ui-sref="uk-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
// it should be
<a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
I have solved this..What I wanted to do is to make the "URL" the same. I have changed the url to manifest the region by the region code, so it is working now.
For example:
UK:
$stateProvider
.state("de-web", {
url: "/web-developer-de",
templateUrl: "templates/de/web-developer.html",
})
.state("de-crm", {
url: "/crm-de",
templateUrl: "templates/de/crm.html"
})
Italy:
$stateProvider
.state("it-web", {
url: "/web-developer-it",
templateUrl: "templates/it/web-developer.html",
})
.state("it-crm", {
url: "/crm-it",
templateUrl: "templates/it/crm.html"
})
United States:
$stateProvider
.state("us-web", {
url: "/web-developer-us",
templateUrl: "templates/de/web-developer.html",
})
.state("us-crm", {
url: "/crm-us",
templateUrl: "templates/de/crm.html"
})
Although this works, I'm not happy. How can it be achieved that the templates are being loaded into the same url?

Setting up sub views and routes in ionic framework

I want to create and manage sub views in ionic but I couldn't figure out how to make it work, I want to make my login and dashboard pages as abstract, and all other pages be the sub views of dashboard :
for example : dashboard.fax or dashboard.inbox or dashboard.fax.send
I think my problem is my root ion_nav_view directive but I'm not sure, any suggestion how to make it work ?
index.html >>
<body ng-app="modiran">
<ion-nav-view name="menuContent"></ion-nav-view>
<!--<div data-ui-view="menuContent"></div>-->
</body>
partials/login.html >>
<ion-view view-title="login">
<ion-pane>
<div class="login">
<ion-content padding="true" scroll="false" ng-controller="SignInCtrl">
<div style="margin-top: 90%">
<div class="list list-inset login_inputs">
<label class="item item-input item-icon-right item-input-wrapper">
<i class="icon ion-person placeholder-icon"></i>
<input type="text" ng-model="user.username" placeholder="username" class="text-right">
</label>
</div>
<div class="list list-inset login_inputs">
<label class="item item-input item-icon-right item-input-wrapper">
<i class="icon ion-locked placeholder-icon"></i>
<input type="password" ng-model="user.password" placeholder="password" class="text-right padding-right">
</label>
</div>
<button class="item button button-block button-dark" ng-disabled="!user.username || !user.password"
ng-click="signIn(user)">login
</button>
</div>
</ion-content>
</div>
</ion-pane>
</ion-view>
partials/dashboard.html >>
<ion-view view-title="dashboard">
<ion-pane>
<ion-header-bar class="bar bar-header bar-dark" align-title="right">
<button class="button"><img src="img/navcon-logo.png" style="width: 35px; height:35px;"/></button>
<h1 class="title">modiran</h1>
</ion-header-bar>
<ion-content has-header="true" scroll="false" ng-controller="DashboardCrtl">
<div style="margin-top: 90%" class="dashboard">
<!--<i class="dash-icon"><img src="../img/24.png" style="width: 60%;height: 60%;"></i>-->
<img ng-src="img/Menubtn.png" style="width: 5%;height: 5%;margin-top: -8%;float: left;">
<img ng-src="img/MenubtnR.png" style="float: right;width: 5%;height: 5%;margin-top: -8%;">
<div class='circle-container'>
<a class='center' ng-click="GoTo('SmartOffice')"><img src="img/24.png"></a>
<a class='deg0'>
<img src='img/3.png'
onmouseover="this.src='img/3sel.png'"
onmouseout="this.src='img/3.png'">
<!--onmouseover="this.src='../img/3sel.png'"-->
</a>
<a class='deg45'>
<img src='img/4.png'
onmouseover="this.src='img/4sel.png'"
onmouseout="this.src='img/4.png'">
</a>
</div>
</div>
</ion-content>
</ion-pane>
</ion-view>
app.js >>
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
abstract: true,
templateUrl: 'partials/login.html',
controller: 'SignInCtrl'
})
.state('dashboard', {
url: '/dashboard',
abstract : true,
templateUrl: "partials/dashboard.html",
controller: 'DashboardCrtl'
})
.state('dashboard.SmartOffice', {
url: '/SmartOffice',
views: {
'menuContent': {
templateUrl: "partials/SmartOffice.html",
controller: 'SmartOfficeCtrl'
}
}
})
.state('dashboard.Fax', {
url: '/Fax',
views: {
'menuContent': {
templateUrl: "partials/fax/Fax.html",
controller: 'ّFaxCtrl'
}
}
})
$urlRouterProvider.otherwise('/login');
})
Try the following changes:
Remove name="menuContent" from the <ion-nav-view>. Why? login state doesn't specify where template should be loaded, by default it will load in the only available <ion-nav-view>, without a name. In case you want to add it, add it this way:
views: {
'menuContent': {
templateUrl: "partials/login.html",
controller: 'SignInCtrl'
}
}
Similarly for dashboard. To keep it simple, avoid giving name unless you have more than one nav views where templates can be loaded.
Your login state shouldn't be abstract state because you want to show login page.
You might need to check if user is logged in or not and conditionally show login or dashboard. You can do this in app.run block.

Angular route not working in custom menu directive

I am having hard time to route to particular url since the menu is coming from directive. Below is the code:
The Route:
var myApp = angular.module('myApp', ['ngRoute', 'mainMenu']);
myApp.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'pages/main.html'
})
.when('/home', {
templateUrl: 'pages/home.html'
})
.when('/bollywoodGossips', {
templateUrl: 'pages/bollywoodGossip.html'
})
.when('/bollywoodNews', {
templateUrl: 'pages/bollywoodNews.html'
})
.when('/bollywoodEvents', {
templateUrl: 'pages/bollywoodEvents.html'
})
.when('/bollywoodFitness', {
templateUrl: 'pages/bollywoodFitness.html'
})
.when('/bollywoodWallpaper', {
templateUrl: 'pages/bollywoodWallpaper.html'
})
.otherwise('/', {
templateUrl: 'pages/main.html'
})
})
The Directive:
(function(){
var mainMenu = angular.module('mainMenu', []);
var newMenu = function($location) {
var link = function(scope, element, attrs) {
element.parent('a.menuBtn').click(function(){
element.toggleClass('test');
});
}
return {
restrict: 'E',
replace: true,
templateUrl: 'pages/directiveTemplate/menu.html',
link: link
}
}
newMenu.$inject = ['$location'];
mainMenu.directive('newMenu', newMenu);
}());
The Menu Template:
<ul class="dropdownMenu">
<li>Bollywood Gossip</li>
<li>Bollywood News</li>
<li>Events</li>
<li>Celeb fitness Mantra</li>
<li>Celeb Wallpapers</li>
</ul>
And the html:
<div class="mainMenu">
<p>
<span class="breadCrumb">Home</span>
<a href="" class="menuBtn">Menu <span class="glyphicon glyphicon-th-large"></span>
<new-menu></new-menu>
</a>
</p>
</div>
The Index file:
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<div class="mainHeader">
<img src="imgs/mainHeader.jpg" alt="" class="img-responsive">
</div>
</div>
</div>
<div ng-view></div>
<div class="row">
<div class="col-xs-12">
<div class="footer">
<p>©2016 All rights reserved. NAYSA VAS Communications Pvt.Ltd.</p>
</div>
</div>
</div>
</div>
This renders correctly but when i click on any link inside the menu it does not route to that particular url. e.g #/bollywoodGossips .should go to index.html#/bollywoodGossips but it is not routing and remains still on index.html#/home. Please help I am new to directives..

Nested view is coming blank in Ionic

Following is my simple routes in app.js -
.state('signup', {
url: '/signup',
templateUrl: 'templates/signup.html',
controller: 'signupCtrl'
})
.state('profile', {
url: '/profile',
abstract: true,
templateUrl: 'templates/profile.html',
})
.state('profile.init', {
url: '/profile-init',
templateUrl: 'templates/profile-init.html'
})
I created a button in signup page on click which should take the user to profile-init page code - $state.go('profile.init')
in profile.html I placed -
<ion-content style="background: #c3c3c3"></ion-content>
in profile-init.html page -
<ion-header-bar class="bar-positive">
<h1 class="title">Profile</h1>
</ion-header-bar>
<div class="row">
<div class="col col-10"></div>
<div class="col col-80 padding">
Thanks for showing your interest
</div>
<div class="col col-10"> </div>
</div>
<ion-footer-bar class="bar-stable">
<button class="button button-clear" ng-click="hello()">Forward</button>
</ion-footer-bar>
But it is moving to /#/profile/profile-starter page but only a background color is coming not text, though I checked the browser console template is loading, let me know what I am doing wrong here.
Create ion-nav-view
<ion-nav-view name="profile"></ion-nav-view>
and modify routes in app.js
.state('profile.init', {
url: '/profile-init',
views: {
'profile': {
templateUrl: 'templates/profile-init.html'
}
}
})
Can't comment yet, and not available to test it but I think you need to use dot ('.') in your file name:
templateUrl: 'templates/profile.init.html'
And of course change the file name too.

Categories

Resources