How can I make the first and second views simultaneously visible? - angularjs

I need two views which will be showed independently of each other. But when I click on the one the other being removed. I need not a child state but like a siblings. It is even possible?
Please, help. This is my Plnkr
<body ng-app="SiblingViews">
<h1>Hello Plunker!</h1>
<div>
<a ui-sref="view1">View_1</a>
<a ui-sref="view2">View_2</a>
</div>
<div ui-view="first"></div>
<div ui-view="second"></div>
</body>
$stateProvider
.state('view1', {
url: '/view-1',
views: {
'first': {
templateUrl: 'first.html'
}
}
})
.state('view2', {
url: '/view-2',
views: {
'second': {
templateUrl: 'second.html'
}
}
});

Related

ui-sref not working state angularjs

I'm working on something and I want to redirect the content to a page in angularjs, but I face the following error:
angular.js:12477 Error: Could not resolve 'dashboard.home' from state 'dashboard'
My code:
.state(
'dashboard.home',
{
url: '/home',
views: {
"content#main": {
templateUrl: '/home'
// controller: 'HomeController',
}
}
}
)
.state(
'dashboard',
{
url: '',
parent: "main",
views: {
"sidebar#main": {
templateUrl: "/sidebar/view"
}
}
})
sidebar.html.twig
<li>
<a ui-sref="dashboard.home">Home <span class="sr-only">(current)</span></a>
</li>
The state 'dashboard.home' exists, why the error appears?
I think you're probably trynig to use views to split header/footer/siderbar from the content which is the only thing to change according states.
I don't have the answer of what exactly is your problem but I may have an answer to a more broader question that you might are trying to solve :
How to mix views for header/content/footer and nested stated for content navigation ?
Solution : use views only for header/content/footer, use '#' to insert direct child by using the default view (no name) and use grand child as you would do normally without views
// root state
.state('home', {
url:'/home',
views:{
'header':{
templateUrl: 'template/header.html',
controller:'HeaderCtrl'
},'sidepanel':{
templateUrl: 'template/sidepanel.html',
controller:'SidePanelCtrl',
},'footer':{
templateUrl: 'template/footer.html'
}
},
'abstract':false
})
//direct child
.state('home.main', {
url:'/main',
// need that for every direct child of home
views:{
'#':{templateUrl: 'template/main.html',
controller: 'MainCtrl'
}
}
})
//grandchild
.state('home.main.child1', {
url:'/child1',
templateUrl: 'template/child1.html',
controller: 'Child1Ctrl'
// NO view anymore for grand child!!
}
})
And the Relevant HTML
<section id="header">
<!--- not container -->
<div data-ui-view="header"></div>
</section>
<section id="content">
<div class="row clearfix">
<div id="mySidebar>
<div data-ui-view="sidepanel"></div>
</div>
<div id="myContent">
<div data-ui-view></div>
</div>
</div>
</section>
<section id="footer">
<div data-ui-view="footer"></div>
</section>
The templateUrl expects the relative path of the html template that you want to render.
.state(
'dashboard.home',
{
url: '/home',
views: {
"content#main": {
templateUrl: 'home.html'
}
}
}).state(
'dashboard',
{
url: '',
parent: "main",
views: {
"sidebar#main": {
templateUrl: "sidebar/view.html"
}
}
})

AngularJS $stateprovider

