Using ui-router for "main" layout? - javascript

I'm trying to create the 'main layout' for my page using ui-router views, but I can't seem to get it working right (various errors, controllers not getting called, templates not getting loaded).
<!DOCTYPE html>
<html ng-app="App">
<head>
...
</head>
<body>
<header ui-view="header">
</header>
<section ui-view="navigation">
</section>
<section ui-view="content">
</section
</body>
</html>
The idea is to have a state representing the "root" state for the whole site providing templates for navigation and header as well as a "root controller". Every other state loads it's content into the "content" view without affecting the others.
$stateProvider
.state("index", {
url: "/",
controller: "App.IndexController",
controllerAs: "vm",
views: {
"header#index" : { templateUrl: "app/main/header.html" }
// nav etc.
}
The app loads without any errors, but the templates as well as the controller never get invoked. Did I miss something?
I also saw that many people provide a separate "layout" view that get's loaded into an unnamed view (mostly on the <body> tag), but I consider this useless as the main index.html file is already my layout. Or: Is there a better way to achieve what I want?

There is an answer Angular UI Router - Nested States with multiple layouts with a working plunker showing layout: http://plnkr.co/edit/I0BJ09BxR7nG9kZDeEIv?p=preview
The point is that there is index.html with
<div ui-view="layout"></div>
And the root state then injects into that ui-view="layout" its own template (layout) and also injects into layout views.
So firstly the layout template:
<div>
<section class="top">
<div ui-view="top"></div>
</section>
<section class="middle">
<section class="left">
<div ui-view="left"></div>
</section>
<section class="main">
<div ui-view="main"></div>
</section>
</section>
</div>
And here is state def
$stateProvider
.state('root', {
url: '',
views: {
'layout': {
templateUrl: 'partials/layout/1-column.html'
},
'header#root': {
templateUrl: 'partials/layout/sections/header.html'
},
'footer#root': {
templateUrl: 'partials/layout/sections/footer.html'
}
}
})
And how it is working? we are using the absolute and relative target names.
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})

Related

Layout with form in angular Js

I am a beginner in angular Js and need some help / pointers. I want to create an application (SPA). Every page of an application has a header bar and in that header bar, I have a form (like search bar) where a user can add data and search. But I am not being able to approach.
How should my approach be so that this header is present in any page of my app and I must be able to search in any page. How can this be done without code repetition? I mean I dont want to create a directive and call it in every page. I want to know if there is a proper way to do it?
The app should be like Quora where the input field for question is present in any page.
Request you to not downvote it as I am naive in Angular and need some good help.
Thank you in advance.
Search for ui-router and define some states for your application, basically you have a main states which hold header and footer, and sub states that are children of your main state.
your markup would be like this:
<header></header>
<ui-view></ui-view>
<footer></footer>
and the header can contain the search form, and all sub states are loaded in mains <ui-view>
Have you checked out ui-router?
You could define a layout/root state whose template defines multiple named ui-views. The layout/root state could load the persisting elements (ex. the search input field) into one view, and child states could load the unique page content into another view.
ex. layout.html
<div class="layout">
<div class="search" ui-view="search"></div>
<div class="content" ui-view="content"></div>
</div>
ex. state configuration (in a module's config() function)
$stateProvider.state('root', {
url: '',
views: {
'main': {
templateUrl: 'layout.html'
},
'search#root': {
template: '<input type="text" ng-model="search.input" />',
controller: ['$scope', function($scope){
$scope.search = {
input: ''
};
}]
}
}
});
$stateProvider.state('root.page1', {
views: {
'content#root': {
template: '<p>This is the first page.</p>',
}
}
})
.state('root.page2', {
views: {
'content#root': {
template: '<p>This is the second page.</p>'
}
}
});
With that config, you would need to have in your main index.html:
<div ui-view="main"></div>
Plunker Demo

Angular partials in some views using ui-router

I'm building a MEAN application and having troubles dealing with ui-router. I have an index.html where i have the template of the entire website with a header, sidebar and a content where i place <div ui-view>. In this file I also load every javascript necessary like angular, ui-router, bootstrap, ocLazyLoad, etc.
Every partial view are placed in index.html content with ui-router states. My ui-router is configured this way:
myApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '../views/home.html',
resolve: {
deps: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'myApp',
files: [
'js/controllers/homeCtrl.js'
]
}]);
}]
}
})
});
Up to now I have everything controlled. My problem is this: How can i create a state login.html that does not have the header and the sidebar, because if the user is not logged in i don't want to show any options but login. How is the safest and best way to achieve this?
Thanks in advance.
My website shared the same case with you. What I did is I have 2 states: login and home. Login state will point to the login page and home state will point to home.html.
Here is example of home.html:
<div id="wrapper" ng-class='{"toggled" : $root.toggle }'>
<div ng-include="'components/sidebar/sidebar.html'"></div>
<div ng-include="'components/navbar/navbar.html'"></div>
<div id="page-content-wrapper">
<div class="container-fluid">
<!-- <ui-breadcrumbs displayname-property="data.displayName" abstract-proxy-property="data.proxy" ></ui-breadcrumbs> -->
<ui-breadcrumbs displayname-property="data.displayName" template-url="components/breadcrumb/uiBreadcrumbs.tpl.html"></ui-breadcrumbs>
<div ui-view="home"></div>
</div>
</div>
</div>
So all the states that after the user login should be the children state of home

