Multiple views in blank ionic app - ionic-framework

In index.html I have included these javascripts:
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
And then I have:
<body ng-app="starter">
<ion-nav-view></ion-nav-view>
</body>
In app.js I have this:
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('view.splash', {
url: '/',
views: {
'view.splash': {
templateUrl: 'templates/view-splash.html',
controller: 'SplashCtrl'
}
}
})
.state('view.login', {
url: '/login',
views: {
'view.login': {
templateUrl: 'templates/view-login.html',
controller: 'LoginCtrl'
}
}
});
$urlRouterProvider.otherwise('/');
});
And finally in controllers.js I have:
angular.module('starter.controllers', [])
.controller('SplashCtrl', function($scope) {
$scope.appname = 'Wetters';
})
.controller('LoginCtrl', function($scope) {
$scope.whereami = 'on login';
})
Now, splash.html looks like this:
<ion-view view-title="Splash">
<ion-content>
This is splash
</ion-content>
</ion-view>
However, when I go to the app with browser, nothing is displayed. The page is empty.
I don't really understand whats wrong.
On ionic-page they don't write much about blank pages, focus is most on tab or menu apps.
What should you put inside index.html when you want to view multiple views, one at the time? I think the problem could be Im using:
<ion-nav-view></ion-nav-view>
Maybe I should put something else in index, but I really dont know what to put there.

I make a example for you:
Splash and Login example
If you need some help, just call!
Here is the code, if you cannot see in codepen:
HTML
<html ng-app="ionicApp">
<title>Side Menus</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
<ion-nav-view></ion-nav-view>
<script id="templates/splash.html" type="text/ng-template">
<ion-view view-title="Splash" ng-controller="SplashCtrl">
<ion-content>
Splash
</ion-content>
</ion-view>
</script>
<script id="templates/login.html" type="text/ng-template">
<ion-view view-title="Login" ng-controller="LoginCtrl">
<ion-content>
Login
</ion-content>
</ion-view>
</script>
JS
angular.module('ionicApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('splash', {
url: "/",
templateUrl: "templates/splash.html"
})
.state('login', {
url: "/login",
templateUrl: "templates/login.html"
});
$urlRouterProvider.otherwise("/");
})
.controller('SplashCtrl', function($scope, $state, $timeout) {
$timeout(function() {
$state.go('login');
}, 3000);
})
.controller('LoginCtrl', function($scope) {
});

Related

ion nav view not rendering template