I am new to angularjs, I am not able to understand the concept of $stateprovider
I want to create a header that has menu and logo and the body content should change when clicked on menu items accordingly, code is given below, please check and answer my query
HTML
<div ui-view = "header"></div>
<div ui-view = "content"></div>
JS
var App=angular.module('test', ["ui.router", "App.controllers", "ui.bootstrap"]);
App.config(function ($stateProvider){
$stateProvider
.state('test', {
url: '',
views: {
'header': { templateUrl: '/templates/header.html'}
}
});
})
Thank You
Since you have taken two views, one for header and other for content,
<div ui-view = "header"></div>
<div ui-view = "content"></div>
The route also should have two different named routes.
views: {
'header': { templateUrl: '/templates/header.html'},
'content': { templateUrl: '/templates/content.html'}
}
From this,
<div ui-view = "header"></div> opens header.html and <div ui-view = "content"></div> opens content.html
Here is the code,
var App=angular.module('test', ["ui.router", "App.controllers", "ui.bootstrap"]);
App.config(function ($stateProvider){
$stateProvider
.state('test', {
url: '',
views: {
'header': { templateUrl: '/templates/header.html'},
'content': { templateUrl: '/templates/content.html'}
}
});
})
In the HTML,
<ul class="nav nav-pills main-menu right">
<li role="presentation"><a ui-sref="test" class="active">Home</a></li>
<li role="presentation">Bus Chart</li>
<li role="presentation">My Bookings</li>
<li role="presentation">Reviews</li>
<li role="presentation">Contact</li>
</ul>
The first li click goes to our test state as given in routes.
Here is the documentation for the same
In config File
// State definitions
$stateProvider
.state('test', {
abstract: true,
views: {
'main#': {
templateUrl: 'app/../../full-view.html'
},
'header#test': {
templateUrl: '/templates/header.html' // correct path to the template
// controller: 'HeaderController as vm' if needed
},
'footer#test': {
templateUrl: '/templates/footer.html' // correct path to the template
// controller: 'FooterController as vm' if needed
}
}
});
HTML
in content-only.html
<div>
<div ui-view = "content"></div>
</div>
in full-view.html
<div class="container">
<div ui-view="header"></div>
<div>
<div ui-view="content"></div>
</div>
<div ui-view="footer"></div>
</div>
in index.html
<body>
<div ui-view="main"></div>
</body>
in other modules(example)
views: {
'content#test': {
templateUrl: 'app/main/policies/policies.html'
// controller: 'PoliciesController as vm' if needed
}
}
so that whatever you append to content#test will comes under ui-view="content"
for routing avoid using href="", use ui-sref="" since you are using ui-router
example ui-sref="app.home" or ui-sref="app.about" rather than usinghref="#/home" or href="#/about"

Nested Views and States Not showing

