I want my modal pops up (with backdrop) rather than a new page. I followed some tutorials but the backdrop is not working (it should be activated by default). I am sure I am missing something.
Here the code from the page where the modal is opened.
openPhonesModal(){
const myModalOptions: ModalOptions = {
showBackdrop: true,
enableBackdropDismiss: false
};
const myModalData = {
phone1: '01 239 239',
phone2: '901 200 438'
};
const myModal: Modal = this.modal.create('ModalseephonesPage',{phones:
myModalData},myModalOptions);
myModal.present();
}
Here the code of the modal itself:
export class ModalseephonesPage {
constructor(private navParams: NavParams, private view: ViewController) {
}
ionViewWillLoad() {
const phones = this.navParams.get(‘phones’);
console.log(phones);
}
closeModal(){
this.view.dismiss();
}
}
I hope I provided enough information.
Thank you in advance.
Related
My problem is quite simple : I try to implement a component in modal, but when I try to add SwipeToClose, it's not working (The modal stay static even if I try to swipe down) ...
I'm really confused, but I've create a Stackblitz to show you my issue in detail, maybe I miss something important ... : https://stackblitz.com/edit/ionic-angular-v5-u4wmun
My component :
import { Component, Injectable } from '#angular/core';
import { NavController, ModalController } from '#ionic/angular';
import { ModalComponent } from './modal/modal.component';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myModal:any;
constructor(
public modalController: ModalController
) {
}
async presentModal() {
this.myModal = await this.modalController.create({
component: ModalComponent,
swipeToClose: true,
backdropDismiss: true
});
return await this.myModal.present();
}
}
Thanks to your time !
PS : I try to use it in iOS only, I've already try on my iOS device and it's doesn't work too ...
swipe to close is only available for modals in ios mode(currently ionic v5). So, specify the mode of your modal to be ios
this.myModal = await this.modalController.create({
component: ModalComponent,
swipeToClose: true,
mode: 'ios',
backdropDismiss: true
});
SwipeToClose Gesture only works on IOS mode and could be applied on card modals and will be deprecated by next release. If you apply following method to IonContent element or first element in body, it detects swipeDown gesture and kinda solves that issue and works with all modes.
constructor(public gestureCtrl: GestureController) { }
swipeDownToCloseModal = (elm: HTMLElement)=>{
const swipeGesture: Gesture = this.gestureCtrl.create({
el:elm,
threshold:1,
maxAngle:95,
gestureName:'swipeGesture',
onEnd:e=>{
if(e.velocityY>0.15 && e.deltaY>100 && elm.getBoundingClientRect().y===0){
this.modal.dismiss(); //change
}
}
});
swipeGesture.enable(true);
};
I have a Modal in Ionic 4. I'd like to close it, when a user press the back button on her mobile (or the back button in her browser).
Does anyone know how I can do this?
EDIT: More details:
I have a button that opens my modal:
async onClick() {
const modal = await this.modalController.create({
component: Foo,
});
return await modal.present();
}
Component Foo doesn't have much more content than a button that closes the modal: this.modalController.dismiss();. So far so good.
On my mobile, however, the app now closes when the modal is open and the user taps the mobile's back button. But in this case only the modal should close.
Enol's answer helped me find a solution, thanks for that.
platform.registerBackButtonAction does no longer exist in v4. I tried platform.backButton.subscribe instead, but it didn't work. What works is this:
private backbuttonSubscription: Subscription;
constructor(private modalCtrl: ModalController) {
ngOnInit() {
const event = fromEvent(document, 'backbutton');
this.backbuttonSubscription = event.subscribe(async () => {
const modal = await this.modalCtrl.getTop();
if (modal) {
modal.dismiss();
}
});
}
ngOnDestroy() {
this.backbuttonSubscription.unsubscribe();
}
You can use the registerBackButtonAction method that Platform service contains. This method allows override the default native action of the hardware back button. The method accepts a callback function as parameter where you can implement your logic. In summary you should do the following:
Inject the Platform service inside the Foo component.
Call the registerBackButtonAction in the ngOnInit (or another init method) and pass a function callback as parameter that executes the logic to close the modal (this.modalController.dismiss();)
Clear the action when the modal component is closed (for example in ngOnDestroy method). To do that, the registerBackButtonAction returns a function that when is called the action is removed.
The code should be something like:
constructor(private platform: Platform) {
...
}
ngOnInit() {
this.unregisterBackAction = this.platform.registerBackButtonAction(() => {
this.modalController.dismiss();
})
}
ngOnDestroy() {
if(this.unregisterBackAction) this.unregisterBackAction();
}
For ionic 5 user
this.platform.backButton.subscribeWithPriority(999, async() => {
if (this.modalCtrl.getTop()) {
const modal = await this.modalCtrl.getTop();
console.log(modal)
if (modal) {
this.modalCtrl.dismiss();
return;
} else {
if (this.router.url=="/myrootpage" ) {
navigator['app'].exitApp();
} else {
this.navCtrl.pop();
}
}
} else {
if (this.router.url=="/myrootpage") {
navigator['app'].exitApp();
} else {
this.navCtrl.pop();
}
}
});
Yes, are almost on the way....
you just need to change in HTML part. I did in this way.
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button color="dark" (click)="closeModal()">
<ion-icon name="arrow-back"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title>Create Pin</ion-title>
</ion-toolbar>
</ion-header>
after this, you just need to create a function that will close your modal popup.
in your ts file
closeModal() {
this.modalCtrl.dismiss();
}
I hope that will help you.
Based on the initial answer by Markus, You can decide to; Instead of unsubscribing after each back button event. You may want to listen to back-button events globally in your application and only call exit on specific pages.
import { fromEvent } from "rxjs"; // import fromEvent from rxjs
import { Router } from "#angular/router"; // import angular router as well
import { Location } from "#angular/common"; // import location from angular common
constructor(private router: Router, private location: Location) {
// Call the function when the app initializes at app.component.ts. it will watch for
// back button events globally in the application.
this.backButtonEvent();
}
// Function to present the exit alert
async exitAlert() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: "Are you sure you want to exit the app?",
buttons: [
{
text: "Cancel",
role: "cancel",
cssClass: "secondary",
handler: blah => {}
},
{
text: "Close App",
handler: () => {
navigator["app"].exitApp();
}
}
]
});
await alert.present();
}
// function to subscribe to the backbutton event
backButtonEvent(): void {
const event = fromEvent(document, "backbutton");
event.subscribe(async () => {
// When the current route matches a specific page/route in the app where u
// want to exit on back button press.
// else assume the user wants to navigate to a previous page
if(this.router.url === "<example page-url to exit from>") { this.exitAlert()
}
else { this.location.back() }
});
}
Update, for Ionic 5 (Angular)
in your-modal.page.ts
import { ModalController } from '#ionic/angular';
at the top of your modal's .ts file. Then in your constructor you can just denote a -public- relationship to the controller, that way it's accessible by your view.
also in your-modal.page.ts
constructor(
public modalCtrl: ModalController
) {}
Now you can inline the close command:
in your-modal.page.html
<ion-header color="dark">
<ion-toolbar color="dark">
<ion-title>Modal Title</ion-title>
<ion-buttons slot="primary">
<ion-button (click)="modalCtrl.dismiss()">
<ion-icon slot="icon-only" name="close"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
Slot "primary" makes the buttons move to the right in iOS.
You can also use the built in function of ionic which is
<ion-back-button>
</ion-back-button>
You can also position the <ion-back-button> to start or end
<ion-buttons slot="start">
<ion-back-button>
</ion-back-button>
</ion-buttons>
for more information about <ion-back-button>
Here's a link
I am developing an ionic app with a side menu.
In my app, i added a modal that contains three button. When i click on any button in that modal, it opens a new page. On that new page, i have header containing a button that is used to open the side menu.
Problem
Side menu opens normally on any page that isn't opened via buttons on modal but when i try to open the side menu on a page that was opened via button on a modal, instead of opening the side menu on that page, it opens the side menu behind the current page and when i press back button to go back to previous page, side menu can be seen opened on the previous page.
Question
What is causing this behavior and how can i fix it ?
Custom Modal typescript code
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, ViewController } from 'ionic-angular';
import { LibraryPageSerice } from './libraryPage.service';
#IonicPage()
#Component({
selector: 'page-custom-posting-pop-up',
templateUrl: 'custom-posting-pop-up.html',
})
export class CustomPostingPopUpPage {
onLibraryPage: boolean;
constructor(private navCtrl: NavController, private navParams: NavParams,
private viewCtrl: ViewController,
private libService: LibraryPageSerice) {}
ionViewDidLoad() {
this.onLibraryPage = this.libService.onLibraryPage;
}
dismissModal(event) {
if(event.target.className === 'modal-container') {
this.viewCtrl.dismiss();
}
}
openCreationpage() {
this.viewCtrl.dismiss();
this.navCtrl.push('PostingCreationPage');
}
openSupportivePage() {
this.viewCtrl.dismiss();
this.navCtrl.push('PostingSupportivePage');
}
openLibraryPage() {
this.viewCtrl.dismiss();
this.navCtrl.push('MylibraryPage');
}
}
Custom modal html code
<div class="modal-container" (click)="dismissModal($event)">
<div class="modal">
<p>Posting Method</p>
<div class="btn-container">
<button class="creation-btn" (click)="openCreationpage()">My Creation</button>
<button class="supportive-btn" (click)="openSupportivePage()">Supportive</button>
<button *ngIf="!onLibraryPage" class="library-btn" (click)="openLibraryPage()">
My Library
</button>
</div>
</div>
</div>
This method is used to open the modal
posting() {
const modal = this.modalCtrl.create('CustomPostingPopUpPage');
modal.present();
}
If i don't use the modal and instead use an alert dialog to open the new page, side menu opens normally. So this problem only arises when i use a modal.
This is part of how modals are defined to work, "A Modal is a content pane that goes over the user's current page ... A modal uses the NavController to present itself in the root nav stack"
Because of this when you are calling this.navCtrl.push('PageName'); this instance of NavController is an Overlay Portal whereas a normal NavController not from a modal is a Nav. This will cause the page to be pushed along side your app-root (Which causes the results that you are witnessing).
Here are two solutions to this.
Pass in reference of NavController to your modal using NavParams
// home.ts
let modal = this.modalCtrl.create('ModalPage', {'nav': this.navCtrl});
// modal.ts
nav: Nav;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public viewCtrl: ViewController) {
this.nav = this.navParams.get('nav');
}
openSupportivePage() {
this.viewCtrl.dismiss();
this.nav.push('PostingSupportivePage');
}
Or pass which page you want to open to viewCtrl.dismiss() and parse with onDidDismiss
// home.ts
modal.onDidDismiss((open_page) => {
if (open_page !== undefined && open_page.hasOwnProperty('open_page')) {
this.navCtrl.push(open_page['open_page']);
}
});
// modal.ts
openCreationpage() {
this.viewCtrl.dismiss({'open_page': 'PostingCreationPage'});
}
I have a problem that if a user opens the app and then press the home button or switching to another apps, and when the push notification arrives, and the user clicked on that notification, my app doesn't open. I am using this plugin in ionic -> https://ionicframework.com/docs/native/push/
It seems that when app is in background, app doesn't open when he clicked the push notification. How can I resolve that problem using that plugin.
here's my app.component.ts
import { Component, enableProdMode } from '#angular/core';
import { Platform, NavController, App } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { Keyboard } from '#ionic-native/keyboard';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HomePage } from '../pages/home/home';
import { Push, PushObject, PushOptions } from '#ionic-native/push';
import { GlobalProvider } from "./global.provider";
import { NotificationDetailsPage } from '../pages/notification-details/notification-details';
enableProdMode();
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
private navCtrl: any;
constructor(
private platform: Platform,
private app:App,
private statusBar: StatusBar,
private splashScreen: SplashScreen,
private keyboard: Keyboard,
private globalVar: GlobalProvider,
private push: Push
) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.navCtrl = this.app.getActiveNav();
this.statusBar.overlaysWebView(false);
this.statusBar.backgroundColorByHexString('#000000');
setTimeout(() => {
this.splashScreen.hide();
}, 500);
this.keyboard.disableScroll(true);
this.initPushNotification();
});
}
initPushNotification() {
const options: PushOptions = {
android: {
icon: 'small-icon',
forceShow: true
},
ios: {
alert: 'true',
badge: true,
sound: 'true'
},
windows: {}
};
const pushObject: PushObject = this.push.init(options);
pushObject.on('notification').subscribe((notification: any) => {
//Notification Display Section
this.navCtrl.push(NotificationDetailsPage, {notifyId:notification.additionalData.id});
});
pushObject.on('registration').subscribe((registration: any) => {
//Register Device ID
let platformName;
if (this.platform.is('android')) {
platformName = 'android';
} else {
platformName = 'ios';
}
this.globalVar.saveDeviceId(registration.registrationId, platformName).subscribe( data => {});
});
pushObject.on('error').subscribe(error => {
console.log('Can\'t send push notification');
});
}
}
How can I handle or trigger this.navCtrl.push when the user clicks on push notification when app is in background? Please help me to resolve this problem. It is almost 3 days and I can't find any solution.
I changed the PushHandlerActivity.kt to it opens the app when click on notification. I added the forceMainActivityReload(false) to force start the app afetr message "Don't Want Main Activity".
Plugin version:
#havesource/cordova-plugin-push#3.0.0
File:
./platforms/android/app/src/main/java/com/adobe/phonegap/push/PushHandlerActivity.kt
./plugins/#havesource/cordova-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.kt
./node_modules/#havesource/cordova-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.kt
From:
if (!dismissed) {
Log.d(TAG, "Is Push Plugin Active: ${PushPlugin.isActive}")
if (!PushPlugin.isActive && foreground && inline) {
Log.d(TAG, "Force Main Activity Reload: Start on Background = False")
forceMainActivityReload(false)
} else if (startOnBackground) {
Log.d(TAG, "Force Main Activity Reload: Start on Background = True")
forceMainActivityReload(true)
} else {
Log.d(TAG, "Don't Want Main Activity")
}
}
To:
if (!dismissed) {
Log.d(TAG, "Is Push Plugin Active: ${PushPlugin.isActive}")
if (!PushPlugin.isActive && foreground && inline) {
Log.d(TAG, "Force Main Activity Reload: Start on Background = False")
forceMainActivityReload(false)
} else if (startOnBackground) {
Log.d(TAG, "Force Main Activity Reload: Start on Background = True")
forceMainActivityReload(true)
} else {
Log.d(TAG, "Don't Want Main Activity (force start)")
forceMainActivityReload(false)
}
}
So the app finally opens when it's closed.
After going through Clear History and Reload Page on Login/Logout Using Ionic Framework
I want to know same question, but for ionic2 using typescript.
On login and logout I need reload the app.ts, because there are classes that run libraries on construct.
it would be basically redirect to home and reload.
Found this answer here, (please note especially the line this.navCtrl.setRoot(this.navCtrl.getActive().component); which is by far the simplest solution that I've come across to reload present page for Ionic 2 & 3 and later versions of Angular (mine is 4), so credit due accordingly:
RELOAD CURRENT PAGE
import { Component } from '#angular/core';
import { NavController, ModalController} from 'ionic-angular';
#Component({
selector: 'page-example',
templateUrl: 'example.html'
})
export class ExamplePage {
public someVar: any;
constructor(public navCtrl: NavController, private modalCtrl: ModalController) {
}
refreshPage() {
this.navCtrl.setRoot(this.navCtrl.getActive().component);
}
}
If you want to RELOAD A DIFFERENT PAGE please use the following (note this.navCtrl.setRoot(HomePage);:
import { Component } from '#angular/core';
import { NavController, ModalController} from 'ionic-angular';
import { HomePage } from'../home/home';
#Component({
selector: 'page-example',
templateUrl: 'example.html'
})
export class ExamplePage {
public someVar: any;
constructor(public navCtrl: NavController, private modalCtrl: ModalController) {
}
directToNewPage() {
this.navCtrl.setRoot(HomePage);
}
}
Ionic 1
I haven't used Ionic 2 but currently i m using Ionic 1.2 and if they are still using ui-router than you can use reload: true in ui-sref
or you can add below code to your logout controller
$state.transitionTo($state.current, $stateParams, {
reload: true,
inherit: false,
notify: true
});
Angular 2
Use
$window.location.reload();
or
location.reload();
You have to implement the CanReuse interface, and override the routerCanReuse to return false. Then, try calling router.renavigate().
Your component should look like this:
class MyComponent implements CanReuse {
// your code here...
routerCanReuse(next: ComponentInstruction, prev: ComponentInstruction) {
return false;
}
}
And then, when you perform login/logout, call:
// navigate to home
router.renavigate()
This is a hack, but it works.
Wrap the logic that follows your template adjustment in a setTimeout and that gives the browser a moment to do the refresh:
/* my code which adjusts the ng 2 html template in some way */
setTimeout(function() {
/* processing which follows the template change */
}, 100);
For ionic 2 it works for me when you force page reload by triggering fireWillEnter on a view controller
viewController.fireWillEnter();
Here is what worked for me to refresh only current page-
I am trying to call refreshMe function when I call onDelete from my view page,
See how my page.ts file looks-
export class MyPage {
lines of code goes here like
public arr1: any;
public arr2: any;
public constructor(private nav: NavController, navParams: NavParams) {
this.nav = nav;
this.arr1 = [];
this.arr2 = [];
// console.log("hey array");
}
onDelete() {
perform this set of tasks...
...
...
refreshMe()
}
refreshMe() {
this.nav.setRoot(MyPage);
}
}
This is just refreshing only current page.
We can also call this function from view if we need as--
<ion-col width-60 offset-30 (click)="refreshMe()">
....
....
</ion-col>
I personally use these three lines to totally refresh a component
let active = this.navCtrl.getActive(); // or getByIndex(int) if you know it
this.navCtrl.remove(active.index);
this.navCtrl.push(active.component);
You can use the ionViewWillLeave() to display your splashscreen while component is reloading and then hide it with ionViewDidEnter() once its loaded.
Hope it helps