I'm begining with ionic framework.
I've got some problem,
I think I've already done all thing needed well
inn app.js
angular.module('starter', ['ionic'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
if (window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('home', {
url: '/home',
templateUrl: 'views/home.html'
}).state('about', {
url: '/about',
templateUrl: 'views/about.html'
});
$urlRouterProvider.otherwise("/home.html");
});
in index.xhtml
<body ng-app="starter">
<!--<ion-nav-bar class="bar-positive"></ion-nav-bar>-->
<ion-nav-bar class="bar-positive">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
in home.html
<ion-view view-title="home">
<ion-content>
<p>
<a ui-sref="about">About</a>
</p>
</ion-content></ion-view>
when I look at the firebug, I can see the answer but the ion-nav-view doen't render the ion-view defined in home page
When loading a view, you have to use the property set in the url property, not the path of the template. SO you have to change /home.html for /home.
$urlRouterProvider.otherwise("/home");

Ionic : Navigate in nested states breaks history and ion-nav-back-button

It seems impossible to navigate to a child state of a sibling or to a child state of an ancestor.
The workaround I used was to put all the states on the same level, which allows me to navigate to any state I need (navigate from a push notification to a nested state, navigate from one nested state to a state inside another parent, etc ...).
The problem with that method is that states and controllers do not inherit any code, leading to code duplication. Moreover, there are cases where the navigation is simply broken and the ion-nav-back-button do not behave as it should.
TLTR: What structure must be used to have a fully navigable application (check out the pen), when you use tabs and nested states ?
Here is the pen describing the problem : http://codepen.io/ruslan-fidesio/pen/LkyAkm
HTML :
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="http://code.ionicframework.com/1.3.1/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.3.1/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="app">
<ion-nav-view></ion-nav-view>
<script id="home.html" type="text/ng-template">
<ion-view view-title="Home">
<ion-content>
<br/>
<a ui-sref="app.tabs.themes.details">Go to Child : broken</a>
<br/>
<br/>
<a ui-sref="app.other">Go to Other : broken</a>
</ion-content>
</ion-view>
</script>
<script id="tabs.html" type="text/ng-template">
<ion-nav-bar class="bar-positive">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-tabs class="tabs-positive">
<ion-tab title="home" ui-sref="app.tabs.home">
<ion-nav-view name="tabs-home"></ion-nav-view>
</ion-tab>
<ion-tab title="themes" ui-sref="app.tabs.themes.list">
<ion-nav-view name="tabs-themes"></ion-nav-view>
</ion-tab>
</ion-tabs>
</script>
<script id="themes/abstract.html" type="text/ng-template">
<div class="bar bar-subheader bar-dark" sticky>
Themes subheader
</div>
<ion-nav-view></ion-nav-view>
</script>
<script id="themes/list.html" type="text/ng-template">
<ion-view view-title="Themes">
<ion-content class="has-subheader">
<p>Parent View</p>
<a ui-sref="app.tabs.themes.details">Go to Child : OK !</a>
</ion-content>
</ion-view>
</script>
<script id="themes/details.html" type="text/ng-template">
<ion-view view-title="Theme X">
<ion-content class="has-subheader">
Child View
</ion-content>
</ion-view>
</script>
<script id="other.html" type="text/ng-template">
<ion-view view-title="Other">
<ion-nav-bar class="bar-positive">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-content>
<br/>
Other View
<br/>
<a ui-sref="app.tabs.themes.details">Go to Child : broken</a>
</ion-content>
</ion-view>
</script>
</body>
</html>
JS :
var app = angular.module(
'app', [
'ionic'
]
);
app.run(
function($ionicPlatform, $rootScope) {
$ionicPlatform.ready(
function() {
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
}
);
}
);
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
template: '<ion-nav-view></ion-nav-view>'
})
.state('app.tabs', {
url: '/tabs',
abstract: true,
templateUrl: 'tabs.html'
})
.state('app.tabs.home', {
url: '/home',
views: {
'tabs-home': {
templateUrl: 'home.html'
}
}
})
.state('app.other', {
url: '/other',
templateUrl: 'other.html'
})
.state('app.tabs.themes', {
url: '/themes',
abstract: true,
views: {
'tabs-themes': {
templateUrl: 'themes/abstract.html'
}
}
})
.state('app.tabs.themes.list', {
url: '/list',
templateUrl: 'themes/list.html'
})
.state('app.tabs.themes.details', {
url: '/details',
templateUrl: 'themes/details.html'
});
$urlRouterProvider.otherwise('/app/tabs/home');
});
app.config(
['$ionicConfigProvider', function($ionicConfigProvider) {
$ionicConfigProvider.tabs.position('bottom');
$ionicConfigProvider.navBar.alignTitle('center');
}]);
After some research it is related to IonTabs and separated ion-nav-views.
(check out this picture : http://ionicframework.com/img/diagrams/tabs-nav-stack.png )
In this case, it is better to replace tabs with custom "tabs" implementation using only one ion-nav-view as shown here : http://codepen.io/ruslan-fidesio/pen/RRgpjL
HTML :
<ion-nav-bar class="bar-positive">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
<better-tabs style="positive">
<better-tab state="app.tabs.home" title="Home"></better-tab>
<better-tab state="app.tabs.themes.list" root-state="app.tabs.themes" title="Themes"></better-tab>
</better-tabs>
JS :
app.directive(
'betterTabs',
function() {
return {
restrict: 'E',
compile: function(elem, attrs) {
var footer = angular.element('<ion-footer-bar></ion-footer-bar>');
var tabs = elem.find('better-tab');
elem.append(footer);
footer.append(tabs);
if (attrs.style) {
footer.addClass('bar-' + attrs.style);
}
}
};
}
);
app.directive(
'betterTab',
['$state', function($state) {
return {
scope: {
state: '#',
rootState: '#',
title: '#'
},
restrict: 'E',
required: ['^betterTabs'],
link: function(scope) {
scope.$state = $state;
},
template: function() {
return '<a ui-sref="{{ state }}" ng-class="{active: $state.includes(\'{{ rootState ? rootState : state }}\')}">{{ title }}</a>';
}
};
}]
);

Can´t disable Back Button (history, cache, ...) in Ionic

I have an app, with a login view that the user needs to put your credentials to login.
This is my index.html:
<!DOCTYPE html>
<html ng-app="starter">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Services for Partners</title>
<link href="lib/ionic/css/ionicons.min.css" rel="stylesheet">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's css and js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/routes.js"></script>
<script src="js/services.js"></script>
<link href="css/app.css" rel="stylesheet">
</head>
<body>
<div>
<ion-nav-view animation="slide-right-left" cache-view="false"></ion-nav-view>
</div>
<div class="bar bar-footer bar-dark">
<div>copyright</div>
</div>
</body>
</html>
In my index.html I am using the attribute cache-view="false".
After the user has logged in, he is redirect to home view.
Here is part of my home view:
<ion-view title="home" ng-controller="homeCtrl">
<div class="bar bar-header bar-dark">
<button class="button button-icon icon ion-gear-b"></button>
<button class="button button-icon icon ion-android-close" ng-click="closeApp()"></button>
</div>
<ion-content overflow-scroll="true" padding="true" scroll="true" class="has-header has-footer">
<!--<div class="spacer" style="width: 300px; height: 15px;"></div>-->
<div style="text-align:center;">
<img src="img/logo.png" class="logo-pequena">
</div>
<div>
In the home view, I have a button to log out, calling a method closeApp().
Here is my home controller, with my closeApp() method:
starter.controller('homeCtrl', ['$scope', '$state', '$ionicHistory', function($scope, $state, $ionicHistory) {
$scope.closeApp = function() {
//Remove todos as infos do usuário do localStorage
localStorage.clear();
$ionicHistory.clearHistory();
$ionicHistory.clearCache();
$ionicHistory.nextViewOptions({
historyRoot: true,
disableAnimate: true,
disableBack: true
});
$state.go('login');
}
}]);
Here we can see that I am using several commands to disable ionic history.
Below, is my services.js file:
var starter = angular.module('starter.services', []);
starter.run(function($ionicPlatform,$state,$ionicHistory){
$ionicPlatform.registerBackButtonAction(function (event) {
if($state.current.name=="home"){
navigator.app.exitApp();
}
else {
$ionicHistory.backHistory();
}
}, 100);
});
Here is my route.js file:
var starter = angular.module('starter.routes', []);
//Rotas do app
starter.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider //.state(...).state(...).state(...)
//Login
.state('login', {
url: '/login',
cache: false,
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
})
//Novo Usuário
.state('newuser', {
url: '/newuser',
cache: false,
templateUrl: 'templates/newuser.html',
controller: 'newUserCtrl'
})
//Esqueceu a senha
.state('forgotpwd', {
url: '/forgotpwd',
cache: false,
templateUrl: 'templates/forgotpwd.html',
controller: 'forgotPwdCtrl'
})
//Sobre
.state('about', {
url: '/about',
cache: false,
templateUrl: 'templates/about.html',
controller: 'aboutCtrl'
})
//Home
.state('home', {
url: '/home',
cache: false,
templateUrl: 'templates/home.html',
controller: 'homeCtrl'
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/login');
}]);
Here I have configured all routes to not caching any view.
After all those stuffs nothing happens. My app still permits me click on back button (not a hardware button, but the software button). I am previewing my app on "Ionic View App" running in my Sony Z3 smartphone.
So, the user can go back to home page, without logging in.
I want to exit app if the user clicks the back button at login view. But after all those configurations, I am still running with this trouble.
What I need to do ?
I have already updated cordova and ionic. Is it a bug or is it possible to resolve this issue ?
Thanks.
Why don't you try this
///code to skip login page if logged in
.run(function ($rootScope, $state) {
// Check login session
$rootScope.$on('$stateChangeStart', function (event, next, current) {
if(condition to check that you are logged in..maybe store token in localstorage and heck){
if (next.name === "login") {
event.preventDefault();
$state.go('home');
}
}
});
})
for back button action
.run(['$rootScope', '$ionicPlatform','$state', '$ionicHistory',
function($rootScope, $ionicPlatform,$state, $ionicHistory){
$ionicPlatform.registerBackButtonAction(function(e){
if ($state.current.name == 'home') {
ionic.Platform.exitApp();
}
else if ($ionicHistory.backView() ) {
$ionicHistory.goBack();
}
e.preventDefault();
return false;
},101);
}])

