How can I handle back button on pages with templates? - javascript

I am working on a site using angularjs. I divide the page into two section: menu and content.
for example
this a page: /mainpage
<div>
<div id="menu">
<div ng-click="setTemplate('firstPage.html')">Page 1</div>
<div ng-click="setTemplate('secondPage.html')">Page 2</div>
<div ng-click="setTemplate('thirdPage.html')">Page 3</div>
</div>
<div id="content" ng-template="template">
</div>
</div>
controller:
$scope.template = 'firstPage.html';
$scope.setTemplate = function(value){
$scope.template = value;
}
So after click on Page 1 Then Page 2 Then Page 3. So when i click on the back button, it load the last page / but not /mainpage with the right template. How would i handle the back button to not go back to previous page and go to previous template if there was a template change?
Thanks.

You should look at https://github.com/angular-ui/ui-router. You could build the functionality yourself, but ui-router is pretty much where you will end up.

The problem is you have nothing for it to default to. When you click back, it's just loading /mainpage, but it has no template to load in. Usually you use a $routeprovider for this:
$routeProvider
.when('/',
{
controller: 'yourControllerName.js',
templateUrl:'mainpage.html'
})
.otherwise(
{
redirectTo : '/'
});

Related

Need suggestions on AngularJS $routeProvider for login page and member page in same SPA

Login page (partial/login.html)
Includes a login form that will be shown using (ng-view)
Member page (partial/main.html)
Includes a nav bar
Includes the main container for contents (ng-view)
Question is how can I "hide" the nav bar in the Login page and only show it after the user has logged in?
Both my login page and member page shared the same index.html ng-view.
Sample index.html
<html ng-app>
<!-- LOGGED IN, SHOW NAV AND CONTENT-->
<div ng-if="logged" class="main_container">
<nav>
... nav bar contents here...
</nav>
<div class="main_container">
<div ng-view>... show partials ...</div>
</div>
</div><!-- end of LOGGED IN, SHOW NAV AND CONTENT-->
<!-- NOT LOGGED IN -->
<div ng-if="!logged" class="main_container">
<div ng-view></div>
</div>
<footer>...</footer
</html>
Tried using ng-if, but controllers are being called twice. May I know what others alternatives do I have?
ng-view should only be used once.
$routeProvider will help you load different view when $route changed, like:
app.config(function($routeProvider){
$routeProvider.when('/login', {
controller: 'LoginController',
templateUrl: 'partial/login.html'
})
.when('/', {
controller: 'MainController',
templateUrl: 'partial.main.html'
});
});
So now you only need to show/hide nav by your root controller, which can be injected in more top div in your page.
<div ng-controller="RootController" class="main_container">
<nav ng-if="logged">
... nav bar contents here...
</nav>
<div class="main_container">
<div ng-view>... show partials ...</div>
</div>
</div>
Next, you can set/get logged in RootController or its child controllers. Notice setting variables in child controller may create a new variable in child scope, so I suggest add a function in RootController to set logged or use a service/factory to store logged status.
You can do this using the ng-show directive, with the help of a function inside your controller.
<nav ng-show="loginStatus()">
... nav bar contents here...
</nav>
And inside your controller, you can add a function as such...
$scope.loginStatus= function() {
return $loginVariable;
}
Use the loginVariable to return true/false based on the users login status.
Similarly, you can use the ng-hide directive to hide the main_container div.

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

Angular dont show view before other view is loaded

I have three views:
nav, main content, footer.
Im using ui-router and when the page is loaded the nav and the footer are loaded immiditaly, but in the main content i have a request to get some data and the view delayed a one second after the nav and footer so i stuck with empty middle content to a second. How can i do that all the views will show at the same time?
<div ng-include="'client/template/nav.tpl.html'"></div>
<div class='main-wrapper'>
<div ui-view='' class='view'></div>
</div>
<div ng-include="'client/template/footer.tpl.html'"></div>
main content controller:
function HomeController( $scope, promos ) {
$scope.products = products.data; // this is come from the server directly, not ajax
}
One thing to notice that the data that requested to main content is not from ajax request it came from server request and its global.
Use ng-cloak on your template:
<div ng-cloak>
<div ng-include="'client/template/nav.tpl.html'"></div>
<div class='main-wrapper'>
<div ui-view='' class='view'></div>
</div>
<div ng-include="'client/template/footer.tpl.html'"></div>
</div>

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