On this post we will learn how to create a popover with an input field, a select dropdown with a function and buttons. The popover takes data from main page and returns data to the main page.
This is how the popover looks like:
First, create the popover Component:
import { Component } from "@angular/core"; import { PopoverController, Events } from '@ionic/angular'; @Component({ templateUrl: './calculate-rent.component.html', styleUrls: ['../base/property.page.scss'], }) export class CalculateRentComponent { // some variables to be bound to the template shouldBeWeeklyRent: number; constructor(private popoverCtrl: PopoverController, private events: Events) { } popoverEvent() { this.events.publish('fromPopoverEvent', this.shouldBeWeeklyRent); this.popoverCtrl.dismiss(); } closePopOver() { this.popoverCtrl.dismiss(); } }We use Events to pass data back to the caller component. Note this.events.publish(‘[name]’, [data]) on the codes.
The template:
<ion-grid> <ion-row> <ion-col class="text-header" style="text-align: center">Calculate Weekly Rent</ion-col> </ion-row> <ion-row> <ion-col size="8">Desired rental yield:</ion-col> <ion-col size="3"> <input type="text" class="textinput" style="border:1px solid #b2b2b2; background-color: #fff; padding: 0 3px 0 3px; text-align: right; width: 100%" number-input [(ngModel)]="desiredYield" (ngModelChange)="calculateWeeklyRent()" /> </ion-col> <ion-col size="1"><span style="padding-top: 6px; padding-left: 0px">%</span></ion-col> </ion-row> <ion-row> <ion-col size="8">From which type:</ion-col> <ion-col size="3"> <select [(ngModel)]="desiredYieldType" (ngModelChange)="calculateWeeklyRent()"> <option value="gross">Gross</option> <option value="net">Net</option> </select> </ion-col> <ion-col></ion-col> </ion-row> <ion-row> <ion-col size="8">New weekly rent:</ion-col> <ion-col><b>{{shouldBeWeeklyRent | currency}}</b></ion-col> </ion-row> <ion-row> <ion-col></ion-col> </ion-row> <ion-row> <ion-col size="4"> <button type="submit" class="button custom-button" (click)="closePopOver()"> Close </button> </ion-col> <ion-col size="8"> <button type="submit" class="button custom-button" (click)="popoverEvent()"> Put in Rental Field </button> </ion-col> </ion-row> </ion-grid>
We then add variables for data binding and the function that will be called on the component.
Then on the main page:
async showCalculateWeeklyRent(ev) { const popover = await this.popoverCtrl.create({ component: CalculateRentComponent, // the popover component that we created event: ev, componentProps: { // data to be passed totalCost: this.model.totalCost, totalExpense: this.model.totalExpense, totalIncomeWithoutRent: this.model.totalIncomeWithoutRent }, cssClass: 'popoverClass', }); // sync event from popover component this.events.subscribe('fromPopoverEvent', (shouldBeWeeklyRent) => { this.model.weeklyRent = shouldBeWeeklyRent; this.calculateYearlyRent(); }); return await popover.present(); }
Note the componentProps property can be used to pass data to popover component. It can contain objects that have more complex structure as well.
We use Events and its subscribe() method to receive data back.
On popover component, to receive data from the main page, we just need to declare local variables then they will be bound automatically with the data passed from the main page. We just need to make sure the variable names are similar.
// codes in main page async showCalculateWeeklyRent(ev) { const popover = await this.popoverCtrl.create({ . . . componentProps: { // data to be passed totalCost: this.model.totalCost, totalExpense: this.model.totalExpense, totalIncomeWithoutRent: this.model.totalIncomeWithoutRent }, . . . }); . . . } // codes in popover export class CalculateRentComponent { . . . totalCost: number; totalExpense: number; totalIncomeWithoutRent: number; // note that even we don’t need to state the variables in the constructor constructor(private popoverCtrl: PopoverController, private events: Events) { . . . } . . . }
Now the full codes in popover component:
import { Component } from "@angular/core"; import { PopoverController, Events } from '@ionic/angular'; @Component({ templateUrl: './calculate-rent.component.html', styleUrls: ['../base/property.page.scss'], }) export class CalculateRentComponent { desiredYield: number; desiredYieldType: string = 'gross'; shouldBeWeeklyRent: number; totalCost: number; totalExpense: number; totalIncomeWithoutRent: number; constructor(private popoverCtrl: PopoverController, private events: Events) { } calculateWeeklyRent() { . . . this.shouldBeWeeklyRent = …; . . . } popoverEvent() { this.events.publish('fromPopoverEvent', this.shouldBeWeeklyRent); this.popoverCtrl.dismiss(); } closePopOver() { this.popoverCtrl.dismiss(); } }
Reference:
https://edupala.com/ionic-4-popover/