Ionic templates folder not show anything

I've started to learn ionic framework recently. I created below files, but result is blank page. nothing shows in the developer tools in Google Chrome too.
app.js
var app = angular.module('sheikhsafi', ['ionic']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('index', {
url: '/',
views: {
home: {
templateUrl: 'templates/home.html',
}
}
})
$urlRouterProvider.otherwise('/')
});
app.controller('HomeController', function ($scope, $stateParams) {
})
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="sheikhsafi">
<ion-nav-view></ion-nav-view>
</body>
</html>
templates/home.html
<script id="templates/home.html" type="text/ng-template">
<ion-view title="Home">
<ion-content>
<ion-pane>Hi</ion-pane>
</ion-content>
</ion-view>
<script>
what's the problem?
Working plunker.
Wrong code in config section of app.js. The correct is:
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/',
templateUrl: 'templates/home.html'
});
$urlRouterProvider.otherwise('/')
})
instead of your:
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('index', {
url: '/',
views: {
home: {
templateUrl: 'templates/home.html',
}
}
})
$urlRouterProvider.otherwise('/')
});
In your case you're trying to add to home view a template, that has sense when you have an abstract view. Take a look to the ionic-starter-sidemenu, that could be a nice way to discover some things.
Also, if you're learning ionic, please read the getting started guide, and use one of them ready-made app templates.

