how to set a starting page in a ionic project - angularjs

Sorry if this is a stupid question I am still fairly new to this. I have a basic understanding of how the navigation works with angular js but I cant figure out how to set a starting page. I want to set my login page as my start page the url shows that the login page is open ("http://localhost:8100/#/template/login") but it only displays a blank header which I suspect is from my index (ion-nav-bar).
thank you.
index.html
<body ng-app="starter">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<!--
The views will be rendered in the <ion-nav-view> directive below
Templates are in the /templates folder (but you could also
have templates inline in this html file if you'd like).
-->
<ion-nav-view class="slide-left-right"></ion-nav-view>
</body>
</html>
login.html
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<h1>lalalalala</h1>
<div class="list">
<label class="item item-input">
<span class="input-label">Username</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Password</span>
<input type="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
</ion-view>
app.js
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
// Each tab has its own nav history stack:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.projects', {
url: '/projects',
views: {
'tab-projects': {
templateUrl: 'templates/tab-projects.html',
controller: 'projectsCtrl'
}
}
})
.state('tab.projects-detail', {
url: '/projects/:projectsId',
views: {
'tab-projects': {
templateUrl: 'templates/projects-detail.html',
controller: 'projectsDetailCtrl'
}
}
})
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'AccountCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('login');
});
controllers.js
angular.module('starter.controllers', [])
.controller('loginCtrl', function($scope) {})
.controller('DashCtrl', function($scope) {})
.controller('projectsCtrl', function($scope, Chats) {
$scope.chats = Chats.all();
$scope.remove = function(chat) {
Chats.remove(chat);
}
})
.controller('ChatDetailCtrl', function($scope, $stateParams, Chats) {
$scope.chat = Chats.get($stateParams.chatId);
})
.controller('AccountCtrl', function($scope) {
$scope.settings = {
enableFriends: true
};
});

I guess the problems is in your default route:
$urlRouterProvider.otherwise('/tab/login');
You have defined it depending from the abastract tab:
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
and this is your login:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
the state name is tab.login which means it inherits from tab.
so your root is /tab/login.
this should be your tabs.html:
<ion-tabs class="tabs-icon-top tabs-color-active-positive">
<ion-tab title="Login" icon-off="ion-ios-pulse" icon-on="ion-ios-pulse-strong" href="#/tab/login">
<ion-nav-view name="login"></ion-nav-view>
</ion-tab>
<ion-tab title="Status" icon-off="ion-ios-pulse" icon-on="ion-ios-pulse-strong" href="#/tab/dash">
<ion-nav-view name="tab-dash"></ion-nav-view>
</ion-tab>
</ion-tabs>
as you can see your ion-nav-view name:
<ion-nav-view name="login"></ion-nav-view>
must match the one defined in your state:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'login.html',
controller: 'loginCtrl'
}
}
})
You don't need to set the view's name here (login.html):
<ion-view view-title="Login" name="login-view">
Another thing I've noticed, you use the same name for two different views: tab-projects:
.state('tab.projects', {
url: '/projects',
views: {
'tab-projects': {
templateUrl: 'templates/tab-projects.html',
controller: 'projectsCtrl'
}
}
})
.state('tab.projects-detail', {
url: '/projects/:projectsId',
views: {
'tab-projects': {
templateUrl: 'templates/projects-detail.html',
controller: 'projectsDetailCtrl'
}
}
})
another thing has more to do with conventions. If you use for your views names starting with tab-, probably you should do the same for the login.
Here is a plunker with some of your code.

I've been putting comments regarding your code, so let me formulate an answer with some steps you would like to follow
1:
You have a mess once you declare your controllers, try to follow a guide like this, at least declare your controllers/services/directives and so on in the same way, LoginCtrl and not loginCtrl and the other stuff with no capital as a first letter. It is just an advise my friend.
2:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
here something you need to check, the name of your view, you have login but
<ion-view view-title="Login" name="login-view">
...
</ion-view>
so change it to login only. And do the same in your abstract route.
like this
<ion-view view-title="Login" name="login">
And this so important
$urlRouterProvider.otherwise('/login');
which goes at the end of the $stateProvider. The otherwise method will always redirect to /login in case that any other route it's been matched

Change your app.js to
.state('login', {
url: '/login',
controller: 'LoginCtrl',
templateUrl: 'templates/login.html'
})
and $urlRouterProvider.otherwise('/login');
If you place your login.html in correct folder then there is not going to be any problem.

You should give a name to your <ion-nav-view> in your index.html template.
e.g. <ion-nav-view name="viewContent"></ion-nav-view>
Then, in your routes, you specify into which part of your app you want your template to be rendered, e.g.:
.state('login', {
url: '/login',
views: {
'viewContent': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
this will render templates/login.html into the viewContent area.
That's why UI-router is so flexible, because you can tell it exactly which parts should be replaced when routing.
If you don't need that flexibility, just write your routes without the views part and add controller and templateUrl directly to each state.
also your fallback probably should be $urlRouterProvider.otherwise('/login');

If you want to evaluate a success at login to show certain views should not be in the same state.
This should be true:
.state('login',{
url: "/login",
views : {
'menuContent' : {
templateUrl : "login.html",
controller : "LoginCtrl"
}
}
})
$urlRouterProvider.otherwise("/login");
Follow the order as advice or guide on how to write their app.js
<script id="login.html" type="text/ng-template">
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<h1>lalalalala</h1>
<div class="list">
<label class="item item-input">
<span class="input-label">Username</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Password</span>
<input type="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
</ion-view>
</script>

I had a similar problem..simply open your app.js file..then right at the bottom you will find $urlRouterProvider.otherwise('/app/tabs'); so for instance if the page thats currently loading is "tabs"
simply change the value tabs to your prefered page name inorder for that page to load as the first default page.

There is config.xml file. Open it and and you will see 'Start Page' Option. Then enter any page you want to start.

Related

Ionic Control Pages

I am trying to put on my app 3 page content in one .html file but I cant figure it out to do that. My .html page code is here:
<script id="templates/topList.html" type="text/ng-template">
<ion-view>
<ion-content class="padding">
<p>
<a class="button icon icon-right ion-chevron-right" href="#/tab/facts">Scientific Facts</a>
</p>
</ion-content>
</ion-view>
</script>
<script id="templates/topList2.html" type="text/ng-template">
<ion-view>
<ion-content class="padding">
<p>
<a class="button icon icon-right ion-chevron-right" href="#/tab/facts">Scientific Facts</a>
</p>
</ion-content>
</ion-view>
</script>
And my app.js is this:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/home.html'
})
.state('registration', {
url: '/registration',
templateUrl: 'templates/registration.html',
controller: 'RegistrationCtrl'
})
.state('code_entery_page', {
url: '/code_entery_page',
templateUrl: 'templates/code_entery_page.html',
controller: 'code_entery_pageCtrl'
})
.state('registration-create-profile', {
url: '/registration-create-profile',
templateUrl: 'templates/registration-create-profile.html',
controller: 'registration-create-profileCtrl'
})
.state('app.main-traveler-page', {
url: '/main-traveler-page',
templateUrl: 'templates/main-traveler-page.html',
controller: 'main-traveler-pageCtrl'
})
.state('pinko.main-pinko-page', {
url: '/main-pinko-page',
templateUrl: 'templates/main-pinko-page.html',
controller: 'main-pinko-pageCtrl'
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/directives/traveler-navigation.html',
controller: 'AppCtrl'
})
.state('pinko', {
url: '/pinko',
abstract: true,
templateUrl: 'templates/directives/pinko-navigation.html',
controller: 'AppCtrl'
})
$urlRouterProvider.otherwise('/');
});
but I dont know how to connect to toplist.html and toplist2.html in app.js to work when my page is open?
In app.js - .state('pinko.main-pinko-page') is the page where i want to show toplist.html and toplist2.html
Add your both template in single html file like common-template.html.
And include this common-template in main-pinko-page.html as you mentioned in your question that's needed in .state('pinko.main-pinko-page').
If this one required in only one place use above case otherwise include this common-template in your main html file from where all the navigation initiates.

Setting login page with other views with parent and child states - Ionic

I am new to UI router and new to Ionic as well.
I am simply looking to create a login page with just a form. Then dashboard and other views will contain a common menu and a header from thereafter in each view.
I am not sure how to proceed with the structuring of the same in config function and my index.html.
Note: I know about angularjs app constructions where I used to have the common header, menu and footer directives for the similar thing in each view.
Update after Anuj's answer
My menu.htm - Is this correct ?
<ion-view>
<ion-content>
<ion-side-menus>
<ion-side-menu side='right'>
<ion-nav-bar class="bar-positive">
<ion-nav-buttons side="right"
>
<button menu-toggle-right class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
</ion-nav-bar>
</ion-side-menu>
<ion-side-menu-content>
</ion-side-menu-content>
</ion-side-menus>
</ion-content>
My Login view
<ion-view>
<ion-content>
<h3>{{msg}}</h3>
<h4>hflahfjasghf</h4>
</ion-content>
</ion-view>
After defining config function as
.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.htm",
controller: "AppCtrl"
})
.state('app.login', {
url: "/login",
templateUrl: "templates/login.htm",
controller: "LoginCtrl"
})
.state('app.dashboard', {
url: "/dashboard",
templateUrl: "templates/dashboard.htm",
controller: "DashboardCtrl"
})
$urlRouterProvider.otherwise('/app/login');
})
.controller('AppCtrl', function($scope){
$scope.msg = "AppCtrl";
});
My app shows a blank login page
download ionic template. in it configure app.js with stateProvider like
.config(function($stateProvider){
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/social/menu.html",
controller: 'AppCtrl'
}).state('app.login', {
url: '/login',
views: {
'menuContent': {
templateUrl: 'templates/social/login.html',
controller: 'LoginCtrl'
}
} $urlRouterProvider.otherwise('/app/login');
});

