To efficiently achieve this, implementing a Modal
is the recommended approach. Additionally, including a search bar at the top can assist users in easily locating their desired country. The provided example serves as a simplified demonstration (please inform me of any identified errors, as extraneous code has been omitted).
It should be noted that instead of utilizing an ion-list
with individual ion-item
components per country, standard div
elements are being used in the view. This decision was made due to the substantial number of countries (~250), necessitating the initialization, rendering, and creation/destruction of Ionic components each time the list is filtered. In the demo, performance remains optimal even on older mobile devices by using basic HTML elements with minimal styling rules.
Controller
// Angular
import { Component } from '@angular/core';
// Ionic
import { NavParams, ViewController } from 'ionic-angular';
@Component({
selector: 'page-country-list',
templateUrl: 'country-list.html'
})
export class CountryListPage {
public countries: Array<any>;
public countriesToShow: Array<any>;
constructor(private paramsCtrl: NavParams, private viewCtrl: ViewController) {
// Retrieve data passed as a parameter
this.countries = paramsCtrl.get('countries');
// Initialize the list of countries to display in the view
this.initializeCountriesToShow();
}
public initializeCountriesToShow(): void {
// Make a clone of the country list to avoid modifying the original copy
this.countriesToShow = [...this.countries];
}
public filterCountries(ev: any): void {
// Reset the displayed countries to show all
this.initializeCountriesToShow();
// Get the value from the searchbar
let val = ev.target.value;
// If the value is empty, do not filter the countries
if (val && val.trim() != '') {
this.countriesToShow = this.countriesToShow.filter((country) => {
return (country.name.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
// Return the selected country to the caller
public selectCountry(country: any): void {
this.viewCtrl.dismiss(country);
}
// Close the modal without returning anything
public close(): void {
this.viewCtrl.dismiss();
}
}
View
<ion-header>
<ion-navbar color="primary">
<ion-title>Countries</ion-title>
<ion-buttons right>
<button (click)="close()" ion-button icon-only>
<ion-icon color="light" class="close-icon" name="close"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
<ion-toolbar color="primary">
<ion-searchbar placeholder="Type the name here..." (ionInput)="filterCountries($event)"></ion-searchbar>
</ion-toolbar>
</ion-header>
<ion-content padding>
<div class="country-list">
<div tappable (click)="selectCountry(country)" class="country-item" *ngFor="let country of countriesToShow">
{{ country.name }}
</div>
</div>
</ion-content>
Styles
.ios, .md {
page-country-list {
div.country-item {
position: relative;
margin-right: 16px;
margin-left: 16px;
margin-top: 16px;
padding-bottom: 16px;
border-bottom: 0.55px solid map-get($colors, light);
&:last-child {
border-bottom: none;
}
}
ion-navbar {
.close-icon {
font-size: 3.5rem;
padding-right: 8px;
}
}
}
}
Caller component
To display the modal, you can follow this procedure:
constructor(private modalController: ModalController) {}
// ...
public showCountryDropdown(): void {
// Create the modal
let modal = this.modalCtrl.create('CountryListPage');
// Manage the returned result
modal.onDidDismiss(country => {
if (country) {
// Process the selected country
// ...
}
});
// Show the modal
modal.present();
}
Note: The assumption made in the demo is that each country
object includes a name
property.