Render New Views Within a Div Based on Click of Button | AngularJS

Hi I am trying to render a new view based on clicks of a button in a navbar. However, it is not working.
Here is my HTML Code:
<!-- Links to all the pages with data entry forms -->
<div id="data_links" ng-controller="MainCtrl">
<ul>
<li>
Home
</li>
</ul>
</div>
</div>
<!-- Modify views here -->
<div class="main" ng-controller="MainCtrl">
<main role="main">
<div ng-view> <!-- Where we will inject html --> </div>
</main>
</div>
<!-- Application Files -->
<script src="js/app.js"></script>
<script src="js/controllers/main.js"></script>
Here is my app.js:
angular.module('DataEntry', [
'ngRoute'
]).config(function ( $routeProvider ) {
$routeProvider
.when('instructions', {
templateUrl: 'views/instructions.html',
controller: 'MainCtrl'
});
});
Here is my controller main.js:
angular.module('DataEntry')
.controller('MainCtrl',
function MainCtrl ( $scope, $location ) {
'use strict';
$scope.ChangeView = function(view) {
alert(view);
$location.url(view);
}
});
This is my instructions.html page for testing to see if it loads:
<div class="module instructions">
<div class="module_instructions">
<h1> Testing Loaded! </h1>
<p> Test <br>
Test <br> Test <br> Test
</p>
</div>
</div>
I want to eventually be able to click on multiple links within a navbar, such as home, instructions, etc. and render different views within the ng-view section. However, it is not working right now and I am not sure how to scale it so I can add more .html pages for the different views I want to render. Can someone help me move forward?
This line
<a href="#" title="Home Page" ng-click = "ChangeView('instructions')"> Home
Can be changed to this:
Home
You don't need to use a function on your controller to set the url, although you can navigate this way - sometimes you want to redirect the user programatically and this works for those cases.
Also, leaving href="#" in that line is causing you a problem. In a non-angular page # is used as a href placeholder but on an Angular href="#" is actually going to be picked up by $routeProvider which will try to change the contents of the ng-view container. What loads will depend upon how you set up your .config section, but is generally not desirable behavior.
As you create more pages, add paths to your .config section and you can link to them from your html the same way as I did above with the /instructions path.
Here's an example:
angular.module('DataEntry', ['ngRoute'])
.config(function ( $routeProvider ) {
$routeProvider
.when('instructions', {
templateUrl: 'views/instructions.html',
controller: 'MainCtrl'
})
.when('faq', {
templateUrl: 'views/faq.html',
controller: 'FaqCtrl'
})
.when('example', {
templateUrl: 'views/example.html',
controller: 'ExampleCtrl'
})
});
and in your markup:
Home
FAQ
Example

angularjs hide ui-view on certain state

I have controller and template views of that controllers.
ProductCtrl => Products.html
SomeCrtl => Some.html
FooCtrl => Foo.html
I have a ui-view on home page.
<html>
<body>
<div ui-view></div>
....
State config like this:
app.config(["$stateProvider", function ($stateProvider) {
$stateProvider.state("product", {
url: "/product",
templateUrl: "templates/Products.html",
controller: "ProductCtrl"
});
}])
My last view is appearing on ui-view when application started. But I want that ui-view should be empty. When I click a link then should view that content.
Try to wrap your ui-view with an HTML element, and manipulate hide it using ng-hide depending on the current state.
Code sample
<div ng-hide="$state.current.name === 'home'">
<div ui-view></div>
</div>
Another way to do what #bookmarker mentioned:
<div ng-hide="$state.includes('home')">
<div ui-view></div>
</div>
$state.includes('...') can be used to see if a state contains a specified state, that is, check if a child state contains a certain parent state.

Different states don't show ui-views

Intro
I'm using AngularJS with the AngularUI module to build an admin interface with several views.
I have a simple Layout for public pages which has one ui-view and another one for admin pages which has four ui-views (header, sidebar, main, footer).
Problem
The problem I have is if I set the ui-view main the public state won't display the login view, but if I won't set the ui-view main the public state will display the login view. The header, sidebar and footer work with any setting. It seems some setting is overriding another even I tried to set absolute names. Could someone explain what's going on here?
ui-view="main" ==> Login doesn't show
ui-view="" ==> Login shows
Visual layout:
Source code (index.html):
<body>
...
<div ui-view="public">
</div>
<div class="admin">
<div ui-view="header"></div>
<div ui-view="sidebar"></div>
<div class="container" style="margin-top:60px" ui-view="">
<!-- ^ add main here -->
</div>
<div ui-view="footer"></div>
</div>
...
</body>
Code example
I set up a minimal full code example to outline the problem:
Plunker Edit
Plunker Run
I've played around with your demo a little bit and had a look at the ui-router documentation.
If you change your 'public' state as shown below then it seems to work.
Original:
.state('public', {
url: '/login',
title: 'Login',
templateUrl: 'login.html'
})
Updated:
.state('public', {
url: '/login',
views: {
'main#': {
title: 'Login',
templateUrl: 'login.html'
}
}
})
Here is an updated plunkr:
http://plnkr.co/edit/okBWMPpWysS9srKrcxeG?p=preview
Is that what you're trying to do, or are you trying to set up login as a nested view?

Categories

Resources