In my app I have the root state named "app":
.state('app', {
abstract: true,
views: {
'app': {
templateUrl: 'prebuilt/views/pages/index.html',
controller: 'MainController'
}
}
})
and its child "app.pages"
.state('app.pages', {
abstract: true,
views: {
'custom#app': {
templateUrl: 'prebuilt/views/templates/custom-styles.html'
},
'header#app': {
templateUrl: 'prebuilt/views/layout/header.html'
},
'topBar#app': {
templateUrl: 'prebuilt/views/layout/topbar.html'
},
'sideBar#app': {
templateUrl: 'prebuilt/views/layout/sidebar.html'
},
'infoBar#app': {
templateUrl: 'prebuilt/views/layout/infobar.html'
},
'contentSide#app': {
templateUrl: 'prebuilt/views/layout/contentside.html'
}
}
})
And grand child "app.pages.dashboard"
.state('app.pages.dashboard', {
url: '/',
views: {
'content#app.pages': {
templateUrl: 'prebuilt/views/index.html',
controller: 'DashboardController'
}
},
resolve: {
loadCalendar: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load([
'prebuilt/bower_components/fullcalendar/fullcalendar.js',
]);
}]
}
})
Now app loads an html view, inside that view are nested views which are/should be loaded when i navigate to "app.pages".
Now up to this point everything works just fine, however now I want to load a page in the content body of "app.pages", I've tried several times but the view never gets loaded:
This is a simplified version of my app.php:
<html>
<head></head>
<body>
<div ui-view="app"></div>
</body>
</html>
This is a simplified version of my index.html:
<div ui-view="header"></div>
<nav ui-view="topBar"></nav>
<div id="wrapper">
<div>
<di ui-view="sideBar">
</div>
<div>
<div>
<div>
<div class="col-md-9" ui-view="content">
</div>
<div class="col-md-3" ui-view="contentSide">
</div>
</div> <!--wrap -->
</div>
<footer>
<div class="clearfix">
<ul class="list-unstyled list-inline pull-left">
<li>© 2015</li>
</ul>
<button><i class="fa fa-angle-up"></i></button>
</div>
</footer>
</div>
</div>
</div>
<div ui-view="infoBar"></div>
One issue is incorrect absolute naming here:
// NOT correct
.state('app.pages.dashboard', {
url: '/',
views: {
// here is incorrect absolute name
'content#app.pages': {
templateUrl: 'prebuilt/views/index.html',
controller: 'DashboardController'
}
},
...
Because this is part of index.html, which is part of state 'app'
...
<div class="col-md-9" ui-view="content">
...
So the proper naming is just '...#app'
.state('app.pages.dashboard', {
url: '/',
views: {
// CORRECT
'content#app': {

Use common templates for different states

I want to be able to use two common components through out my app in all the states basically the header and the sidebar. I have read through the docs but i must have missed something. How can i reuse the header and sidebar in the states
$stateProvider
.state('home', {
url: '/leads:id',
views: {
'details': {
templateUrl: '../views/details.html',
controllerProvider: function($stateParams) {
if($stateParams.id) {
return 'CompanyDetails as companydetails';
}else {
return 'NewCompanyDetailsController as companydetails';
}
}
},
'sidebar': {
templateUrl: '../views/sidebar.html'
},
'header': {
templateUrl: '../views/header.html',
controller: 'HeaderCtrl as header'
},
'vehicledetails': {
templateUrl: '../views/vehicledetails.html',
controller: 'VehicleDetailsController as vehicledetails'
},
'comments': {
templateUrl: '../views/comments.html',
controller: 'CommentsController as comments'
},
'saveupdate': {
templateUrl: '../views/saveupdate.html',
controller: 'SaveUpdateDetailsController as saveupdate'
}
}
});
I want to create another state called 'data' for example which reuses the header and sidebar. How can I acheive this without requiring to write down all the the components again ?
I did a bit of reading and now, I have an updated state provider that displays the common header and sidebar on all routes but the data inside the actual container is not being displayed at all. Here is my updated code
$stateProvider
.state('home', {
abstract: true,
views: {
'header': {
templateUrl: '../views/header.html',
controller: 'HeaderCtrl as header'
},
'sidebar': {
templateUrl: '../views/sidebar.html'
}
},
resolve: {
somedata: function(){return {}}
}
})
.state('home.login', {
url: '/',
views: {
'login#home': {
templateUrl: '../views/login.html'
}
}
})
.state('home.leads', {
url: '/leads:id',
views: {
'details#home': {
templateUrl: '../views/details.html',
controllerProvider: function($stateParams) {
if($stateParams.id) {
return 'CompanyDetails as companydetails';
}else {
return 'NewCompanyDetailsController as companydetails';
}
}
},
'vehicledetails#home': {
templateUrl: '../views/vehicledetails.html',
controller: 'VehicleDetailsController as vehicledetails'
},
'comments#home': {
templateUrl: '../views/comments.html',
controller: 'CommentsController as comments'
},
'saveupdate#home': {
templateUrl: '../views/saveupdate.html',
controller: 'SaveUpdateDetailsController as saveupdate'
}
}
});
and my index.html
<body ng-app="MyApp">
<div id="page-wrapper" ng-class="{'open': toggle}" ng-cloak class="open" ng-controller="SlideCtrl">
<div id="sidebar-wrapper" ui-view="sidebar">
</div>
<div id="content-wrapper">
<div class="page-content">
<!-- Header Bar -->
<div class="row header" ui-view="header">
</div>
<!-- Header Bar -->
<div ui-view="login"></div>
<div ui-view="details" class="panel panel-default col-xs-11" ></div>
<div ui-view="vehicledetails" class="panel panel-default col-xs-11" ></div>
<div ui-view="comments" class="panel panel-default col-xs-11" ></div>
<div ui-view="saveupdate"></div>
</div>
</div>
</div>
<script src="js/main.js"></script>
</body>
I actually managed to get this working now using this link https://stackoverflow.com/a/28826126/1679310
I will explain my answer since I couldnt understand how it worked before I did it on my own. You need this to be present for the child states to plug into it.
https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#scope-inheritance-by-view-hierarchy-only
Basically you create a main ng-view inside the index.html that serves as the container to your others partials then you basically contain all the child ui-views inside another layout that will serve as the parent to all the states.
So in essence your structure is something like this
<body ng-app="MyApp">
<div id="page-wrapper" ng-class="{'open': toggle}" ng-cloak class="open" ng-controller="SlideCtrl">
<div ng-view>
</div>
</div>
<script src="js/main.js"></script>
and another file that has the layouts
<div id="sidebar-wrapper" ui-view="sidebar">
</div>
<div id="content-wrapper">
<div class="page-content">
<!-- Header Bar -->
<div class="row header" ui-view="header">
</div>
<!-- Header Bar -->
<div ui-view="login"></div>
<div ui-view="details" class="panel panel-default col-xs-11" ></div>
<div ui-view="vehicledetails" class="panel panel-default col-xs-11" ></div>
<div ui-view="comments" class="panel panel-default col-xs-11" ></div>
<div ui-view="saveupdate"></div>
</div>
</div>
Then you basically follow the pattern here
$stateProvider
.state('home', {
abstract: true,
views: {
'#': {
templateUrl: '../views/layouts.html'
},
'header#home': {
templateUrl: '../views/header.html',
controller: 'HeaderCtrl as header'
},
'sidebar#home': {
templateUrl: '../views/sidebar.html'
}
}
})
.state('home.login', {
url: '/',
views: {
'login#home': {
templateUrl: '../views/login.html'
}
}
})
For all your states. This worked for me and I am pretty sure that is the right way to do so.
There's a better way:
HTML part
Index file (index.html):
<html ng-app="app">
<head></head>
<body ui-view></body>
</html>
Base file (layout.html)
<header>
Here's the header part
</header>
<aside>
Here's the sidebar part
</aside>
<main ui-view>
And here is where the app will be ran when you go to a state like "app.home"
</main>
States:
var states = {
'app': {
templateUrl: 'app/layout.html',
controller: 'LayoutController as layout'
},
'app.home': {
templateUrl: 'app/home.html',
controller: 'HomeController as home'
}
};
angular.forEach(states, function(config, name) {
$stateProvider.state(name, config);
});

UI-Router nested view not working

I am trying to create nested view with angular breadcrumb ... and here the problem is in state app.input1.input2 its own template input2 is not loading.. its only loading app.input1 continuously...
If I try to give wrong templateUrl in app.input1.input2 then it throws error back but when I give correct path then its not loading same template and any error .. it just loading same template of app.input1
Suggest me some idea why that template is not loading?
#app.js
$stateProvider
.state('app', {
abstract: true,
url: '/app',
templateUrl: 'view/abc.html',
data: {
breadcrumbProxy: 'app.start'
}
})
.state('app.start', {
url: '/start',
templateUrl: 'view/start.html',
data: {
displayName: 'start',
}
})
.state('app.input1', {
url: '/input1',
templateUrl: 'view/input1.html',
data: {
displayName: 'input1',
}
})
.state('app.input1.input2', {
url: '/input2',
templateUrl: 'view/input2',
data: {
displayName: 'input2',
}
});
$urlRouterProvider.otherwise('app.start');
index.html
<div ui-view></div>
abc.html
<div ui-view></div>
start.html
<div>
<a ui-sref="app.input1">Input1</a>
</div>
input1.html
<div>
<a ui-sref="app.input1.input2">Input2</a>
</div>
input2.html
<div>bla bla bla bla</div>
Here is a working plunker. Change made is here:
input1.html
<div>
<a ui-sref="app.input1.input2">Input2</a>
<div ui-view></div> // anchor for child
</div>
The input2 is a child state of input1. So we need to create an anchor/target for it. Check the plunker here
Also, I used this as otherwise:
$urlRouterProvider.otherwise('/app/start');

Resources