The form is initialized like this in auth.js:
 
this.authForm = formBuilder.group({
	username: ['', Validators.compose([Validators.required, Validators.pattern('[a-zA-Z]*'), Validators.minLength(8), Validators.maxLength(30)])],
	password: ['', Validators.compose([Validators.required, Validators.minLength(8)])]
});
 
We’re using FormBuilder helper service formBuilder to group form fields into ControlGroup object called authForm.
 
I hope all these make sense. It’s almost funny, but validation is the easiest part here. 🙂
 
Everything shown here makes an Angular 2 form, but what about validation?
 
Let’s once again take a look at these lines:
 
username: ['', Validators.compose([Validators.required, Validators.pattern('[a-zA-Z]*'), Validators.minLength(8), Validators.maxLength(30)])],
password: ['', Validators.compose([Validators.required, Validators.minLength(8)])]
 
We have defined four validation rules for the username field and two validation rules for the password filed. All these rules except pattern are predefined and you can use them any way you want. While the pattern is also preexisting validation rule you still need to provide a working regex pattern.
 
<ion-item [ngClass]="{'error-border':!authForm.controls.password.valid && authForm.controls.password.touched}">
	<ion-label floating>Password</ion-label>
	<ion-input formControlName="password" type="password"></ion-input>
</ion-item>
<ion-item *ngIf="authForm.controls.password.hasError('required') && authForm.controls.password.touched">
	<p>Sorry, field password is required!</p>
</ion-item>
<ion-item *ngIf="authForm.controls.password.hasError('minlength') && authForm.controls.password.touched">
	<p>Sorry, minimum password length is 8!</p>
</ion-item>
 
If the password field is not valid (!authForm.controls.password.valid) after a field has been touched (authForm.controls.password.touched) Angular will add a class error-border to ion-item element:
 
<ion-item [ngClass]="{'error-border':!authForm.controls.password.valid && authForm.controls.password.touched}">
 
authForm.controls.password keyword is a reference to password Control object.
 
At the same time, below each field, we can find a few additional div elements holding error descriptions. In case of fields (username or password) have validation errors, a related description will become visible.
 
<ion-item *ngIf="authForm.controls.password.hasError('required') && authForm.controls.password.touched">
	<p>Sorry, field password is required!</p>
</ion-item>
<ion-item *ngIf="authForm.controls.password.hasError('minlength') && authForm.controls.password.touched">
	<p>Sorry, minimum password length is 8!</p>
</ion-item>
 
Finally, if everything is OK and application form is successfully validated, we’ll enable submit button:
 
<button ion-button full color="primary" [disabled]="!authForm.valid" style="margin-top: 20px;" type="submit">Authorize</button>
 

Code

 
In case of GitHub repo is not available and you can only use code provided below, this is what project folder looks like (image was taken from the Sublime text editor):
 
Ionic 2 Form Validation Folder Structure
 
app.component.ts
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { HomePage } from '../pages/home/home';
import { AuthPage } from '../pages/auth/auth';

@Component({
  templateUrl: 'app.html'
})

export class MyApp {
  rootPage:any;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
      this.checkPreviousAuthorization();
    });
  }

  checkPreviousAuthorization(): void { 
    if((window.localStorage.getItem('username') === "undefined" || window.localStorage.getItem('username') === null) && 
       (window.localStorage.getItem('password') === "undefined" || window.localStorage.getItem('password') === null)) {
      this.rootPage = AuthPage;
    } else {
      this.rootPage = HomePage;
    }
  }  
}
 
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
 
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { AuthPage } from '../pages/auth/auth';
 
