Angular

Angular 2 Forms Tutorial – Introduction


Introduction

HTML forms are an essential part of every data-driven web application. The user is able to enter data by using input elements of forms. Therefore a form does not only present data entry fields in the right order but also needs to offer further guidance. Any modern web form will deliver immediate feedback, so that the user is able to see if any input errors occurred before finally submitting the data.

In this tutorial you will learn how to start building forms using the Angular 2 framework. Angular 2 offers a lot of building blocks which makes implementing forms straight forward. In the following you’ll find a step-by-step introduction of how to set-up a new initial Angular 2 application, import the Angular 2 forms module and implement a simple data entry form.

Project Setup

The easiest way to get started with a new initial Angular 2 project is to use Angular 2 CLI to setup a new project.

If you haven’t installed Angular 2 CLI yet, first install the package by using NPM:

$ npm install -g angular-cli

Having installed Angular 2 CLI successfully the ng command becomes available and you can initiate a new project by using this command in the following way:

$ ng new angular-forms-app-01

A new folder angular-forms-app-01 is created a initial Angular 2 project template is downloaded. To check that everything was sucessfully initialized change into the new directory and start the application server:

$ cd angular-forms-app-01
$ ng serve

After having started the web server the application can be accessed in the browser:

01

Create a Data Model Class

Before starting implementing the form, we need to create a data model in our application that corresponds to the data entry fields which will be available in the form we’re going to implement in the next steps. Create a new file src/app/book.model.ts and insert the following code:

export class Book {
  constructor(
    public id: number,
    public title: string,
    public author: string,
    public url?: string
  ) { }
}

The TypeScript compiler generates a public field for each public constructor parameter and assigns the parameter’s value to that field automatically when we create new books.

Import FormsModule

