Forms and Validations
Handling user input with forms is the cornerstone of many common applications. In this section we added many common use cases of inputs and validations in Ionic apps.
In this Ionic theme we included different types of form validations with Ionic and Angular such as: password and confirm password validation, international phone validation, email format validation and username validator. Learn everything about Forms and Validations in Ionic and how to use Angular Reactive Forms to create your own validators.
Angular Forms
This template uses Angular 8, so we will use Angular Forms library.
Angular provides two different approaches to handling user input through forms: reactive and template-driven. Both capture user input events from the view, validate the user input, create a form model and data model to update, and provide a way to track changes.
Reactive and template-driven forms process and manage form data differently. Each offers different advantages. You can learn more in Introduction to Forms in Angular.
In this Ionic template we use Angular Reactive Forms.
Angular Reactive Forms
Angular reactive forms helps the reactive programming style that favors an explicit data management flowing between non-UI data models (typically retrieved from a server) and a UI-oriented form model that keeps the states and values of HTML controls on the app screen. Reactive forms offer an easy way to use reactive patterns, testings and validations. Learn more in this Learning Angular Forms Ionic tutorial.
When using reactive forms (also known as model-driven forms), we will avoid directives like ngModel
, NgForm
, required
and such.The idea is that instead declaring that, we actually use the underlying APIs to do it for us and so making Angular power things for us. In a sense, instead binding Object models to directives like in template-driven forms, we create our own instances inside a component class and construct our very own JavaScript models. This approach has a lot more power and is extremely productive to work with since it allows us to write expressive code, that is very testable and keeps all logic in the same place, instead of dividing it around different form templates.
Because we use Reactive Forms, we will define all the logic of the form, the validators and the error messages on the Component.
Form Validators
In reactive forms, instead of adding validators through attributes in the template (like we do in template driven forms), you add validator functions directly to the form control model in the Component. Angular then calls these functions whenever the value of the control changes.
You can choose to write your own validator functions, or you can use some of Angular built-in validators.
Basic Validations
Angular provides lots of built-in validators to validate your inputs. In this template we will use the following:
required
: Validator that requires controls to have a non-empty value. It also validates that the value matches the input type. For example, if the input is of “email” type, then the input will be valid if it’s not empty and if the value is of email type.
minLength
: Validator that requires controls to have a value of a minimum length.
maxLength
: Validator that requires controls to have a value of a maximum length.
pattern
: Validator that requires a control to match a regex to its value. You can find more information about regex patterns in the PatternValidator reference.
email
: Validator that performs email validation.
compose
: is used when more than one validation is needed for the same form field.
You can visit our tutorial to learn more about using Angular built in validators in Ionic.
Custom Validators
Since the built-in validators won't always match the exact use case of our applications, sometimes we will need to create a custom validator.
We can get very creative and build any kind of custom validators. In this template we include four useful input validators that you can use through any Ionic or Angular app.
You can find these validators in src/app/validators
Phone/Country Validator
The purpose of this one is to validate if a phone number belongs to a certain country.
We use Google Libphonenumber JavaScript library for parsing, formatting, and validating international phone numbers. The phone directive controls that the value from the phone number input is correct for the selected country.
So, for this validation we have a <ion-select>
so the user can select the country. In this template we just added a few random countries, however, you can use the countries you need by just adding them to the countries list from the src/app/forms/validations/forms-validations.page.ts
or you can also use a library to get all the countries from the world.
We also have an input for the phone number and each time the user changes the selected country, this input updates his placeholder to reflect the correct phone format for that country.
In our component we define a FormGroup with both the country and the phone number. As you can see in the following code the phone number uses our custom invalidCountryPhone
validator.
Password Validator
This validator is probably the most used and common validator because is present almost in every signup page. It's a validator to check if the confirmation password is equal to the password as you can see in the following image:
So, for the password input we have the following validations where we check the length and if it contains at least one uppercase and one number.
And then for the FormGroup which contains the password
and the confirm_password
inputs we validate if they are equal or not.
Username Validator
The goal of this validator is to check if a username is available or not. In the Forms and Validations page we trigger this validator in real time, I mean, as the user is typing it.
For this template, because we don't have a real database, we define two existing usernames: 'abc123' and '123abc'. If our validation fails, we return an object with a key for the error name and a value of true. Otherwise, if the validation passes, we simply return null because there is no error.
In a real app you should check against your Database if the username is already in use.
To use it in our FormControl we just add it like this:
Error Messages
We want to be able to display custom error messages to our users when they don't fill the form correctly.
Because we are using Reactive Forms, we don't want to attach the error messages to the markup of the page. To manage error messages, we use an array with all the error types and messages for each control of our ValidationsForm.
Let's see an example with the username input. The username input has five different types of validations and their corresponding error messages.
In the markup we have a <ng-container>
which iterates through all the validations the username has and checks if it should show the corresponding error message or not.
Another option for error messages
You could also choose to display errors from the html like in the code below. However, we don't recommend this way because you have the error messages tied to the html of the page. We recommend the way explained before.
Last updated