@NgModule({
  declarations: [
    MyApp,
    HomePage,
    AuthPage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    AuthPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}
 
auth.html
<ion-header>
  <ion-navbar>
    <ion-title>Authorization Page</ion-title>
  </ion-navbar>
</ion-header>
 
 
<ion-content padding>
    <form [formGroup]="authForm" (ngSubmit)="onSubmit(authForm.value)">
        <ion-item [ngClass]="{'error-border':!authForm.controls.username.valid && authForm.controls.username.touched}">
            <ion-label floating>Username</ion-label>
            <ion-input formControlName="username" type="text"></ion-input>
        </ion-item>
 
        <ion-item *ngIf="authForm.controls.username.hasError('required') && authForm.controls.username.touched">
            <p>Sorry, field username is required!</p>
        </ion-item>
        <ion-item *ngIf="authForm.controls.username.hasError('pattern') && authForm.controls.username.touched">
            <p>Sorry, only small and capital letters are allowed!</p>
        </ion-item>        
        <ion-item *ngIf="authForm.controls.username.hasError('minlength') && authForm.controls.username.touched">
            <p>Sorry, minimum username length is 8!</p>
        </ion-item>
        <ion-item *ngIf="authForm.controls.username.hasError('maxlength') && authForm.controls.username.touched">
            <p>Sorry, maximum username length is 30!</p>
        </ion-item>
 
        <ion-item [ngClass]="{'error-border':!authForm.controls.password.valid && authForm.controls.password.touched}">
            <ion-label floating>Password</ion-label>
            <ion-input formControlName="password" type="password"></ion-input>
        </ion-item>
        <ion-item *ngIf="authForm.controls.password.hasError('required') && authForm.controls.password.touched">
            <p>Sorry, field password is required!</p>
        </ion-item>
        <ion-item *ngIf="authForm.controls.password.hasError('minlength') && authForm.controls.password.touched">
            <p>Sorry, minimum password length is 8!</p>
        </ion-item>                
 
        <button ion-button full color="primary" [disabled]="!authForm.valid" style="margin-top: 20px;" type="submit">Authorize</button>        
    </form>
</ion-content>
 
auth.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';
import { IonicPage, NavController, NavParams } from 'ionic-angular';

import { HomePage } from '../home/home';

@IonicPage()
@Component({
  selector: 'page-auth',
  templateUrl: 'auth.html',
})

export class AuthPage {

	authForm: FormGroup;

	constructor(public nav: NavController, public navParams: NavParams, public formBuilder: FormBuilder) {

		this.nav = nav;

	    this.authForm = formBuilder.group({
	        username: ['', Validators.compose([Validators.required, Validators.pattern('[a-zA-Z]*'), Validators.minLength(8), Validators.maxLength(30)])],
	        password: ['', Validators.compose([Validators.required, Validators.minLength(8)])]
	    });
	}

	onSubmit(value: any): void { 
	    if(this.authForm.valid) {
			window.localStorage.setItem('username', value.username);
			window.localStorage.setItem('password', value.password);

			this.nav.push(HomePage);
	    }
	}   
}
 
home.html
https://www.gajotres.net/wp-admin/post.php?post=10371&action=edit#
<ion-header>
  <ion-navbar hideBackButton>
    <ion-title>Home Page</ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  <h1>Welcome {{username}}</h1>
  <button ion-button full color="primary" style="margin-top: 20px;" (click)="logout()">Logout</button>
</ion-content>
 
home.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
 
import { AuthPage } from '../auth/auth';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 
    username: string;
 
    constructor(public nav: NavController) {
        this.nav = nav;
        this.username = window.localStorage.getItem('username');
    }

	logout() {
        window.localStorage.removeItem('username');
        window.localStorage.removeItem('password');

        this.nav.setRoot(AuthPage);
        this.nav.popToRoot();         
	}    
}
 

Deployment

 
Next step, build our application:
 
ionic build android
 
Be careful here, this step may break if you’re behind a firewall. The first execution will take a long time, so be patient.
 
Finally:
 
ionic run android -l -c -s
 
or, as this example is not bound to any platform, you can run it in your browser:
 
ionic serve -l -c -s
 

Download The Code

 
Working GitHub repo link can be found below:
 
GitHub
 
 

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.



  • Works great 🙂 Thank you for sharing it. Though, I did not try custom method for validating.

    • You’re welcome … neighbour 🙂

    • karthiikk Baleneni

      whether its working in latest ionic2 beta v0.0.25

  • Thanks for that. It would be helpful to state what files these code blocks go into..

  • Thanks for that. This helped me a lot.

    I managed to get rid of the ‘function’ keyword in
    checkFirstCharacterValidator(control: Control): { [s: string]: boolean } { … }

    by adding ‘this’ in the Validators group:
    ‘username’: [”, Validators.compose([Validators.required, Validators.minLength(8), this.checkFirstCharacterValidator])],

    I also didn’t need to add the class declarations as they are already declared in the constructor:
    //authForm: ControlGroup;
    //username: AbstractControl;
    //password: AbstractControl;

    Lastly I changed the return line from the checkFirstCharacterValidator function to:
    return {“invalid_firstCharacter”: true};
    as I found naming the string and the method the same confusing (even though that’s what the native angular 2 validator functions do).

  • aluknot

    One of the things i don’t like about ionic 2 is the import part… you need to import a lot of things, when you only want to do something really simple. How can i remember this? i have to come back to this article every time.

  • Graciele E. Victor

    I’d love to see this article updated to Ionic 2 beta 6

  • karthiikk Baleneni

    whether it will work in Ioinic 2 @beta 0.25?? seems to be its not working.

  • Cyril Zilbermann

    Hi,
    Thanks for your share !
    I’m very newbie on ionic.
    However, I’ve a trouble : I’ve copy/paste your code for testing and I’ve compilation parsing error on three variables declaration (authForm, username and password).
    It seems does not accept variable declaration on class and I don’t know why.
    Could you help me ?
    Thanks

    • Cyril Zilbermann

      Sorry,
      My bad, i tried to work a TS code like a JS one :/
      Works perfectly !
      Thanks !

  • Varshil Shah

    hi i used your code AND ITS’S RUN PERFECT BUT PROBLEM IS THAT I WANT USERNAME AND PASSWORD IN STRING VARIABLE . I DON’T KNOW HOW I DO THAT

    • Don’t forget that this is still JavaScript and that every object is easily readable.

      For example, you can use this:

      console.log(this.username);

      To find out what AbstractControl object looks like. And it will tell you that value is accessible like this:

      console.log(this.username.value);
      console.log(this.password.value);

      • Varshil Shah

        thanx..solved problem

        • Your welcome

          • Varshil Shah

            Hey I have one another problem..I getting the response from the server now it’s not fully json response so I want cut string how I do it in ionic 2..

          • My advice, Google it

          • Varshil Shah

            i already do it but i didn’t anything find it.

  • Davide Troise

    HI! I’m trying to follow your guide, but there’s no way i can make the custom Validator Work :/
    I wrote a console.log() in the validator, but it never appears, like it’s never called! Would you please paste your whole CustomValidator.ts file? Thanks!

    • Just download my GitHub example, you can find it on the second page. Though I will also add CustomValidator.ts, I forgot to add it after my last article update.

      • Andre Dreyer

        After having a look at the required validator I realised that the logic of the custom validator function had to be inverted. If (valid) return null else return {‘required’: true}

    • I have update article with CustomValidators.ts class example

  • Palmani

    Hi, Thanks for your post. It’s really helped a lot. Please help me to add validation for creating dynamic elements. i’m trying to add validation for input elements using ng-repeat.

  • Áron Barócsi

    is this is depreciated as of rc4?

    • James Trigg

      Yes think so. beta11 is now using the new angular forms.
      think you use some setting in ionicBootstrap to use the old forms but not really the way forward.

  • james stevens

    hey i am not able to submit the form,when i click on submit there is no submitted values shown in the console

  • manoj meshram

    hi, There is any way to submit image with form’s other field?

  • Lokesh Sahu

    How to prevent hidden field validation. In my form i have a select box, if i select one option some fields are visible, if select another option then other fields are visible and the previous fields are hidden.

    • Andreza Pollyana

      Hi, maybe this kind of validator will help you

      ‘note’: [“”, Validators.nullValidator]

  • manoj meshram

    HI,
    haserror is not function in ionic2 beta 11.

  • EM Products

    hi, thanks for the great post
    any upcoming update for the post
    also how can I validate for retype password ??

  • Eduardo Borges

    Greate!!

  • Lior Balmas

    Thanks for the article.
    I get this error:
    “Can’t bind to ‘ngFormModel’ since it isn’t a known native property”

    I use beta.11

  • Ansar Zhalyalov

    Unfortunately doesn’t work in beta 11 – “ORIGINAL EXCEPTION: No value accessor for ””

    • Franck Didier

      +1 doesn’t work

      • An article has been updated to Ionic v2 2.2.1 version.

  • Hi, Thanks for effort, the only problem is ionic2 and angular2 have had a lot of breaking changes, also the article doesn’t have published date (or mentioning ionic2 and angular2 version that this is based on), then it will be so confusing.

    • An article has been updated to Ionic v2 2.2.1 version. Plus article always had published date; on the second page; at the beginning of the Code chapter.

      Thought; I should move this information to the first page; it makes more sense. Thank you for your observation.

  • Periyasamy M

    Thank you so much.This is working fine..particular working in latest ionic 2 version and angular 2 rc versions. Thank you once again .@gajotres

  • Tammanoon K

    Thank you for reply i’ll try this.

  • Stevenson Nelli

    Could you please provide example with ionic select field ??

  • Sanchit Mahajan

    In above form how to display variable value in username field– I have {{username}} containing user name.. I want to display that value in username field..

    • I’m just in the process of updating this article to Ionic 3, give me a few hours and I will answer your question.

      • Sanchit Mahajan

        Thank You Sir…

    • I have updated this article. If you have time please describe me your request in more details and I will give you an answer as soon as possible.

  • Ols

    Thank you for the tuto, first try, first success 😉

    • I’m glad you have benn able to make it work. 🙂 Do you maybe need help with something else? I’m always looking for a good ideas or problems to cover here.