I have an ionic2 application with angular2, at one page I inject LoadingController and make use of it, at different location on my app.ts I catch all global http errors and want to display alert so I inject AlertController there .
So having 2 location which can at some point call a modal dialog creation and present it causing a problem that freezes the screen , I believe it is because there are 2 modals being open one on the other.
Is there any chance I can grab the current dialog and close it, or add param to create which closes any background modal ?
This is my code:
export class SandboxPage implements OnInit {
private _loadingModel;
constructor(private _navCtrl:NavController, private _alertCtrl:AlertController , private _loadingCtrl: LoadingController ) {
}
ngOnInit() {
this._loadingModel = this._loadingCtrl.create();
this._loadingModel.present();
let alert = this._alertCtrl.create({
title: 'Error',
message:"error message",
buttons: [{
text: 'Ok',
handler: () => {
// user has clicked the alert button
// begin the alert's dismiss transition
let navTransition = alert.dismiss();
}
}]
});
//timeout the error to let other modals finish dismissing.
setTimeout(()=>{
alert.present();
},500);
}
}
The ok click want close the alert model, Here in this example it's on the same page so I can dismiss the loading but when on different components it's not possible to do.
Related
callHelpCenter(){
let alert = this.alertCtrl.create({
subTitle: 'Help Center',
message: "<p (click)='callEn()'>Phone number 12345</p>",
buttons: ['Dismiss']
)}
}
callEn(){
console.log('clicked');
}
As I have written above code, I want to handle the event on clicking of the message <p>. Tag it's showing in DOM properly but not able to call the function (click)='callEn()' . So how can I handle on click of message of the custom alert in ionic?
I have a PWA built with ionic deep linker. I have done a demo here https://stackblitz.com/edit/ionic-mee2ut?file=app%2Fcustomer%2Fcustomer.component.html where the browser back button doesn't work as expected.
Steps to reproduce
1.In Dashboard page click on edit button.It will navigate to customer
page(see URL.It is changed to /Customer/CustomerId).
2.In Customer page, you will see the customer info and other customers
list, there click edit from other customers list.This will open another
page.(see URL.It is changed to /Customer/CustomerId).
3.Click on browser back button u can see that the URL is changed but the
view is not updated.
If I repeat steps 1 & 2 then click on nav back button instead of browser button then it works correctly.Both the URL and the view gets updated.
Is there something I am doing wrong because the browser back button does not work as expected or this is issue of ionic framework.
This is how i navigate between views
EditCustomer(Customer: any) {
this.navCtrl.push('Customer', { Id: Customer.Id, Name: Customer.Name });
}
Can somebody please tell me a way how to resolve this issue?
I saw your code in the above url, you are passing id as param but not the name so, that is the reason url is changing but data is not reflected i modified your code in app.module.ts file please replace this code in your app.module.ts file
IonicModule.forRoot(MyApp, {}, {
links: [
{ component: DashboardComponent, name: 'Dashboard', segment: 'Dashboard' },
{ component: CustomerComponent, name: 'Customer', segment: 'Customer/:Id/:Name' }
]
})
Please replace your app.module.ts with the following code
import { Component } from '#angular/core';
import { Platform, IonicApp, App } from 'ionic-angular';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = 'Dashboard';
constructor(private _app: App, platform: Platform, private _ionicApp: IonicApp,) {
platform.ready().then(() => {
this.setupBackButtonBehavior();
});
}
private setupBackButtonBehavior () {
// If on web version (browser)
if (window.location.protocol !== "file:") {
// Register browser back button action(s)
window.onpopstate = (evt) => {
//Navigate back
if (this._app.getRootNav().canGoBack())
this._app.getRootNav().pop();
};
}
}
}
I was able to use something like this:
let randomID = this.makeId(5); // random string id
this.navCtrl.push('path', {
eventID: eventID,
instituteID: instituteID,
randomID: randomID
}, {
id: `path/${eventID}/${instituteID}/${randomID}`
});
This "id" seems to fix it, but if you can go to the same page, then it requires a "random" value to separate each visit to that page.
#IonicPage({
name: 'path',
segment: 'path/:instituteID/:eventID/:randomID'
})
It looks like, by default, it uses the name of the page as an id for that view. If multiple views have same id => issue when using browser back/forward. That's where the random comes in, to separate multiple instances of the same page.
I am new to ionic framework and I am unable to manage hardware back click functionality in Iframe. I am using Iframe to load certain url. While clicking the hardware back button I should be able to navigate back to the browser history page. But whenever I click hardware back its exiting the app.
`<iframe #iframe id="iframe" style="height: 100%;width: 100%;" src="your url"></iframe>`
#ViewChild('iframe') iframe:ElementRef;
constructor(public platform:Platform,public nav:Nav){
platform.registerBackButtonAction(() => {
if(this.nav.canGoBack()){
this.iframe.nativeElement.contentWindow.history().back();
}
});
}
You can use window.history.back():
ionViewDidLoad() {
this.navBar.backButtonClick = (e: UIEvent) => {
window.history.back();
}
this.initializeBackButtonCustomHandler();
}
ionViewWillLeave() {
// Unregister the custom back button action for this page
this.unregisterBackButtonAction && this.unregisterBackButtonAction();
}
initializeBackButtonCustomHandler(): void {
this.unregisterBackButtonAction = this.platform.registerBackButtonAction(function(event){
window.history.back();
}, 101); // Priority 101 will override back button handling (we set in app.component.ts) as it is bigger then priority 100 configured in app.component.ts file */
}
More info about this method can be found here.
I have a component which is my main interface. Inside this component, clicking a button opens ionic 2 modal which allows to choose items.
My modal page (itemsPage):
..list of items here
<button ion-button [disabled]="!MY_TURN || !selectedItem || !selectedItem.quantity"
(click)="useItem(selectedItem)">
<span>Choose item {{selectedItem?.name}}</span>
</button>
useItem() should:
Send item data to my main interface component
Close the modal
Execute a method in my main interface
How I can perform such actions? Couldn't find any documentation about communicating between modal and component in Ionic 2.
It is simply a matter of using parameters in viewController.
In your main interface component,
let chooseModal = this.modalCtrl.create(itemsPage);
chooseModal.onDidDismiss(data => {
console.log(data);
});
chooseModal.present();
In your modal page,
useItem(item) {
this.viewCtrl.dismiss(item);
}
Modal Controller link here
This is a clear example of getting data from modals in ionic.
You need to add a handler for modal’s onDismiss() and then return the data from the modal itself by passing the data to the ViewController’s dismiss() method:
// myPage.ts
// Passing data to the modal:
let modal = Modal.create(myModal, { data: [...] });
// Getting data from the modal:
modal.onDismiss(data => {
console.log('MODAL DATA', data);
});
this.nav.present(modal);
on the modal page
// myModal.ts
constructor(private navParams: NavParams, private viewCtrl: ViewController) {
// Getting data from the page:
var dataFromPage = navParams.get('data');
}
dismiss() {
// Returning data from the modal:
this.viewCtrl.dismiss(
// Whatever should be returned, e.g. a variable name:
// { name : this.name }
);
}
I have written this simple demo component to demonstrate a problem. The component code is below
App.FocusOutComponent = Em.Component.extend({
attributeBindings: ['tabindex'],
tagName: 'focus-out',
setFocus: function() {
console.log('clicked focus-out container');
this.$().find('button').focus();
console.log('focus set to button');
}.on('click'),
focussedOut: function() {
console.log('focussedOut from outer container');
}.on('focusOut'),
});
{{#focus-out id="focus-container" tabindex="-1"}}
<button id="text-button">Test Button</button>
{{/focus-out}}
When I run this and click on the focus-out element, this is the order of the logs. Link to demo
clicked focus-out container
focussedOut from outer container
focus set to button
Now when I am trying to write acceptance tests for this with the following code.
test('test visit / and click button', function() {
expect(0);
visit('/').then(function() {
find('focus-out').click();
console.log('after click in test');
});
});
The order of the logs are different. Link to demo.
clicked focus-out container
focus set to button
after click in test
focussedOut from outer container
The focusOut log got printed at the very end instead before the after click log. I was expecting the same order for the logs with just an additional log(after click) in the end.
Im not sure if this is a bug or something wrong with my code.
I also noticed another problem while executing tests. If I have focus on the chrome dev-tools while the tests are running, the focusOut event will not trigger at all.
Some help with this is much appreciated.
the click event doesn't set focus (being a back door route). You'll need to manually set focus then click if you want the same results.
Ember's Click Helper (sends mousedown/mouseup, then click)
function click(app, selector, context) {
var $el = app.testHelpers.findWithAssert(selector, context);
run($el, 'mousedown');
if ($el.is(':input')) {
var type = $el.prop('type');
if (type !== 'checkbox' && type !== 'radio' && type !== 'hidden') {
run($el, function(){
// Firefox does not trigger the `focusin` event if the window
// does not have focus. If the document doesn't have focus just
// use trigger('focusin') instead.
if (!document.hasFocus || document.hasFocus()) {
this.focus();
} else {
this.trigger('focusin');
}
});
}
}
run($el, 'mouseup');
run($el, 'click');
return app.testHelpers.wait();
}
Modified Test
test('test visit / and click button', function() {
expect(0);
visit('/').then(function() {
var el = find('focus-out');
el.focus();
click(el);
console.log('after click in test');
});
});
http://emberjs.jsbin.com/lefazevozi/1/edit?js,console,output
It's also important to note, that tearing down will also call the focus out event. So the main reason you were seeing the focusout at all was because on teardown it was losing focus from the button child.
Maybe focus should be set before mousedown on the click helper in the ember test, though I'm not sure what else that might affect, or if people wouldn't generally be expecting that since jquery doesn't do that.