Harish Harish - 2 months ago 145
TypeScript Question

How to create or customize a Toast view using ionic2 framework

I am new to ionic2 development. Trying to show a toast message to the user, However using ionic2 framework am able to display only string message's in the toast view, I want to display a image and few other string in the form of customized view. How can i do that.

I got this link from ionic site which says we can display string's.
http://ionicframework.com/docs/v2/api/components/toast/ToastController/

Any suggestions ?

Answer

I've been playing around with this, and I think I found a workaround, but please notice that this is just that, a workaround, and may cause some other things to break somehow.

The final result is something like this.

The idea is to use Ionic2's ModalController but using an ugly and small workaround to modify the styles of that modal without affecting other modals of the app.

When a page is shown (even though if it's used as a modal page) the Component's name is used to set a class in the <ion-page> element in the html code. We're going to use that class to style a modal to make it look like a Toast, but taking advantage of using a page for it's content so we can put an image and some other things.

For this demo, I've created a page with two buttons:

<ion-header>

  <ion-navbar>
    <ion-title>ModalController Demo</ion-title>
  </ion-navbar>

</ion-header>

<ion-content padding>
    <h5>ModalController with custom size</h5>

    <button (click)="presentCustomModal()">Open Custom Modal</button>

    <button (click)="presentDefaultModal()">Open Default Modal</button>

</ion-content>

And with the following code:

import { Component } from '@angular/core';
import { NavController, ModalController, ViewController } from 'ionic-angular';

@Component({
    templateUrl: 'build/pages/modal-controller-custom-size/modal-controller-custom-size.html',
})
export class ModalControllerCustomSizePage {

    constructor(private navCtrl: NavController, private modalCtrl: ModalController) {

    }

    presentCustomModal() {
        let customModal = this.modalCtrl.create(CustomModalPage);

        customModal.onDidDismiss(() => {
            // Do what you want ...
        });

        // Present the modal
        customModal.present();
    }

    presentDefaultModal() {
        let defaultModal = this.modalCtrl.create(DefaultModalPage);

        defaultModal.onDidDismiss(() => {
            // Do what you want ...
        });

        // Present the modal
        defaultModal.present();
    }

}

/* ********************
    Custom modal 
********************* */
@Component({
    template:   '<ion-header>' +
                    '<ion-navbar dark>' +
                        '<ion-title>My custom modal</ion-title>' +
                        '<ion-buttons end>' +
                            '<button (click)="dismiss()">Close</button>' +
                        '</ion-buttons>' +
                    '</ion-navbar>' +
                '</ion-header>' +
                '<ion-content padding>' +
                    '<ion-grid>' +
                        '<ion-row>' +
                            '<ion-col width-50><img src="http://placehold.it/150x150"/></ion-col>' +
                            '<ion-col width-50>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</ion-col>' +
                        '</ion-row>' +
                    '</ion-grid>' +
                '</ion-content>',
})
class CustomModalPage {

    constructor(public viewCtrl: ViewController) {

    }

    public dismiss() {
        this.viewCtrl.dismiss();
    }
}

/* ********************
    Default modal 
********************* */
@Component({
    template:   '<ion-header>' +
                    '<ion-navbar>' +
                        '<ion-title>Default modal</ion-title>' +
                        '<ion-buttons end>' +
                            '<button (click)="dismiss()">Close</button>' +
                        '</ion-buttons>' +
                    '</ion-navbar>' +
                '</ion-header>' +
                '<ion-content padding>' +
                    '<h5>Modal content...</h5>' +
                '</ion-content>',
})
class DefaultModalPage {

    constructor(public viewCtrl: ViewController) {

    }

    public dismiss() {
        this.viewCtrl.dismiss();
    }
}

Please notice that I included the code of the two components that are going to be used as modals in the same page, just to make the code easier to read. The recommended approach is to put every Component in its own .ts file.

Until now there's nothing special in that code, is just a page that opens two different (but full-page) modals. The magic will be done by using these style rules:

.custom-modal-page {
    height: 270px;
    position: absolute;
    top: calc(100% - 270px);

    ion-content {
        background-color: #333;
        color: #eee;
    }
}

Since we're using the .custom-modal-page class, those changes will only affect the custom modal and not the default one.