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

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);
}])

Related

error firebase and angularfire in ionic

I installed firebase and angularfire with bower bower.
I included the files and angularfire but I get these errors:
When I click error on the file angularfire
code app.js
var app = angular.module('myApp', ['ui.router','ionic','firebase'])
.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();
}
});
})
app.config(['$stateProvider','$urlRouterProvider', function($stateProvider,$urlRouterProvider) {
$stateProvider.state("home",{ url : "/home", templateUrl : "templates/home.html" , controller: "HomeCtrl"});
$stateProvider.state("Inscription",{ url : "/inscription", templateUrl : "templates/inscription.html" , controller: "InscriCtrl"});
$stateProvider.state("listmsg",{ url : "/listmsg", templateUrl : "templates/list.html" , controller: "ListCtrl"});
$stateProvider.state("msg",{ url : "/msg", templateUrl : "templates/msg.html" , controller: "MsgCtrl"});
$urlRouterProvider.otherwise("home");
}]);
app.controller('HomeCtrl', [,'$firebaseSimpleLogin',function($scope,$firebaseSimpleLogin) {
var firebaseObj = new Firebase("https://appsfactor-68466.firebaseio.com");
var loginObj = $firebaseSimpleLogin(firebaseObj);
$scope.SignIn = function(event) {
event.preventDefault();  // To prevent form refresh
var username = $scope.user.email;
var password = $scope.user.password;
loginObj.$login('password', {
email: username,
password: password
})
.then(function(user) {
// Success callback
console.log('Authentication successful');
}, function(error) {
// Failure callback
console.log('Authentication failure');
});
}
}]);
app.controller('InscriCtrl', [function() {
}]);
app.controller('ListCtrl', [function() {
}]);
app.controller('MsgCtrl', [function() {
}]);
code 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 rel="manifest" href="manifest.json">
<!-- un-comment this code to enable service worker
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.log('Error', err));
}
</script>-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link rel="icon" href="http://getbootstrap.com/favicon.ico">
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="http://getbootstrap.com/examples/signin/signin.css" rel="stylesheet">
<!-- AngularFiionic servere -->
<script src="lib/firebase/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "myapi",
authDomain: "appsfactor-68466.firebaseapp.com",
databaseURL: "https://appsfactor-68466.firebaseio.com/",
storageBucket: "gs://appsfactor-68466.appspot.com",
};
firebase.initializeApp(config);
</script>
<script src="lib/angularfire/dist/angularfire.js"></script>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/ionic/js/angular-ui/angular-ui-router.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js" ></script>
</head>
<body ng-app="myApp">
<ion-side-menus>
<ion-side-menu-content>
<ion-nav-bar class="bar-calm">
<ion-nav-buttons>
<button menu-toggle="left" class="button button-icon ion-navicon">
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view>
</ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-item menu-close ui-sref="home">Acceuil</ion-item>
<ion-item menu-close ui-sref="Inscription">Inscription</ion-item>
<ion-item menu-close ui-sref="listmsg">Listes Messages</ion-item>
<ion-item menu-close ui-sref="msg">Message</ion-item>
</ion-side-menu>
</ion-side-menus>
</body>
</html>

Ionic ng-click will be executed after on-hold

I have a problem with elements which has the ng-click and on-hold property. The problem is after on-hold event the ng-click event will be executed.
I think this is a common issue and I hope there is a solution for this.
Example:
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.min.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.min.js"></script>
<script src="js/ListCtrl.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-nav-bar class="bar-positive">
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>
list.html
<ion-view view-title="Test">
<ion-content>
<ion-list show-delete="data.deleteMode">
<ion-item class="item-icon-right"
ng-repeat="item in items track by $index"
on-hold="data.deleteMode = ! data.deleteMode;"
ng-click="onClick(item)">
<ion-delete-button class="ion-trash-a" ng-click="onRemoveTaskBtn(task)"></ion-delete-button>
<p>{{item.text}}</p>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
app.js
angular.module('starter', [
'ionic',
'starter.list'
]).run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
});
}).config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/list');
});
ListCtrl.js
angular.module('starter.list', [])
.config(function ($stateProvider) {
$stateProvider.state('list', {
url: '/list',
templateUrl: 'js/list.html',
controller: 'ListCtrl'
});
}).controller('ListCtrl', [
'$scope',
function ($scope) {
$scope.data = {
deleteMode : false
};
$scope.items = [
{ text : 'Text 1' },
{ text : 'Text 2' },
{ text : 'Text 3' },
{ text : 'Text 4' },
{ text : 'Text 5' }
];
$scope.onClick = function(item) {
console.log('Clicked on item with text: ' + item.text);
}
}
]);
Just found exactly the same problem.
The solution is to use the on-tap instead of the ng-click.
For what I've seen, Ionic classifies its events on tap duration and stop propagating the event to its own listeners. Since ng-click is not a Ionic event, the event will be propagated.

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>';
}
};
}]
);

Multiple views in blank ionic app

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) {
});

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.