AngularJS : How do I nest a view within a parent state with parameters?

I'm using the Ionic Framework to create a mobile app, but I'm having a difficult time with the UI Router. I've gotten a few screens working properly, but I can't seem to get nested views working on a state with parameters. I'd like a URL that looks like /legislator/1/profile. It would have a header with the name of legislator #1 and tabs below. The profile tab would be automatically visible and clicking on other tabs (e.g. /legislator/1/votes) would change the content, but not the header
I wound up abandoning the tabs & sidemenu starter projects to customize my nested views. Here's what I have in app.js. The home and people.* states work correctly, but I can't seem to load the legislator screen with the profile view in place. I've tried changing the abstract & controller attributes, but no luck yet.
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/home.html",
controller: "homeController"
})
.state('people', {
url: "/people",
abstract: true,
templateUrl: "templates/people.html"
})
.state('people.legislators', {
url: "/legislators",
templateUrl: "templates/legislators.html",
controller: "legislatorController"
})
.state('people.following', {
url: "/following",
templateUrl: "templates/following.html",
controller: "followingController"
})
.state('legislator', {
url: "/legislator/{legislatorId:int}",
templateUrl: "templates/legislator.html",
abstract: true
})
.state('legislator.profile', {
url: "/legislator/{legislatorId:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
.state('legislator.votes', {
url: "/legislator/{legislatorId:int}/votes",
templateUrl: "templates/legislator.votes.html",
controller: "votelistController"
})
$urlRouterProvider.otherwise('/home');
// if none of the above states are matched, use this as the fall-back
})
How is this scenario supposed to work in the UI Router? Once I have $stateProvider configured, how should the tabs link to the nested states?
Thanks for any help you can give me.
Maybe your solution is as simple as replacing the classic href by Ui Router's ui-sref:
replace
<ion-tab ... href="#/legislator/{ scopeLegislatorId }/profile">...</ion-tab>
by
<ion-tab ... ui-sref="legislator.profile({ legislatorId: scopeLegislatorId })">...</ion-tab>
Where scopeLegislatorId is the legislatorId, available from your scope.
If that doesn't help, please provide us with your html files (e.g. legislator.html and legislator.profile.html).
You can use following method to create separate views.
state('people.following',{
data:{
anyVar: {
label: 'cp',
text : 'anyText'
}
},
views: {
'content#people': angularAMD.route({
template: infoView,
controller: 'custInfoCtrl',
controllerUrl: 'modules/custCtrl'
}),
'mobileView#people': angularAMD.route({
template: mobileView,
controller: 'mobileCtrl',
controllerUrl: 'modules/mobileBottomViewCtrl'
})
}
})
<pre>
<div ui-view='contentArea'> </div>
<div ui-view='mobileView'> </div>
</pre>
RobYed pointed me in the right direction to figure out the right way to define my states. Here's the bones of what I wound up with.
app.js:
.state('legislator', {
url: "/legislator",
templateUrl: "templates/legislator.header.html",
abstract: true,
})
.state('legislator.profile', {
url: "/{seq_no:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
templates/legislator.header.html:
<ion-nav-view animation="slide-left-right">
<div class="bar bar-header" ng-controller="profileController">
{{legislator.name}}
</div>
<div class="tabs tabs-striped tabs-top">
<a class="tab-item" ui-sref="legislator.profile" ng-class="{selected: is('legislator.profile')}">
{{'Profile' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.votes" ng-class="{selected: is('legislator.votes')}">
{{'Votes' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.stats" ng-class="{selected: is('legislator.stats')}">
{{'Stats' | translate}}
</a>
</div>
<div ui-view></div>
</ion-nav-view>
templates/legislator.profile.html:
<ion-content>
<div class="bar bar-stable has-subheader" style="height:145px;">
{{legislator.whatever}}
Content Here
</div>
</ion-content>
profileController.js:
'use strict';
angular.module('myApp').controller('profileController', function($scope, $rootScope) {
$scope.legislator = $rootScope.legislators[$stateParams.seq_no-1];
});
Links from other states:
<a ui-sref="legislator.profile({seq_no:legislator.seq_num})"></a>

ionic/angular $state.go gives blank screen on change

I'm trying to implement a facebook login for my ionic app based on this tutorial Coenraets fb tutorial, but I am coming across some problems.
I use tabs in my app, but when I try and redirect a user to the login page (tab) if they are not logged in, the login page shows as being blank (the navigation bar is still at the top though). If I refresh the page though, the login page then shows correctly. I know it is at least trying to redirect the page because I can't go to other tabs, just always this blank login tab.
Here is where I declare my tabs:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
//setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
.state('tab.login', {
url: '/login',
views: {
'tab-login': {
templateUrl: 'templates/tab-login.html',
controller: 'AppCtrl'
}
}
})
//example of another state
.state('tab.map', {
url: '/map',
views: {
'tab-map': {
templateUrl: 'templates/tab-map.html',
controller: 'MapController'
}
}
})
Here is what my Login Tab HTML looks like:
<ion-view title="Login" name="tab-login" hide-back-button="true" style="background: #1b5a83" hide-nav-bar="true">
<ion-content has-header="true" padding="true" ng-controller="AppCtrl">
<div class="list list-inset" style="background: #1b5a83">
<div class="item item-image" style="border:none;margin-top:50px;">
<img src="img/sociogram.jpg"/>
</div>
<button class="button button-block button-light" ng-click="facebookLogin()">
<i class="icon ion-social-facebook"></i>
Login with Facebook
</button>
</div>
</ion-content>
And here is where my redirection takes place inside the .run function:
.run(function($rootScope, $state, $ionicPlatform, $window, OpenFB) {
OpenFB.init(fbappid, 'http://localhost:8100/oauthcallback.html', window.sessionStorage);
$ionicPlatform.ready(function() {
$rootScope.$on('$stateChangeStart', function(event, toState) {
if (toState.name !== "tab.login" && toState.name !== "tab.logout" && !$window.sessionStorage['fbtoken']) {
$state.go('tab.login');
event.preventDefault();
}
});
$rootScope.$on('OAuthException', function() {
$state.go('tab.login');
});
})
Any ideas where I am going wrong??? Thanks
Make sure that in your templates/tabs.html is a named <ion-nav-view>, because in your state 'tab.login' you tell UI router to look for a view placeholder with the name 'tab-login'. So you need to define this in your template:
<ion-nav-view name="tab-login">
Or you change your state definition to use an empty view name, so it references your unnamed <ion-nav-view> in the parents state 'tab':
.state('tab.login', {
url: '/login',
views: {
'': {
templateUrl: 'templates/tab-login.html',
controller: 'AppCtrl'
}
}
})
In your linked example there is only one named view vor all states, see https://github.com/ccoenraets/sociogram-angular-ionic/blob/master/www/templates/menu.html#L7
Have a look at multiple nested views in UI router here: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

ionic sidemenu not showing up

I am using ionic framework's sidemenu project to build something on top of it.
I have created this plunker to demonstrate my problem.
In the plunker, on the join page, when you click home, it shows blank screen. I can see that the HTML elements of sidemenu are all there, however, it doesnt showup on screen.
If I change my sidemenu with tabs, it works fine.
Does anyone know whats going on?
My sidemenu template looks like this:
<ion-side-menus>
<ion-pane side-menu-content>
<ion-nav-bar class="bar-dark nav-title-slide-ios7">
<ion-nav-back-button class="button-clear"><i class="icon ion-ios7-arrow-back"></i> Back</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view>
</ion-pane>
<ion-side-menu side="left">
<header class="bar bar-header bar-dark">
<h1 class="title">Menu</h1>
</header>
<ion-content class="has-header">
<ion-list>
<ion-item nav-clear menu-close ui-sref="home">
Search
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
My states looks like this:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
//url: "/app",
abstract: true,
templateUrl: "tpl.tabs.html",
controller: 'AppCtrl'
})
.state('join', {
url: "/join",
views: {
'': {
templateUrl: "tpl.join.html",
controller: 'joinCtrl'
}
}
})
.state('home', {
parent: 'app',
url: "/app",
views: {
'home': {
templateUrl: "tpl.home.html",
controller:'homeCtrl'
}
}
})
.state('menu', {
parent: 'app',
url: "/menu",
views: {
'menuContent': {
templateUrl: "tpl.home.html",
}
}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/join');
})
You had several misconceptions in your code here is how it works properly.
First of all, I recommend you to use the newest version of Ionic.
Then make sure you use the
<ion-side-menu-content></ion-side-menu-content>
and the parent/child view function of the ui-router with dot notation, for example:
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "tpl.tabs.html",
controller: 'appCtrl'
})
.state('app.join', {
url: "/join",
views: {
'menuContent': {
templateUrl: "tpl.join.html",
controller: 'joinCtrl'
}
}
});
I solved it myself.
The problem was with the naming of views of the states, which should match with the
ion-nav-view name in the abstract template.
The updated solution is here

Resources