Ionic - Showing side-menu ONLY in concrete pages

I'm developing an App with Ionic Framework, and I only want to show a side-menu in some concrete views, but not in every view.
I' have my menu.html file:
<ion-side-menus>
<ion-pane ion-side-menu-content>
<ion-nav-bar class="bar-positive nav-title-slide-ios7">
</ion-nav-bar>
<ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view>
</ion-pane>
<ion-side-menu side="left">
<ion-content class="mymenu">
<div id="menu-list">
<ion-list class="list">
<ion-item item-type="item-icon-left" nav-clear menu-close href="#">
<i class="icon ion-home"></i><span>Menu Item</span>
</ion-item>
...
</ion-list>
</div>
</ion-content>
</ion-side-menu>
</ion-side-menus>
My index.html's body tag looks exactly like this:
<body ng-app="myApp">
<ion-nav-view></ion-nav-view>
</body>
And the JavaScript code where I set up my App states:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.page1', {
url: "/page1",
views: {
'menuContent' :{
templateUrl: "templates/page1.html"
}
}
})
.state('app.page2', {
url: "/page2",
views: {
'menuContent' :{
templateUrl: "templates/page2.html"
}
}
})
// etc...
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/page1');
});
page1.html and page2.html both contain the following structure:
<ion-view title="something">
<ion-content>
... // here comes the html content of the page
</ion-content>
</ion-view>
What can I actually do to only show my side-menu (menu.html) on page1.html and not on page2.html?? Is there anything I'm missing??
Is there a way of inserting the menu.html content only on those pages I want it to appear and forgetting about creating the state that uses it as templateUrl?
The reason why your all your pages have side menu is because you 'app' state as their parent state. When a state is activated, its templates are automatically inserted into the <ion-view> of its parent state's template. If it's a top-level state, because it has no parent state then its parent template is index.html. The app state has the side menu in it.
Your code should look like this:
config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
//this state has the 'app' state (which has the sidemenu) as its parent state
.state('app.page1', {
url: "/page1",
views: {
'menuContent' :{
templateUrl: "templates/page1.html"
}
}
})
//this state has no parent, so it uses 'index.html' as its template. The index page has no
//sidemenu in it
.state('page2', {
url: "/page2",
templateUrl: "templates/page2.html"
}
})
///more code here
});
Check out https://github.com/angular-ui/ui-router/wiki
if your problem is simple , use
onExit: function(){
angular.element(document.querySelector('#menuAPP')).removeClass('hidden');
}
into state
just add hide-nav-bar=" true " in ion-view
<ion-view title="Login" **hide-nav-bar="true"** id="page" class=" "> </ion-view>