In previous posts I walked you through the steps I followed when creating a bespoke 'look and feel' for a Hybrid Mobile App built using the Ionic Framework.

In this post, I'll show you how to build a 'Sign in' page using FormBuilder.

Forms

To quote Angular's 'Getting Started' guide:

Developing forms requires design skills, as well as framework support for two-way data binding, change tracking, validation, and error handling.

Angular supports three distinct approaches to building forms: Templates; ngModel; and FormBuilder.

FormBuilder

FormBuilder is an aptly-named class that helps us build forms. Forms contain FormControls and FormGroups and FormBuilder makes the process of creating them a little easier (you can think of it as a 'factory' object).

The Sign in page

Let's start by using the Ionic CLI to create the scaffolding for the 'Sign in' page:

ionic g page sign-in 

The CLI will create a new directory (/src/pages/sign-in) and four new files:

├── /big-top
    └── /src
        └── /pages
            └── /sign-in
                ├── sign-in.html
                ├── sign-in.module.ts
                ├── sign-in.scss
                ├── sign-in.ts

Using FormBuilder

We're going to be using FormBuilder and FormGroup so we need to import the appropriate classes (in sign-in.ts):

import { FormBuilder, FormGroup } from '@angular/forms';

We inject FormBuilder by adding a constructor parameter to the SignInPage component:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { FormBuilder, FormGroup } from '@angular/forms';

import { LoggerService } from '../../services/log4ts/logger.service';

@IonicPage()
@Component({
  selector: 'page-sign-in',
  templateUrl: 'sign-in.html'
})
export class SignInPage {

  credentialsForm: FormGroup;

  constructor(public navCtrl: NavController,
              public navParams: NavParams,
              private formBuilder: FormBuilder,
              private logger: LoggerService) {

    this.credentialsForm = this.formBuilder.group({
      email: [''],
      password: ['']
    });
  }

  onSignIn() {
    this.logger.info('SignInPage: onSignIn()');
  }

  onForgotPassword() {
    this.logger.info('SignInPage: onForgotPassword()');
  }
}

During construction of the SignInPage component a FormBuilder instance will be injected (by Angular DI) and assigned to the formBuilder variable.

We create a FormGroup by calling FormBuilder's group() method and assign it to the credentialsForm variable. The group() method accepts an object containing 'key-value' pairs that describe the groups's FormControls.

Adding credentialsForm to our view

We use the [formGroup] directive to tell Angular that we want to use the credentialsForm as the FormGroup for this form:

<form [formGroup]="credentialsForm">
  
  ...
  
</form>

And when we want to bind a FormControl to an <ion-input> we use the [formControl] directive:

<form [formGroup]="credentialsForm">

  <ion-item>
    <ion-label floating>Email</ion-label>
    <ion-input [formControl]="credentialsForm.controls['email']"
        type="email"></ion-input>
  </ion-item>
  
  <ion-item>
    <ion-label floating>Password</ion-label>
    <ion-input [formControl]="credentialsForm.controls['password']"
        type="password"></ion-input>
  </ion-item>      

  <ion-row>
    <ion-col text-center>
      <button ion-button block color="secondary" (click)="onSignIn()">
        Sign in
      </button>
    </ion-col>
  </ion-row>

  <ion-row>
    <ion-col text-center>
      <button ion-button clear color="light" (click)="onForgotPassword()">
        Forgot your password?
      </button>
    </ion-col>
  </ion-row>

</form>

AppModule

We also need to add the SignInPage component to our AppModule (in app.module.ts):

...

import { SignInPage } from '../pages/sign-in/sign-in';

@NgModule({
  declarations: [
    ...
    SignInPage
  ],
  imports: [
    ...
    IonicModule.forRoot(BigTopApp, {}, {
      links: [
        ...
        { component: SignInPage, name: 'SignInPage', segment: 'sign-in' }
      ]
    })
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    ...
    SignInPage
  ],
  providers: [
    ...
  ]
})
export class AppModule {}

Let's try running the application to make sure it’s working as expected:

ionic serve --platform=ios

You should see output like:

What's Next

In the next post, I'll show you how to add support for validation and error handling:

And social logins:

Source Code:
Resources: