Forms are an essential part of many web applications, being the most common way to enter and edit text-based data. Front-end JavaScript frameworks such as Angular, often have their own idiomatic ways of creating and validating forms that you need to get to grips with to be productive.
Angular allows you to streamline this common task by providing two types of forms that you can create:
- Template-driven forms - simple forms that can be made rather quickly.
- Reactive forms - more complex forms that give you greater control over the elements in the form.
In this article, we'll make a simple example form with each method to see how it's done.
Prerequisites
You do not need to know all the details of how to create an Angular application to understand the framework's usefulness when it comes to forms. However, if you want to get a better grasp of Angular, you can take a look at this SitePoint article series on building a CRUD app with Angular.
Requirements
We will use Bootstrap in this tutorial. It is not an integral part of an Angular application, but it will help us streamline our efforts even further by providing ready-made styles.
This is how you can add it to your application:
-
Open the command prompt and navigate to the folder of your project
-
Type
npm install bootstrap@next
. This will add the latest version of bootstrap to the project -
Edit the
.angular-cli.json
file and add a link to the Bootstrap CSS file"apps": [ "styles": [ "../node_modules/bootstrap/dist/css/bootstrap.css" ] ]
We will not use the Bootstrap JavaScript file in this application.
-
Both template-driven Forms and Reactive Forms require the
FormsModule
. It should be added to the application inapp.module
:import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ BrowserModule, FormsModule ] })
With that out of the way, we can proceed with the forms themselves.
Template-Driven Forms
Let us assume you want to create a simple form as quickly as possible. For example, you need a company registration form. How can you create the form?
The first step is to create the <form>
tag in your view.
<form #companyForm="ngForm">
We need to modify this tag in two ways in order to submit the form and use the information from the input fields in our component:
- We will declare a template variable using the
ngForm
directive. - We will bind the
ngSubmit
event to a method we will create in our component
<form #companyForm="ngForm" (ngSubmit)="submitCompany(companyForm.form);">
We will create the submitCompany
method in the component a bit later. It will be called when the form is submitted and we will pass it the data from the form via companyForm.form
.
We also need a submit button, regardless of the content of the form. We will use a few Bootstrap classes to style the button. It is good practice to disable the button before all the data validation requirements are met. We can use the template variable we created for the form to achieve this. We will bind the disabled property to the valid property of the companyForm
object. This way the button will be disabled if the form is not valid.
<button class="btn btn-primary" [disabled]="!companyForm.valid">Submit</button>
Let us assume our simple form will have two fields - an input field for the name of the company and a drop-down field for the company's industry.
Creating form inputs
First, we create an input field for the name:
<input type="text"
class="form-control"
name="company-name">
Right now we have a standard input with the type, name and class attributes. What do we need to do to use the Angular approach on our input?
We need to apply the ngModel
directive to it. Angular will create a control object and associate it with the field. Essentially, Angular does some of the work for you behind the scenes.
This is a good time to mention that ngModel
requires the input field to have a name or the form control must be defined as standalone in ngModelOptions
. This is not a problem because our form already has a name. Angular will use the name attribute to distinguish between the control objects.
In addition, we should specify a template variable for the input: #nameField
in this case. Angular will set nameField
to the ngModel
directive that is applied to the input field. We will use this later for the input field's validation. This variable will also allow us to perform an action based on the value of the field while we are typing in it.
Now our input looks like this:
<input type="text"
class="form-control"
name="company-name"
ngModel
#nameField="ngModel">
It is almost the same, but with a few key changes.
Validation
Let us assume we want the company name field to be required and to have a minimum length of 3 characters. This means we have to add the required
and minlength
attributes to our input:
<input type="text"
class="form-control"
name="company-name"
ngModel
#nameField="ngModel"
required
minlength="3">
Sounds simple enough, right? We will also need to display an error message if any of these two requirements are not met. Angular allows us to check the input's value and display the appropriate error message before the form is submitted.
We can perform such a check while the user is typing in the form. First of all, it is a good idea to display an error only after the user has started to interact with the form. There is no use in displaying an error message right after we load the page. This is why we will insert all the error messages for this input inside the following div:
<div *ngIf="nameField.touched && nameField.errors"></div>
The ngIf
directive allows us to show the div only when a specific condition is true. We will use the nameField
template variable again here because it is associated with the input. In our case, the div will be visible only, if the input has been touched and there is a problem with it. Alright, what about the error messages themselves?
We will place another div inside the aforementioned one for each error message we want. We will create a new div for the error message and use the nameField
template variable again:
<div class="alert alert-danger"
*ngIf="nameField.errors.required">
The company name is required
</div>
We are using the "alert alert-danger" bootstrap classes to style the text field. The nameField
variable has the property errors
, which contains an object with key-value pairs for all the current errors. The ngIf
directive allows us to show this error message only when the 'required' condition is not met. We will use the same approach for the error message about the minimum length.
Continue reading %Quickly Create Simple yet Powerful Angular Forms%
by Kaloyan Kolev via SitePoint
No comments:
Post a Comment