Web Programming TutorialsLearn How to build a Model-driven forms app in Angular 2

Learn How to build a Model-driven forms app in Angular 2

model-driven-forms

In this chapter, we are going to build a Model-driven forms app in Angular 2.0 by using the following two approaches.
1. FormGroup and FormControl.
2. FormGroup and FormBuilder.

Comparison between template-driven and model-driven form
Both template-driven form and model-driven form differs from each other as the former allows us to write as little JavaScript code as possible to prepare the sophisticated forms and the latter makes the testing of a form easy as it doesn’t require end-to-end testing. It prepares forms imperatively out of the properties on the available components. Model-driven forms are also known as reactive forms and can be thought of as the addition to the template-driven forms such as validators on DOM elements etc.

1. FormGroup and FormControl
The following is the app structure for this type of model-driven form in Angular 2.0

app/main.ts

import { platformBrowserDynamic }    from '@angular/platform-browser-dynamic';
import { AppModule } from './app-module';

platformBrowserDynamic().bootstrapModule(AppModule);

Explanation of Code:
The above main.ts file is used to Bootstrap the angular 2.0 app that uses the root component from the NgModule.

app/app-module.ts

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

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

Explanation of Code:
The root App Module typescript file is present in the app package. Here, we are importing the NgModule, BrowserModule, FormsModule, ReactiveFormsModule, and AppComponent classes as shown above. The @NgModule decorator declared here has imports, declaration classes and bootstrap class to start the app.

app/app-component.ts

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

@Component({
  selector: 'my-modal-form-app',
  templateUrl: 'resource/app-component.html',
  styleUrls:  ['assets/styles.css'],
})
 
export class AppComponent implements OnInit {

 ngOnInit (){
  registerForm = new FormGroup({
    first_name: new FormControl(),
    last_name: new FormControl(),
    phone: new FormControl(),
    email: new FormControl(),
      address: new FormGroup({
      	street: new FormControl(),
      	zip: new FormControl(),
      	city: new FormControl()
      })
    });
   }
}

Explanation of Code:
It has the selector ‘my-modal-form-app’ which is used on the index.html to load the complete app on the browser. It has the template URL as ‘resource/app-component.html’ and styleUrls as ‘assets/styles.css’ as shown below. In the controller class ‘AppComponent’, we are implementing OnInit interface for the method ‘ngOnInit ()’, where we are using the FormGroup and FormControl classes to create a model-driven form in Angular 2.0. Both FormGroup and FormControl are low level APIs where the FormGroup always represents a set of FormControls. They collectively form the model-driven form in Angular 2.0.

FormGroup: This class is present in the ‘@angular/forms’ package of Angular 2.0. It is used to represent a set of form controls inside its constructor as shown above.
FormControl: This class is present in the ‘@angular/forms’ package of Angular 2.0. Each of the form element defined above has an associated FormControl with it.

Here, we can notice the nested FormGroup i.e. address which has street, zip and city as three form elements associated with the respective FormControl. In order to drive this form model-driven, we need to write the HTML code in the template that represents that DOM structure in our component as shown below.

resource/app-component.html

<div align="center">
	<h2>Model-driven Form</h2><br><br>
	<form [formGroup]="registerForm">
		<label>First Name:</label> <input type="text"
			formControlName="first_name"><br>
		<br> <label>Last Name:</label> <input type="text"
			formControlName="last_name"><br>
		<br> <label>Phone:</label> <input type="text"
			formControlName="phone"><br>
		<br> <label>Email:</label> <input type="text"
			formControlName="email"><br>
		<br>
		<fieldset formGroupName="address">
			<label>Street:</label> <input type="text" formControlName="street"><br>
			<br> <label>Zip:</label> <input type="text"
				formControlName="zip"><br>
			<br> <label>City:</label> <input type="text"
				formControlName="city"><br>
			<br>
		</fieldset>
		<button type="submit">Submit</button>
	</form>
</div>
<br>
<hr>