To be able to use Angular 2 forms the FormsModule needs to be imported in our application. To make it available application-wide we’re importing in app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule
  ],
  declarations: [
    AppComponent,
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

As you can see, we need to make two adaptions to the default implementation of AppModule. The first thing which has been added is the import statement on top of the file:

import { FormsModule } from '@angular/forms';

With this import statement we’re importing FormsModule from the @angular/forms library.

Second, we’re attaching FormsModule to the imports array of @NgModule. Herewith we’re making sure the all of Angular’s form features are available to components belonging to AppModule.

Create a Form Component

Scaffolding a New Component

To implement the book form let’s create another form component in our application. With Angular 2 CLI that’s easy. On the command line switch into the project folder and execute the following command:

$ ng g component book-form

The command is generating four files in folder src/app/book-form as you can see in the following screenshot:

02

The scaffolding process does not only generate the four files but also imports BookFormComponent in AppModule. If you take a look into app.module.ts you’ll see that two things have been added.

An import statement for BookFormComponent has been added:

import { BookFormComponent } from './book-form/book-form.component';

Furthermore BookFormComponent has been added to the declarations array of the @NgModule decorator:

@NgModule({
  declarations: [
    AppComponent,
    BookFormComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [],
    bootstrap: [AppComponent]
  })
export class AppModule { }

Implementing The Form Template

Now that the BookFormComponent is available and has been added to AppModule we can continue to implement the form template in file book-form.component.html:

<div class="container">
    <h1>Book Form</h1>
    <form>
      <div class="form-group">
        <label for="title">Title</label>
        <input type="text" class="form-control" id="title" required>
      </div>
      <div class="form-group">
        <label for="author">Author</label>
        <input type="text" class="form-control" id="author" required>
      </div>
      <div class="form-group">
        <label for="url">URL</label>
        <input type="text" class="form-control" id="url">
      </div>
      <button type="submit" class="btn btn-default">Submit</button>
    </form>
</div>

We’re making use of container, form-group, btn and btn-default class for styling of the form elements. All these classes are part of the Bootstrap framework, so Bootstrap needs to be added as a dependency to our project:

$ npm install bootstrap —save

Next the Bootstrap classes needs to be made available by including the Bootstrap CSS file in the header section of index.html:

<link rel="stylesheet"
href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">

To display the form in the browser we need to include the BookFormComponent in the template of AppComponent. But before completing that step, first open book-form.component.ts and set the selector property to string value ‘book-form’.

selector: 'book-form'

Next open the template file app.component.html, delete the content and insert the following line of code to include BookFormComponent:

<book-form></book-form>

Having made that change the output in the browser should now look like the following:

02-02

Implementing Two-Way Data Binding

Now that the form template is ready and the form is displayed in the browser we need to find a way to access the form data. Angular 2 offers the concept of two-way data binding which helps us to solve that problem.

To enable two-way data binding we need to extend the form template and use the ngModel directive in the input elements. The extended form template code with ngModel looks like the following:

<div class="container">
  <h1>Book Form</h1>
  <form>
    <div class="form-group">
      <label for="title">Title</label>
      <input type="text" class="form-control" id="title" required [(ngModel)]="model.title" name="title">
    </div>
    <div class="form-group">
      <label for="author">Author</label>
      <input type="text" class="form-control" id="author" required [(ngModel)]="model.author" name="author">
    </div>
    <div class="form-group">
      <label for="url">URL</label>
      <input type="text" class="form-control" id="url" [(ngModel)]="model.url" name="url">
    </div>
    <button type="submit" class="btn btn-default">Submit</button>
  </form>
</div>

The binding syntax is

[(ngModel)]="..."

Notice that, together with ngModel, we also added the name attribute to each element. We’re assinging a unique string value to this attribute. Defining a name attribute is a requirement when using [(ngModel)] in combination with a form. Why is this a requirement? For each input element with a name attribute assigned Angular 2 created internally a FormControl. Furthermore these FormControls are registered with an NgForm directive which is automatically created for each <form> element in the template code. Each FormControl is registered under the name we assigned to the name attribute.

Display Model Data

Now that we’ve established two-way data binding for our book form, we’re able to access the value which is entered in the input fields of the form by accesing the model properties which have been assigned to the ngModel:

  • model.title
  • model.author
  • model.url

Open the implementation of BookFormComponent in file book-form.component.ts

import { Component, OnInit } from '@angular/core';

import { Book } from '../book.model';

@Component({
  selector: 'book-form',
  templateUrl: './book-form.component.html',
  styleUrls: ['./book-form.component.css']
})
export class BookFormComponent implements OnInit {
  model = new Book(1, '', '', 'http://');

  constructor() { }

  ngOnInit() {
  }

  get currentBook() { return JSON.stringify(this.model); }
}

To check that the data binding is working we’re including currentBook as an expression in the template code as follows:

<div>
<h2>Model:</h2>
{{ currentBook }}
</div>

This prints out the model properties in JSON format as you can see in the following screenshot:

03

With this output available we’re able to check that the model binding is fully working. Each change of the input field values which is done by the user is directly reflected in the model output below. So we’re able to read out form values by accessing properties of our model object.

Conclusion

Angular 2 has great form features and makes developing rich HTML forms very easy. In this post you’ve learnt how to get started with Angular 2 forms. This is the beginning of a series of tutorials focusing on Angular 2 forms. In next part we’ll dive deeper into the topic and extend the form to also include validation logic with direct and instant user feedback. Stay tuned!

ONLINE COURSE: Angular - The Complete Guide

Check out the great Angular – The Complete Guide with thousands of students already enrolled:

Angular – The Complete Guide

  • This course covers Angular 4
  • Develop modern, complex, responsive and scalable web applications with Angular
  • Use their gained, deep understanding of the Angular 2 fundamentals to quickly establish themselves as frontend developers
  • Fully understand the architecture behind an Angular 2 application and how to use it
  • Create single-page applications with on of the most modern JavaScript frameworks out there

Go To Course


Using and writing about best practices and latest technologies in web design & development is my passion.

    View Comments

    *