Is there a way to show a confirmation popup when you press the hardware back button in android devices to exit the phonegap/ionic application?
In the current status, my app keep going to the previous state upon clicking the back button.
Is there a way to exit the app when you press the back button no matter where you are on, in the application?
I found this piece of code but it did not seem to work:
$ionicPlatform.registerBackButtonAction(function() {
var confirmPopup = $ionicPopup.confirm({
title: 'Sign Out Confirm',
template: 'Are you sure you want to Logout?'
});
confirmPopup.then(function(res) {
if (res) {
$rootScope.rootScopeUserTransactionPassword = null;
$state.go('app.playlists');
} else {
console.log('You are not sure');
}
});
}, 100);
Try this:
document.addEventListener('backbutton', function(event){
event.preventDefault(); // EDIT
navigator.app.exitApp(); // exit the app
});
I hope it helps you.
It will ask you before exit in stipulated timestamp : Press back button again to exit. If it's dashboard page then it will ask whether to Log out?
I hope it will solve your problem.
.run(function($rootScope, $ionicPlatform, $ionicHistory){
$ionicPlatform.registerBackButtonAction(function(e) {
if ($ionicHistory.currentView().stateName == 'dashboard') {
Dialogs.showConfirm('Do you want to logout?', function(buttonIndex) {
if (buttonIndex == 1)
User.clear();
}, 'Logout', ['Yes', 'No']);
} else
if ($rootScope.backButtonPressedOnceToExit) {
ionic.Platform.exitApp();
} else if ($ionicHistory.backView()) {
$ionicHistory.goBack();
} else {
$rootScope.backButtonPressedOnceToExit = true;
window.plugins.toast.showShortCenter(
"Press back button again to exit",
function(a) {},
function(b) {}
);
setTimeout(function() {
$rootScope.backButtonPressedOnceToExit = false;
}, 2000);
}
e.preventDefault();
return false;
}, 101);
});
The following close the app if we hit back button on Android device in "Login" screen.
In your app.js you maybe have something like this:
app.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$stateProvider.state('login', {
url : '/',
}).state('login', {
url : '/login',
views : {
contentView : {
templateUrl : 'login.html',
controller : 'LoginCtrl'
}
}
});
So all you have to do is add this method in the same file:
app.run(function($ionicPlatform) {
$ionicPlatform.registerBackButtonAction(function() {
if ($state.current.name == "login") {
navigator.app.exitApp();
}
}, 100);
});
Note that "login" it the state name which mentioned in the app.config
Related
I have an ionic 3 application and I modified the functionality of the hardware back button. It works on pages but it cannot determine whether overlay views like modals and alert dialog boxes are present or not.
Here is my code
this.platform.registerBackButtonAction(() => {
let nav = app._appRoot._getActivePortal() || app.getActiveNav();
let activeView = nav.getActive().instance;
if (activeView != null) {
if (nav.canGoBack()) {
if (activeView instanceof MultiRegistrationOne || activeView instanceof MultiRegistrationTwo || activeView instanceof MultiRegistrationThree) {
// do something
} else {
nav.pop();
}
} else if (activeView.isOverlay) {
activeView.dismiss();
} else {
let alert = this.alertCtrl.create({
title: 'Ionic App',
message: 'Do you want to close the app?',
buttons: [{
text: 'Cancel',
role: 'cancel',
handler: () => {
console.log('Application exit prevented!');
}
},
{
text: 'Close',
handler: () => {
this.platform.exitApp();
}
}]
});
alert.present();
}
}
});
I hope someone can help me with this. Thank you in advance š
declare a variable :viewController:ViewController
then in your page or app.components.ts , modify your back button handle to be like the
this.platform.registerBackButtonAction(() => {
try{
this.viewController.dismiss()
}
catch(e){
console.log("error");
}
});
I solved it using MD. Riyas' answer here: Solution
LoginScreen.js
this.props.navigator.push({
screen: "auxxa.LandingScreen",
passProps: { login: true },
overrideBackPress: true,
navigatorStyle: {
navBarHidden: true
}
});
LandingScreen.js
constructor(props) {
super(props);
this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
// this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
this.state = {
size: { width, height },
tileData: null,
isLoading: true,
user_id: null,
refetching: false,
access_token: null
};
}
componentWillMount() {
BackHandler.addEventListener(
"hardwareBackPress",
this.handleBackButtonClick
);
}
handleBackButtonClick() {
console.log("check login " + this.props.login);
if (this.backPressed && this.backPressed > 0) {
if (this.props.login) {
console.log("login");
RNExitApp.exitApp();
} else {
console.log("root");
this.props.navigator.popToRoot({ animated: false });
return false;
}
}
this.backPressed = 1;
this.props.navigator.showSnackbar({
text: "Press one more time to exit",
duration: "long"
});
return true;
}
componentDidMount() {
BackHandler.removeEventListener(
"hardwareBackPress",
this.handleBackButtonClick
);
}
I used react-native-navigation from Wix for my app nevigation purpose.Here I have attached login screen and landing screen.after successful login app navigate to landing screen.after that I click back button It will return to login screen.I need to avoid that.How can I do that thing? I tried to exit from the app.But it also not working properly.
Please help me if some one know this.Thanks in advanced.
Use this call in handleBackButtonClick function and why are you removing the listener in componentDidMount ?
this.props.navigator.resetTo({ screen: 'example.ScreenThree'})
.
Uncomment this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this)); on your constructor to listen to navigation events
and add the navigationEvent listener method
onNavigatorEvent(event: NavigatorEvent) {
if (event.type === 'NavBarButtonPress') {
if (event.id === 'skill_information') {
// Add here whatever you would like to do (this.handleBackButtonClick() for example)
}
}
I try to listen android hardware back button,but it is no effect.
main code:
.run(['$ionicPlatform','$ionicHistory',function($ionicPlatform,$ionicHistory) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
$ionicPlatform.registerBackButtonAction(function (e) {
e.preventDefault();
$ionicHistory.nextViewOptions({
disableAnimate: true
});
$ionicHistory.viewHistory().backView.go();
return false;
}, 100);
}])
My running environment is mobile browser.Android version 4.4.2
UPDATE: I'm no longer using this as it was unreliable. Additionally, in the latest Ionic release, app.ts is now app.component.ts.
For Ionic 2, check out my blog post on how to fix this. Should also work for Ionic 1, as it's only calling a cordova listener:
http://www.codingandclimbing.co.uk/blog/ionic-2-android-back-button-13
and here's the actual post info:
In your app.ts, do the following to get the back button working as expected (mostly!):
initializeApp() {
this.platform.ready().then(() => {
this.registerBackButtonListener();
});
}
registerBackButtonListener() {
document.addEventListener('backbutton', () => {
var nav = this.getNav();
if (nav.canGoBack()) {
nav.pop();
}
else {
this.confirmExitApp(nav);
}
});
}
confirmExitApp(nav) {
let confirm = Alert.create({
title: 'Confirm Exit',
message: 'Really exit app?',
buttons: [
{
text: 'Cancel',
handler: () => {
console.log('Disagree clicked');
}
},
{
text: 'Exit',
handler: () => {
navigator.app.exitApp();
}
}
]
});
nav.present(confirm);
}
getNav() {
return this.app.getComponent('nav');
}
Note:
If you get errors about app not being a property of navigator:
1) Add a typings folder to your app root: e.g. app/typings
2) Add a file called: pluginshackyhacky.d.ts
3) Add for properties you need extended for TypeScript to compile.:
interface /*PhoneGapNavigator extends*/ Navigator {
app: any;
}
4) Add the pluginshackyhacky.d.ts to the compile in the tsconfig.json:
"files": [
"app/app.ts",
"app/typings/pluginshackyhacky.d.ts",
"app/typings/phonegap.d.ts"
]
You can see that I've also included the phonegap.d.ts file which includes a lot of missing properties/variables that allows TypeScript to compile without errors.
Hope this helps anyone having this problem.
Cheers.
may be this could help you.
$state.$current.name == "";var backbutton=0;
$ionicPlatform.registerBackButtonAction(function (event) {
if (($state.$current.name == "app.intro") ||
($state.$current.name == "app.main.home") ||
($state.$current.name == "app.account")) {
if(backbutton==0){
backbutton++;
window.plugins.toast.showLongBottom('Press again to exit');
$timeout(function(){backbutton=0;},3000);
}else{
navigator.app.exitApp();
}
console.log("one");
}else if($state.$current.name == "app.welcome.takeControl") {
console.log("two");
$state.go("app.main.home");
}else{
console.log("three");
navigator.app.backHistory();
}
}, 100);
I'm developing using IONIC framework. I'm having trouble with the hardware back button.
In android the hardware back button works perfectly, but the windows phone did not work out.
When I use the back button on windows phone minimizes the application and returns the device's home.
This function only works on android:
$ionicPlatform.registerBackButtonAction(function () {
console.log("Not work in WP");
}, 100);
help !!
I found solution.
In site
https://www.hoessl.eu/2014/12/on-using-the-ionic-framework-for-windows-phone-8-1-apps/
have a post calling -> Not fixed yet: Back Button
Not fixed yet: Back Button
With Windows Phone 8.0, listening on the ābackbuttonā event was pretty
simple, just as with android. On WP8.1, this event is not triggered
anymore. I havenāt figured out how to enable it yet. Any hint would be
appreciated.
But a user commented the solution. follows the passage that worked in
my case
Back Button Fix :
Set your $ionicPlatform.registerBackButtonAction
$ionicPlatform.registerBackButtonAction(function (evt) {
if (evt && evt.type == ābackclickā) {
$ionicHistory.goBack();
return true;
}
}, 100);
Hookin WinJS and send it to Ionic :
if(ionic.Platform.isWindowsPhone)
{
WinJS.Application.onbackclick = function (evt) {
$ionicPlatform.hardwareBackButtonClick(evt);
return true;
}
}
Easy Fix, long time figuring it out
Example for placing the code inside app.js
angular.module('starter', ['ionic', 'starter.menu', 'starter.services'])
.run(function ($ionicPlatform, $ionicHistory, $state, ...) {
$ionicPlatform.registerBackButtonAction(function (evt) {
if (evt && evt.type == 'backclick') {
$ionicHistory.goBack();
return true;
}
}, 100);
...
$ionicPlatform.ready(function () {
...
if (ionic.Platform.isWindowsPhone()) {
WinJS.Application.onbackclick = function (evt) {
if ($state.current.name == 'app.home') {
//function responsible for exiting the application in Windows phone 8.1
cordova.exec(null, null, "ExitApp", "execute", []);
} else {
$ionicPlatform.hardwareBackButtonClick(evt);
return true;
}
}
}
}); ...
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl',
onEnter: function ($state, UserService) {
console.log("##### - " + UserService.get().isLogged);
if (UserService.get().isLogged) {
$state.go("app.home");
}
}
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'MenuCtrl'
})
.state('app.secretary', {
url: '/secretary',
views: {
'menuContent': {
templateUrl: 'templates/secretary/menusecretary.html',
controller: 'MenuSecretaryCtrl'
}
}
})
I have a form and there is a button that submits it. I wish that submit would be executed only on tap on 'Register' button. But when user inputs some text in any textfield and presses "Go" (aka "Enter") button. The form submits and I can do nothing about it.
This behavior is noticed on Samsung Galaxy S (GT i9000) on Android v2.3.6. But HTC with Android 4 behaves as I wish.
The submitOnAction:false doesn't help.
beforesubmit too. Any of solutions in code listing don't work.
I just don't want the form to submit in any other way except pressing 'Register' button!
File /view/userRegistration/FormPanel.js
Ext.define('My.view.userRegistration.FormPanel', {
extend: 'My.view.components.FormPanel',
xtype : 'userRegistrationForm',
config: {
standardSubmit : false,
submitOnAction : false,
listeners: {
beforesubmit: function(form, values, options, eOpts){
console.log('before submit fired');
return false; // returning false doesn't help
},
'> field': {
keyup: function(fld, e){
//13 = user tapped 'return' button on keyboard
//10 = user tapped 'hide keyboard' on keyboard
if (e.browserEvent.keyCode == 13 || e.browserEvent.keyCode == 10) {
e.stopEvent();
fld.element.dom.blur();
}
}
}
},
items : [
{
xtype: 'textfield',
name : 'firstName',
required: true,
listeners: {
action: function(field, e, eOpts) {
e.stopEvent();
return false;
},
keyup: function(field, e) {
if (e.browserEvent.keyCode == 13 || e.browserEvent.keyCode == 10) {
// GO pressed on "firstName"
e.stopEvent();
field.element.dom.blur();
return false;
}
}
}
},
{
xtype: 'button',
text : 'Register',
listeners: {
tap: function(button) {
var form = button.parent;
if (form.isValid()) {
form.onSubmit();
}
}
}
}
]
}
});
File /view/components/FormPanel.js
Ext.define('My.view.components.FormPanel', {
extend : 'Ext.form.Panel',
onSubmit: function() {
var fieldValues = this.getValues();
// Sending fieldValues via AJAX
},
isValid: function(args) {
// Validating values
}
});
The problem was in the onSubmit() method. It is #private in sencha-touch-all-debug.js:
Ext.define('Ext.form.Panel', {
// #private
onSubmit: function(e) {
var me = this;
if (e && !me.getStandardSubmit()) {
e.stopEvent();
} else {
this.submit();
}
}
}
So it is absolutely incorrect to override onSubmit() in child classes. More correct way.
File /view/components/FormPanel.js
Ext.define('My.view.components.FormPanel', {
extend : 'Ext.form.Panel',
config: {
standardSubmit: false,
listeners: {
beforesubmit: function(form, values, options, eOpts) {
// Do something with data. Send it via AJAX, for example
return false; // returning false to prevent real form.submit();
}
}
}
}
And the button in the form should just call form.submit();.
File /view/userRegistration/FormPanel.js
{
xtype: 'button',
text : 'Register',
handler: function() {
var form = button.parent;
if (form.isValid()) {
form.submit();
}
}
}
You don't really need to override the FormPanel for that. In the controller, you can just prevent the action from field to execute and bubble up.
Ext.define('TestApp.controller.Login', {
extend: 'Ext.app.Controller',
config: {
control: {
'field': {
action: 'onFieldAction'
}
}
},
onFieldAction: function(field, e) {
// Stop event here
e.stopEvent();
e.stopPropagation();
}
});
There is a gotcha that i encountered while doing this. I've accidentally overridden the default initialize function of my FormPanel. Every thing will not work if you do this
Ext.define('TestApp.view.Login', {
extend: 'Ext.form.Panel',
xtype: 'loginform',
config: {
...
}
initialize: function(config) {
this.callParent(arguments); // Nothing will work without this line
...
}
});
Just in case someone needs to disable the Enter key on keyboard or the Go button in the softkeyboard, I found the following solution:
Ext.define('App.view.Login', {
extend: 'Ext.form.Panel',
xtype: 'login',
config: {
....
},
getElementConfig: function() {
var config = this.callParent();
config.children.pop();
return config;
}
});
document.addEventListener("keypress", onGoKeyDown, false);
function onGoKeyDown(e) {
console.log(e);
if(e.srcElement.localName == 'input') {
if (e.keyCode === 13 || e.keyCode === 10) {
e.preventDefault();
}
}
}
I don't know if anyone is still looking for a solution, but I came up with a very simple trick - trap the input and prevent the form submission even if the user hits 'Go' or any button/key other than the one you want. To do that just place a listener in every entry field and listen for the 'blur' event. This will trap any action when leaving the field (blur). Inside the blur listener event do a focus() on the next field (like tabbing through the form, i.e. if you are in field 1 send the focus to 2 and so on) until you arrive at your desired submit or register button. Once there, you can do your processing, submit, etc. This worked for me!
Now, if we want to call Ajax method on submit by either clicking Submit button or by enter action then,
submitOnAction : true in the FormPanel config
Add this.callParent(arguments)in initialize method in case we are overriding initialize method of FormPanel
Override submit method of FormPanel to add Ajax Call
Listen to tap event of Submit button to add Ajax Call