Explanation of Code:
It is the HTML code template for ‘app-component-ts’. Here, we can notice that this model-driven form has ‘[formGroup]=”registerForm”’, and each of the form element has ‘formControlName’ exactly what we defined in AppComponent class. Also, for the nested FormGroup ‘address’, we have used the ‘fieldset’ tag with the ‘formGroupName’ directive (i.e.).
assets/styles.css

h1, h2, h3 {
  color: #444;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: lighter;
}
body, input[text], button {
  color: #588;
  font-family: sans-serif;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
}
a {
  cursor: pointer;
  cursor: hand;
}
button {
  font-family: Arial;
  background-color: #eee;
  border: none;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
  cursor: hand;
}
button:hover {
  background-color: #cmh8dc;
}
button:disabled {
  background-color: #eee;
  color: #ava;
  cursor: auto;
}
nav a {
  padding: 5px 10px;
  text-decoration: none;
  margin-top: 10px;
  display: inline-block;
  background-color: #eee;
  border-radius: 4px;
}
nav a:visited, a:link {
  color: #607D8B;
}
nav a:hover {
  color: #039be5;
  background-color: #CFD8DC;
}
nav a.active {
  color: #039be5;
}
/* everywhere else */
* {
  font-family: Arial, Helvetica, sans-serif;
}

Explanation of Code:
It is the stylesheet used to style the text on the web page of the app.

Index.html

<html>
<head>
<title>Custom form Controls Angular 2.0</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/styles.css">
<!-- 1. Load libraries -->
<!-- Poly-fills for the older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<link rel="stylesheet" 
      href="node_modules/bootstrap/dist/css/bootstrap.min.css">
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
      System.import('app').catch(
    		  function(err){ 
    			  console.error(err); 
    			  }
    		  );
</script>
</head>
<!-- 3. Display the application -->
<body>
		<my-modal-form-app>A moment please...</my-modal-form-app>
</body>
</html>

Explanation of Code:
It is the ‘index.html’ file that has the ‘my-modal-form-app’ tag in its body section i.e. selector defined in the ‘app-component’ to load and display the complete application. Here, we are including all the paths for the scripts which are required for the Angular 2.0 build as shown above.

Output
When we run the above angular 2.0 model-driven form app by executing the command ‘npm start’ on command line that has pointer to the application’s root directory ‘angular2-model-driven-forms’ then we will observe the following output.
output1
Source Code for FormGroup and FormControl

2. FormGroup and FormBuilder.
In the last approach of FormGroup and FormControl, we have written FormGroup and FormControl multiple times which makes the code quite verbose. We can reduce the coding effort by the use of a high level API known as FormBuilder. FormBuilder has a .group () method that makes this task very easy and act a factory for the creation of the FormGroup’s and FormControl’s for the form. Therefore, our ‘app-component.ts’ file will look as follows.

app/app-component.ts

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

@Component({
  selector: 'my-modal-form-app',
  templateUrl: 'resource/app-component.html',
  styleUrls:  ['assets/styles.css'],
})
 
export class AppComponent implements OnInit {

registerForm: FormGroup;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.registerForm = this.formBuilder.group({
      first_name: 'Aparjita',
      last_name: 'Jain',
      phone: '0123456',
      email: '[email protected]',
      address: this.formBuilder.group({
        street: 'Yonge',
        zip: 'XXX VVB',
        city: 'Toronto'
      })
    });
  }
}

Explanation of Code:
Here, we are able to create the form model by using ‘FormBuilder.group()’ in ‘ngOnInit()’ lifecycle as the AppComponent class implements ‘OnInit’ interface. Also, here we are able to initialize the default values to the model-driven form as shown above.

Output
When we run the program, after making this change to ‘app-component.ts’, then we will observe the following output.
output2
Source Code for FormGroup and FormBuilder.

Conclusion:
In this chapter, we have built a model-driven form app in Angular 2.0 by using the FormGroup, FormControl, and FormBuilder classes of ‘@angular/forms’ (i.e. low level and high level APIs).

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -