An open API service indexing awesome lists of open source software.

https://github.com/dinanathsj29/angular-forms-reactive-tutorial

Lets have a quick overview of Angular's Reactive Model Driven Forms with live practical example.
https://github.com/dinanathsj29/angular-forms-reactive-tutorial

angular-forms dynamic-forms formbuilder formcontrol formcontrolname formgroup ngsubmit reactive-forms setvalidators validators

Last synced: 2 months ago
JSON representation

Lets have a quick overview of Angular's Reactive Model Driven Forms with live practical example.

Awesome Lists containing this project

README

        


Angular logo

Angular Reactive Forms (Model driven)
=====================

Working with existing/cloned/copied Angular App
---------------------
- Clone or Download the project/app from Github or any other sources
- If using Visual Studio Code / Insiders, open Command panel/terminal from menu: View -> Terminal (shortcut key is `CTRL + BackTick` OR `COMMAND + J`)
- Go inside the project/app directory, command: `cd _examples-angular-templateDrivenForm OR cd templateDrivenForm`
- Run command: `npm install` to install project/app dependencies `(node_modules)`
- To Build and run Angular App, command: `ng serve / npm start` OR `ng serve -o` OR `ng serve --open`
- To change the port from 4200 to other port - type command: `ng serve --port 5000`
- To check the application in browser type path/URL: `localhost:4200 / 5000`

1.1. Reactive Model Driven Forms
---------------------
We know that:
- Reactive forms give the ability to control validation from the component code
- Also, we are able to do a unit test of reactive model-driven forms

1.2. Setup Angular Project
---------------------
1. Create a `new Angular project` with command at the console: `ng new angular-reactive-forms-tutorial`
2. Change Directory and get inside the directory with the command: `cd angular-reactive-forms-tutorial` and check angular app folder structure



    Angular project/app folder structure
    Image - Angular project/app folder structure

3. Run/Serve/Build Angular application with the command: `ng serve` or `ng serve -o` or `ng serve --open`
- `-o` or `--open` flag directly launch the application into default browser (default port is `4200`)
- One can also change the port number by using the command: `ng serve --port 5000 -o`
4. Go to browser and type: `http://localhost:5000` to launch an angular application



    Angular default app launch
    Image - Angular default app launch

1.3. Constructing HTML Form structure
=====================
1. In `Index.html` file, in `head` element, link/import/include any front-end UI framework like `Bootstrap` or `Zurb Foundation` which helps to easily style our app/form layout

> **Syntax & Example**: index.html
```html

or

```

2. To verify the Zurb Foundation included/working properly in an application, `check the angular app in browser fonts, etc changed?`
- Right click on page/element and check in `inspect element` the Zurb Foundation classes and properties applied to respective elements:



    Zurb Foundation framework styly applied
    Image - Zurb Foundation framework styly applied

3. From file `app.component.html` delete all old code and add new markup to create form:

> **Syntax & Example**: app.component.html
```html



Beginners Simple Reactive Form


Name


Description


Minimum of 5 Characters Name required
ON


You Entered Name: {{ name }}

Your Description Details: {{ description }}


```



    Simple HTML Form with Zurb Foundation
    Image - Simple HTML Form with Zurb Foundation

1.4. Styling HTML Form with CSS
=====================
- With the `Zurb Foundatio`n framework some styling applied, let us create some custom css style to make form/interface more attractive and intuative

> **Syntax & Example**: styles.css
```css
/* You can add global styles to this file, and also import other style files */

/* apply google font family */
@import url('https://fonts.googleapis.com/css?family=ZCOOL+XiaoWei');

body {
background:rgba(148, 134, 93, 0.35);;
/* font-family: 'ZCOOL XiaoWei', serif !important; */
}

* {
font-family: 'ZCOOL XiaoWei', serif !important;
}

.form-container {
display:block;
width:90%;
padding:2em;
margin: 2em auto;
background:#fff;
}

h1 {
text-align: center;
margin-bottom: 1rem;
font-weight:bold;
}

.button {
margin-top: 1rem;
font-weight: bold;
}

/* error text message alert */
.alert {
background: #f2dada;
padding: 5px;
font-size: .9em;
margin-bottom: 15px;
display: inline-block;
animation: 2s alertAnim forwards;
}

/* animation effect for error text message alert */
@keyframes alertAnim {
from {
opacity:0;
transform: translateY(-20px);
}
to {
opacity:1;
transform: translateY(0);
}
}
```



    CSS Style applied HTML Form
    Image - CSS Style applied HTML Form

1.5. Integrating Rective Form Class
=====================
- To work with reactive/dynamic forms we need to import `'ReactiveFormsModule'` which provides bunch of classes/directives/utilities necessary to build reactive/dynamic forms

1. In `app.module.ts`: import { ReactiveFormsModule } from '@angular/forms';
- also add to imports: [ ReactiveFormsModule ]

**Syntax & Example**: app.module.ts
```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';

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

1.6. Composing Component Class with ReactiveForms building blocks
=====================
- `FormGroup` and `FormControl` are two important building blocks classes for reactive/dynamic forms
- In Reactive forms, the form is represented by `model in component class`, FormGroup and FormControl classes used to make that model
- `FormGroup` represents whole/entire form ( `form` is instance of `FormGroup` class )
- `FormControl` represents each form field ( `form fields` are instance of `FormControl` class )
- `FormBuilder` handle form control creation, dynamic/run time field/FormControl creation
- `Validators` helps to setup validation on each form control

1. In `app.component.ts` import { FormBuilder, FormGroup, Validators } from '@angular/forms'; and write following logical code to build reactive form

**Syntax & Example**: app.component.ts
```typescript
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})

export class AppComponent {

simpleBegReactiveForm: FormGroup; // form
formSubmitPost: any; // A property for our submitted form
name: string = ''; // name text
description: string = ''; // description text

// create a FormBuilder dependecy injection
constructor(private fb: FormBuilder) {

// reference FormBuilder instance to control the validation of each form field
this.simpleBegReactiveForm = fb.group({
'name': ['', Validators.required],
'description': ['', [Validators.required, Validators.minLength(30), Validators.maxLength(100)]],
'validate': ''
});

}

// handler to submit form
submitFormData(formSubmitPost) {
this.description = formSubmitPost.description;
this.name = formSubmitPost.name;
}

}
```

1.7. Update HTML Form (bind Model with View)
=====================
- Lets use and apply class members created in `app.component.ts` for specific field/controls and bind with form and input fields, `([formGroup]="simpleBegReactiveForm", formControlName="name" ...) `

**Syntax & Example**: app.component.html
```html




Beginners Simple Reactive Form


Name


Description


Minimum of 5 Characters Name required
ON



```



    Bind Model with View
    Image - Bind Model with View

1.8. Adding/Showing Validation Messages
=====================
- Now add required validation message text as a alert and use interpolation to show class member

**Syntax & Example**: app.component.html
```html

{{ titleAlertText }}

{{ descriptionAlertText }}

```

**Syntax & Example**: app.component.ts
```typescript
titleAlertText = 'Name field is required';
descriptionAlertText = 'Specify Description between 30 to 100 characters';
```



    Shwoing alert error message text
    Image - Shwoing alert error message text

1.9. Implement Dyanmic Validation with checkbox
=====================
- Sometimes we need to perform form validation based on user input
- Like in current form, If checkbox is `ON` than `Name must required with 5 characters` else `any characters`
- We need to track value of checkbox and conditionaly set status of other field
- `valueChanges` property helps to track the current value of any controls as a observables
- `setValidators` methods - set desired validators to formControl/field
- `clearValidators` methods - clears validators from formControl/field
- Finally we need to invoke/call `updateValueAndValidity` method to reflect latest status

**Syntax & Example**: app.component.ts
```typescript
ngOnInit() {

// subscribe checkbox
this.simpleBegReactiveForm.get('validate').valueChanges.subscribe(

(validate) => {

if (validate == '1') {
// name field set/unset `required` validators
this.simpleBegReactiveForm.get('name').setValidators([Validators.required, Validators.minLength(5)]);
this.titleAlertText = 'Specify Name with 5 characters';
} else {
this.simpleBegReactiveForm.get('name').setValidators(Validators.required);
this.titleAlertText = 'Name field is required';
}
// to reflect latest correct status
this.simpleBegReactiveForm.get('name').updateValueAndValidity();

});
}
```



    Checkbox dynamic validator error
    Image - Checkbox dynamic validator error




    Checkbox dynamic validator success
    Image - Checkbox dynamic validator success




    Submit Data success screen
    Image - Submit Data success screen

1.10. Final working code
=====================
**Syntax & Example**: index.html
```html



AngularReactiveFormsTutorial







```

**Syntax & Example**: app.component.html
```html




Beginners Simple Reactive Form


Name


{{ titleAlertText }}


Description




{{ descriptionAlertText }}


Minimum of 5 Characters Name required
ON


You Entered Name: {{ name }}

Your Description Details: {{ description }}


```

**Syntax & Example**: styles.css
```css
/* You can add global styles to this file, and also import other style files */

/* apply google font family */
@import url('https://fonts.googleapis.com/css?family=ZCOOL+XiaoWei');

body {
background:rgba(148, 134, 93, 0.35);;
/* font-family: 'ZCOOL XiaoWei', serif !important; */
}

* {
font-family: 'ZCOOL XiaoWei', serif !important;
}

.form-container {
display:block;
width:90%;
padding:2em;
margin: 2em auto;
background:#fff;
}

h1 {
text-align: center;
margin-bottom: 1rem;
font-weight:bold;
}

.button {
margin-top: 1rem;
font-weight: bold;
}

/* error text message alert */
.alert {
background: #f2dada;
padding: 5px;
font-size: .9em;
margin-bottom: 15px;
display: inline-block;
animation: 2s alertAnim forwards;
}

/* animation effect for error text message alert */
@keyframes alertAnim {
from {
opacity:0;
transform: translateY(-20px);
}
to {
opacity:1;
transform: translateY(0);
}
}
```

**Syntax & Example**: app.module.ts
```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';

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

**Syntax & Example**: app.component.ts
```typescript
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})

export class AppComponent {

simpleBegReactiveForm: FormGroup; // form
formSubmitPost: any; // A property for our submitted form
name: string = ''; // name text
description: string = ''; // description text

titleAlertText = 'Name field is required';
descriptionAlertText = 'Specify Description between 30 to 100 characters';

// create a FormBuilder dependecy injection
constructor(private fb: FormBuilder) {

// reference FormBuilder instance to control the validation of each form field
this.simpleBegReactiveForm = fb.group({
'name': ['', Validators.required],
'description': ['', [Validators.required, Validators.minLength(30), Validators.maxLength(100)]],
'validate': ''
});

}

// handler to submit form
submitFormData(formSubmitPost) {
this.description = formSubmitPost.description;
this.name = formSubmitPost.name;
}

ngOnInit() {

// subscribe checkbox
this.simpleBegReactiveForm.get('validate').valueChanges.subscribe(

(validate) => {

if (validate == '1') {
// name field set/unset `required` validators
this.simpleBegReactiveForm.get('name').setValidators([Validators.required, Validators.minLength(5)]);
this.titleAlertText = 'Specify Name with 5 characters';
} else {
this.simpleBegReactiveForm.get('name').setValidators(Validators.required);
this.titleAlertText = 'Specify Name with 5 characters';
}
// to reflect latest correct status
this.simpleBegReactiveForm.get('name').updateValueAndValidity();

});
}

}
```