& Classes
Exercise 4 Adding the Modal component
A modal is a form of temporary UI that slides into the screen, over the page content, and is often used for login/registration forms, composing messages or presenting app configuration options for example.
For the last exercise in this chapter we’ll incorporate the Modal component into a template within our app and play with some of the available methods and properties in the process.
Let’s create a new page for our app with the following command in our Terminal:
ionic g page technologies
This page will contain a list of technologies used within the app that, when an individual technology listing is clicked on, will open a modal overlay with further information about that selected listing.
myApp/src/pages/technologies/technologies.html template and make the following changes (highlighted in bold):
<ion-header>
<ion-navbar>
<ion-title>Technologies</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-list-header>
Technologies </ion-list-header>
<ion-item
*ngFor="let technology of technologies"
(click)="activateModal(technology)">
{{ technology.name }}
</ion-item>
</ion-list>
</ion-content>
The only “surprise” in the above code would be the inclusion of the <ion-list-header>
component which adds a header to our list.
The <ion-list> and <ion-item> components, Angular 2 *ngFor directive and event binding should be familiar from previous examples in this chapter.
Now we need to amend our myApp/src/pages/technologies/technologies.ts file to create the technologies object and the activateModal method which are being implemented into each iterated <ion-item> component in the above template.
Open the myApp/src/pages/technologies/technologies.ts file and make the following changes (highlighted in bold):
import { Component } from '@angular/core';
import { ModalController, NavController} from 'ionic-angular';
import { Modals } from '../modals/modals';
@Component({
selector: 'page-technologies', templateUrl: 'technologies.html' })
export class TechnologiesPage {
public technologies: Array<{name: string, date: string, summary:
string, website: any}>;
constructor(public nav: NavController, public modalCtrl: ModalController) {
this.technologies = [ {
name: "Angular JS",
date: "October 20th 2010",
summary: "Web application framework developed and maintained by Google", publish to multiple platforms from one single codebase",
website: "https://cordova.apache.org"
}, {
name: "TypeScript",
date: "October 1st 2012",
summary: "Strict superset of JavaScript developed and maintained
by Microsoft",
website: "http://typescriptlang.org"
}];
}
activateModal(link) {
let modal = this.modalCtrl.create(Modals, link);
modal.present();
}
}
If we break this down here’s what we are accomplishing with the above class:
• Imported the ModalController component
• Imported a custom component called Modals (which we will create shortly!)
• Created a technologies array - which is then initialised within the constructor
• Created the activateModal method which calls the create and present methods of the ModalController class
At this point we need to pay attention to the activateModal method and its use of one particular method of the ModalController class - create.
This method accepts 3 parameters:
• Component Type - The modal view
• Data - Any data to be passed to the modal (optional)
• Modal options - Configuration options for the modal (optional)
The first parameter - the component type - refers to a class which is used to define the modal view.
There’s only one little snag with our use of this class in the activateModal method.
The Modals class doesn’t exist!
Using the Ionic CLI let’s create a new page called modals:
import { Component } from '@angular/core';
import { NavController, ViewController, NavParams } from 'ionic-angular';
@Component({
selector: 'page-modals', templateUrl: 'modals.html' })
export class Modals { public name : string;
public summary : string;
public website : string;
constructor(
public navCtrl: NavController, public params: NavParams, public viewCtrl: ViewController )
{
this.name = this.params.get('name');
this.summary = this.params.get('summary');
this.website = this.params.get('website');
}
ionic g page modals
Now open the newly created myApp/src/pages/modals/modals.ts file and make the following amendments (highlighted in bold):
In the Modals class we use the NavParams object to extract the data passed to our modal through the activateModal method from the TechnologiesPage class.
We then assign this data to properties which will then be implemented in the myApp/src/pages/modals/modals.html template.
Finally we create a closeModal method which will allow the modal window when open to be closed.
In your favourite IDE (I’m a fan of Sublime Text but take your pick of whichever software works best for you) open the myApp/src/pages/modals/modals.html file and make the following amendments (highlighted in bold):
<ion-header>
<button ion-button color="primary" (click)="closeModal()">
<span>Close</span>
<span showWhen="ios">Cancel</span>
<ion-icon name="md-close" showWhen="android,windows"></
ion-icon>
</ion-header>
<ion-content>
<ion-list>
<ion-item>
<h2>{{ name }}</h2>
<p [innerHTML]="summary"></p>
<p>
<br>
<a href="{{ website }}" target="_blank">Visit website</a>
</p>
</ion-item>
</ion-list>
</ion-content>
Okay, nothing too involved or complex here.
Within our <ion-header> component we add an <ion-toolbar> component which contains an <ion-buttons> component to display the button to close our modal.
In our <ion-content> section we create a list to display the properties from the ModalsPage class.
Unfortunately, if we try to run this in our browser with Ionic serve we won’t actually be able to get to the technologies page as we don’t have any link from our home page to get there!
Let’s change that by adding the following addition to the pages object in the myApp/src/pages/home/home.ts file (highlighted in bold):
import {TechnologiesPage} from '../technologies/technologies';
...
constructor(public navCtrl: NavController) {
this.pages = [
import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { TechnologiesPage } from '../pages/technologies/technologies';
import { TweetsPage } from '../pages/tweets/tweets';
import { Modals } from '../pages/modals/modals';
@NgModule({
The penultimate step now involves registering the technologies and modals
components with the root module for the app - the myApp/src/app/app.module.ts file (amendments highlighted in bold):
Finally, from the download files for this chapter copy the images in the Modal/
myApp/src/assets/images/ directory to the same directory in your own local app.
Once this has been done we can then preview the app in the browser by running the ionic serve command from the Terminal/Command Prompt.
When published to the browser navigate to the Technologies page, click on the declarations: [
MyApp, HomePage, AboutPage, ContactPage,
TechnologiesPage, TweetsPage,
Modals ],
imports: [
IonicModule.forRoot(MyApp) ],
TechnologiesPage, TweetsPage,
Result!
Of course there’s a lot more we could do with the Modal component but I’ll leave that to you to play around with and subsequently build on the above example.
You can read the API docs for the Modal component here: http://ionicframework.
com/docs/v2/api/components/modal/ModalController/.
What’s impressive about Ionic 2’s component API is that we can quickly and easily implement functionality such as Lists, Slides and Modals into our pages - and these are only a fraction of the UI components provided by the framework.
For further information the online documentation for all Ionic 2 UI components is available here: http://ionicframework.com/docs/v2/components/.
If you’re feeling brave, you might try devoting some time to peering into the source code for each Ionic UI component located within the following app directory:
node_modules/ionic-angular/components/.
During subsequent chapters we’ll start to use more of these components but here we conclude our basic introduction to templating and instead turn our attention in the
next chapter to theming Ionic 2 apps.
Resources
All project files for this chapter can be found listed in the download links on page 636.
Ionic 2 apps
By default every app you develop with Ionic 2 comes with pre-built themes for iOS, Android & Windows Phone. This means that UI components that are added to our templates are already styled to not only appear aesthetically pleasing but also match the style conventions of the platform that the app is being published to.
If we take a look at the technologies screen of the myApp project, for example, across iOS, Android & Windows Phone using the following command:
// Add lowercase L as a flag after the command ionic serve -l
We can see the following variations, displayed side by side, in how font sizes &
styles, header bars and the alignment of page headings are rendered on the screen for each different platform:
These style variations are driven through the use of the following platform specific Sass files:
• node_modules/ionic-angular/themes/ionic.globals.ios.scss
• node_modules/ionic-angular/themes/ionic.globals.scss
• node_modules/ionic-angular/themes/ionic.globals.md.scss
• node_modules/ionic-angular/themes/ionic.globals.wp.scss We’ll take a look at each of these files in more detail below.
ionic.globals.ios.scss
This Sass file imports globally shared style rules and iOS specific rules only - all of which are targeted, as you might have guessed, for use on Apple mobile & tablet devices.
The Apple human interface guidelines for iOS design/development are available here: https://developer.apple.com/ios/human-interface-guidelines/
ionic.globals.scss
This Sass file imports Sass functions, mixins and defines variables that will be used globally for the app.
ionic.globals.md.scss
Imports style rules, globally shared and Android specific only, targeted specifically for use on the Android platform.
The md in the name of the file stands for Material Design which is a visual language developed by Google that aims to describe and promote good design principles and practice for the Android platform.
More information on Material Design is available here: https://material.google
ionic.globals.wp.scss
This is where style rules, globally shared and those that are Windows Phone only, are imported for use on the Windows Phone platform.
Design & UI information for developers targeting Windows 10 based devices is available here: https://developer.microsoft.com/en-us/windows/design.
You’ll never have a call to amend these files but it’s important to be aware of how each platform is initially themed through their use.
Custom Themes
The src/themes directory allows us Sass variables to be implemented through the variables.scss file.
Global styles
Style rules to be applied globally as well as those that are platform specific should be written within the src/app/app.scss file.
Variables
The src/themes/variables.scss file contains various Ionic Sass functions, mixins and variables (which are applicable across all targeted platforms) imported from the node_modules/ionic-angular/themes/ionic.globals.scss file as well as sections that are devoted solely for implementing platform specific variables.
Some of the cross-platform variables are displayed in the following $colors map:
$colors: (
primary: #387ef5, secondary: #32db64, danger: #f53d3d, light: #f4f4f4, dark: #222, favorite: #69BB7B );
Ionic uses keys from the above $colors map as component properties, typically on buttons, to provide their CSS style which we can see implemented in some of the components that we worked with during the last chapter.
For example, if you go back to the Sliding Lists exercise in the last chapter you’ll see this little snippet of code which defines the hidden buttons for our list that are
<ion-item-options side="right">
<button ion-button color="primary" (click)="buttonOne(page.title)">
<ion-icon name="text"></ion-icon>
BUTTON 1 </button>
<button ion-button color="secondary" (click)="buttonTwo(page.title)">
<ion-icon name="call"></ion-icon>
BUTTON 2 </button>
</ion-item-options>
Notice the primary and secondary values (highlighted in bold)?
These are keys drawn from the $colors map in our variables.scss file which can, of course, be edited to use whatever colors you desire and there’s nothing stopping you from adding new key/value pairs too.
Let’s say you wanted to provide specific style rules for different types of social media sharing buttons.
We could add these to the $colors map like so:
$colors: (
This is a little different to the existing key/value pairs but what we have done in the above is define the key for each social media component and then supply multiple values in the form of a map for each key.
The keys that are supplied in the twitter and facebook maps are as follows:
• base (acts as the background color for a component)
• contrast (acts as the text color for the component)
The base and contrast keys are recognised defaults and parsed by Ionic using colour handling functions provided by the node_modules/ionic-angular/themes/
ionic.functions.scss file.
By supplying a map of key/value pairs to our social media keys we have greater flexibility in how we can customise style data that we want to add to the $colors map.
UI Components
If you look inside the node_modules/ionic-angular/components directory of your app you’ll see all of the available UI components for quickly implementing interface elements such as an alert box, modal window or slideshow.
With a few exceptions almost all of these UI components mirror one another in terms of the Sass files they contain:
• component-name-here.scss
• component-name-here.ios.scss
• component-name-here.md.scss
• component-name-here.wp.scss
Each platform specific Sass file imports the global Sass file for that platform into itself as shown in the following for the List component list.ios.scss file:
@import " ../../themes/ionic.globals.ios";
This is a pattern that you’ll notice throughout the pre-built Sass files contained within your app - the segregation and modularisation of different types of style rules that are then imported into other Sass files as and where required.
Themes
In addition to each component’s respective Sass files our app also contains a node_modules/ionic-angular/themes directory which contains the following two pre-baked themes:
• Dark
• Default
The Default theme (which IS the default theme for the app if you hadn’t already guessed from the name!) for each platform is imported into their respective files:
• node_modules/ionic-angular/themes/ionic.globals.ios.scss
• node_modules/ionic-angular/ themes/ionic.globals.md.scss
• node_modules/ionic-angular/ themes/ionic.globals.wp.scss
These themes are then imported into the platform specific Sass files for each UI component and the following specific Sass files:
• node_modules/ionic-angular/themes/components.scss
• node_modules/ionic-angular/platform/cordova.ios.scss
What this means is that the team at Ionic have already done the work of not only providing theming for your app but also ensuring that such theming is also tailored on a platform by platform basis too.
This is pretty powerful and gives you the flexibility to develop and publish your app without any CSS modifications whatsoever.
A word of warning here though - Do not EVER manually edit these theme files or the Sass UI component files to change any of the existing Sass rules/variable values that are contained within.
First off, there should NEVER be a need to do this and secondly, doing so could introduce some pretty serious layout & styling bugs or have other unforeseen and unintended consequences - just sayin’!
And if you want to change the default Ionic theme to use the dark theme instead?
Simply include the following import statement for the dark theme towards the top of your src/theme/variables.scss file like so:
This change would then be seen across all targeted platforms.
Simple as!
This pre-built theming does create a problem though with the potential for many Ionic apps to look the same as one another on the Apple App or Google Play stores unless some level of CSS customisation involved.
Okay, with that said how do we roll our own themes then?
Custom Theming
If all App Store apps looked the same it would be pretty bad - not to mention being downright suspicious, bland, boring and ultimately unattractive right?
If we want our apps to look unique, communicate their own specific branding and ultimately stand out amongst others apps in the online marketplace then we have to implement our own custom theming.
@import "ionic.build.dark";
• Modifying attributes & theme values
• Override existing Sass variables
• Define custom Sass variables
• Define custom component styles
• Setting mode configurations
Modifying attributes & theme values
The quickest and least disruptive method of customising the app design would be to edit the src/app/app.scss file and/or src/theme/variables.scss file.
Editing the src/theme/variables.scss file gives us the advantage of simply amending preset values to match those of the design palette for our app.
In this file, as we saw earlier in the chapter, we can add additional key/value pairs to the $colors map (amendments displayed in bold):
$colors: (
primary: #387ef5, secondary: #32db64, danger: #f53d3d,
The twitter and facebook keys can then be used as attributes on UI components and DOM elements in our page templates.
Let’s see this at work in our app.
In the myApp/src/pages/home/home.html file replace the primary and secondary color values with twitter and facebook values instead (displayed in bold below):
<ion-item-options side="right">
<button ion-button color="facebook" (click)="buttonOne(page.title)">
<ion-icon name="text"></ion-icon>
BUTTON 1 </button>
<button ion-button color="twitter" (click)="buttonTwo(page.title)">
<ion-icon name="call"></ion-icon>
BUTTON 2 </button>
</ion-item-options>
All we’re doing here is simply changing the colours of the background/text colour for the buttons that are revealed when we swipe our list item to the left.
And yes, I DO know they’re not social media buttons!
That’s not the point for this example though as we’re doing this to prove that we can add/change attributes to the myApp/src/theme/variables.scss file that can then be used in our page templates as and where required.
If we run the ionic serve command (with or without the lowercase L as an additional flag - the choice is yours!) we should be able to see the changes to these buttons as shown in the following screenshot:
Here we see the facebook and twitter styles being applied and those attributes displayed on each button component in the browser console.
It’s important to note that we could define any type of CSS property, not just
It’s important to note that we could define any type of CSS property, not just