Getting Access to Controls in Angular using Reactive Forms

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  genders = ['male', 'female'];
  signupForm: FormGroup;

  ngOnInit(): void {
    this.signupForm = new FormGroup({
      'username': new FormControl(null, Validators.required),
      'email': new FormControl(null, [Validators.required, Validators.email]),
      'gender': new FormControl('male') // default value for radiobutton => male
    })
    ;
  }

  onSubmit() {
    console.log(this.signupForm);
  }
}

app.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
        <div class="form-group">
          <label for="username">Username</label>
          <input
            type="text"
            id="username"
            class="form-control"
            formControlName="username">
          <span
            *ngIf="!signupForm.get('username').valid && signupForm.get('username').touched"
            class="help-block">Please enter a valid username</span>
        </div>
        <div class="form-group">
          <label for="email">email</label>
          <input
            type="text"
            id="email"
            class="form-control"
            formControlName="email">
          <span
            *ngIf="!signupForm.get('email').valid && signupForm.get('email').touched"
            class="help-block">Please enter a valid email</span>
        </div>
        <div class="radio" *ngFor="let gender of genders">
          <label>
            <input
              type="radio"
              [value]="gender"
              formControlName="gender">{{ gender }}
          </label>
        </div>
        <span
          *ngIf="!signupForm.valid && signupForm.touched"
          class="help-block">Please enter valid data</span>
        <button class="btn btn-primary" type="submit">Submit</button>
      </form>
    </div>
  </div>
</div>

app.component.css

.container {
  margin-top: 30px;
}

.input.ng-invalid.ng-touched {
  border: 1px solid red;
}

 

Adding Validation in Angular using Reactive Forms

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  genders = ['male', 'female'];
  signupForm: FormGroup;

  ngOnInit(): void {
    this.signupForm = new FormGroup({
      'username': new FormControl(null, Validators.required),
      'email': new FormControl(null, [Validators.required, Validators.email]),
      'gender': new FormControl('male') // default value for radiobutton => male
    })
    ;
  }

  onSubmit() {
    console.log(this.signupForm);
  }
}

 

Creating a Form in Angular using Reactive Forms

app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';

import {AppComponent} from './app.component';

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

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  genders = ['male', 'female'];
  signupForm: FormGroup;

  ngOnInit(): void {
    this.signupForm = new FormGroup({
      'username': new FormControl(null),
      'email': new FormControl(null),
      'gender': new FormControl('male') // default value for radiobutton => male
    })
    ;
  }

  onSubmit() {
    console.log(this.signupForm);
  }
}

app.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
        <div class="form-group">
          <label for="username">Username</label>
          <input
            type="text"
            id="username"
            class="form-control"
            formControlName="username">
        </div>
        <div class="form-group">
          <label for="email">email</label>
          <input
            type="text"
            id="email"
            class="form-control"
            formControlName="email">
        </div>
        <div class="radio" *ngFor="let gender of genders">
          <label>
            <input
              type="radio"
              [value]="gender"
              formControlName="gender">{{ gender }}
          </label>
        </div>
        <button class="btn btn-primary" type="submit">Submit</button>
      </form>
    </div>
  </div>
</div>

References
https://angular.io/guide/reactive-forms

Resetting Forms in Angular Template-driven forms

onSubmit() {
  this.user.username = this.signupForm.value.myUserData.username;
  this.user.email = this.signupForm.value.myUserData.email;
  this.user.question = this.signupForm.value.secret;
  this.user.answer = this.signupForm.value.questionAnswer;
  this.user.gender = this.signupForm.value.gender;
  this.submitted = true;

  this.signupForm.reset();
}

 

Using Form Data in Angular Template-driven forms

app.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form (ngSubmit)="onSubmit()" #myForm="ngForm">
        <div id="user-data"
             ngModelGroup="myUserData"
             #myUserData="ngModelGroup">
          <div class="form-group">
            <label for="username">Username</label>
            <input type="text" id="username" class="form-control"
                   ngModel name="username"
                   required>
          </div>
          <button class="btn btn-default" type="button"
                  (click)="suggestUserName()">Set All Values
          </button>

          <button class="btn btn-default" type="button"
                  (click)="overrideUseName()">Override Part of Values
          </button>
          <div class="form-group">
            <label for="email">Mail</label>
            <input type="email" id="email" class="form-control"
                   ngModel name="email"
                   required email
                   #myEmail="ngModel">
            <span class="help-block" *ngIf="!myEmail.valid && myEmail.touched">Please enter a valid email!</span>
          </div>
        </div>
        <p *ngIf="!myUserData.valid && myUserData.touched">User Data is invalid!</p>
        <div class="form-group">
          <label for="secret">Secret Questions</label>
          <select id="secret" class="form-control"
                  [ngModel]="'pet'"
                  name="secret">
            <option value="pet">Your first Pet?</option>
            <option value="teacher">Your first teacher?</option>
          </select>
          <div class="form-group">
            <textarea name="questionAnswer" rows="3" class="form-control"
                      [(ngModel)]="answer"></textarea>
          </div>
        </div>
        <div>Your replay: {{answer}}</div>
        <div class="radio" *ngFor="let gender of genders">
          <label>
            <input type="radio" required name="gender" ngModel [value]="gender">
            {{gender}}
          </label>
        </div>
        <button class="btn btn-primary" type="submit"
                [disabled]="!myForm.valid">Submit
        </button>
      </form>
    </div>
  </div>
  <hr/>
  <div class="row" *ngIf="submitted">
    <div class="col-xs-12">
      <h3>Your Data</h3>
      <p>Username: {{user.username}}</p>
      <p>Mail: {{user.email}}</p>
      <p>Secret Question: {{user.question}}</p>
      <p>Answer: {{user.answer}}</p>
      <p>Gender: {{user.gender}}</p>
    </div>
  </div>
</div>

app.component.ts

import {Component, ViewChild} from '@angular/core';
import {NgForm} from '@angular/forms';

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

  @ViewChild('myForm') signupForm: NgForm;
  answer: string;
  genders = ['male', 'female'];
  user = {
    username: '',
    email: '',
    question: '',
    answer: '',
    gender: ''
  };
  submitted = false;

  /**
   * Set values all together
   */
  suggestUserName() {
    const suggestedName = 'Superuser';
    this.signupForm.setValue({
      myUserData: {
        username: suggestedName,
        email: '[email protected]'
      },
      secret: 'pet',
      questionAnswer: 'Hello Wolrd',
      gender: 'male'
    });
  }

  /**
   * Set part of values
   */
  overrideUseName() {
    const suggestedName = 'Superuser';
    this.signupForm.form.patchValue({
      myUserData: {
        username: suggestedName
      }
    });
  }


  onSubmit() {
    this.user.username = this.signupForm.value.myUserData.username;
    this.user.email = this.signupForm.value.myUserData.email;
    this.user.question = this.signupForm.value.secret;
    this.user.answer = this.signupForm.value.questionAnswer;
    this.user.gender = this.signupForm.value.gender;
    this.submitted = true;
  }
}

 

Setting and Patching Form Values in Angular Template-driven forms

app.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form (ngSubmit)="onSubmit()" #myForm="ngForm">
        <div id="user-data"
             ngModelGroup="myUserData"
             #myUserData="ngModelGroup">
          <div class="form-group">
            <label for="username">Username</label>
            <input type="text" id="username" class="form-control"
                   ngModel name="username"
                   required>
          </div>
          <button class="btn btn-default" type="button"
                  (click)="suggestUserName()">Set All Values
          </button>

          <button class="btn btn-default" type="button"
                  (click)="overrideUseName()">Override Part of Values
          </button>
          <div class="form-group">
            <label for="email">Mail</label>
            <input type="email" id="email" class="form-control"
                   ngModel name="email"
                   required email
                   #myEmail="ngModel">
            <span class="help-block" *ngIf="!myEmail.valid && myEmail.touched">Please enter a valid email!</span>
          </div>
        </div>
        <p *ngIf="!myUserData.valid && myUserData.touched">User Data is invalid!</p>
        <div class="form-group">
          <label for="secret">Secret Questions</label>
          <select id="secret" class="form-control"
                  [ngModel]="'pet'"
                  name="secret">
            <option value="pet">Your first Pet?</option>
            <option value="teacher">Your first teacher?</option>
          </select>
          <div class="form-group">
            <textarea name="questionAnswer" rows="3" class="form-control"
                      [(ngModel)]="answer"></textarea>
          </div>
        </div>
        <div>Your replay: {{answer}}</div>
        <div class="radio" *ngFor="let gender of genders">
          <label>
            <input type="radio" required name="gender" ngModel [value]="gender">
            {{gender}}
          </label>
        </div>
        <button class="btn btn-primary" type="submit"
                [disabled]="!myForm.valid">Submit
        </button>
      </form>
    </div>
  </div>
</div>

app.component.ts

import {Component, ViewChild} from '@angular/core';
import {NgForm} from '@angular/forms';

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

  @ViewChild('myForm') signupForm: NgForm;
  answer: string;
  genders = ['male', 'female'];

  /**
   * Set values all together
   */
  suggestUserName() {
    const suggestedName = 'Superuser';
    this.signupForm.setValue({
      myUserData: {
        username: suggestedName,
        email: '[email protected]'
      },
      secret: 'pet',
      questionAnswer: 'Hello Wolrd',
      gender: 'male'
    });
  }

  /**
   * Set part of values
   */
  overrideUseName() {
    const suggestedName = 'Superuser';
    this.signupForm.form.patchValue({
      myUserData: {
        username: suggestedName
      }
    });
  }


  onSubmit() {
    console.log(this.signupForm);
  }
}

 

Handling Radio Buttons in Angular Template-driven forms

app.component.ts

import {Component, ViewChild} from '@angular/core';
import {NgForm} from '@angular/forms';

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

  @ViewChild('myForm') signupForm: NgForm;
  answer: string;
  genders = ['male', 'female'];

  suggestUserName() {
    const suggestedName = 'Superuser';
  }

  // onSubmit(form: NgForm) {
  //   console.log(form);
  // }


  onSubmit() {
    console.log(this.signupForm);
  }
}

app.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form (ngSubmit)="onSubmit()" #myForm="ngForm">
        <div id="user-data"
             ngModelGroup="myUserData"
             #myUserData="ngModelGroup">
          <div class="form-group">
            <label for="username">Username</label>
            <input type="text" id="username" class="form-control"
                   ngModel name="username"
                   required>
          </div>
          <button class="btn btn-default" type="button">Suggest an Username</button>
          <div class="form-group">
            <label for="email">Mail</label>
            <input type="email" id="email" class="form-control"
                   ngModel name="email"
                   required email
                   #myEmail="ngModel">
            <span class="help-block" *ngIf="!myEmail.valid && myEmail.touched">Please enter a valid email!</span>
          </div>
        </div>
        <p *ngIf="!myUserData.valid && myUserData.touched">User Data is invalid!</p>
        <div class="form-group">
          <label for="secret">Secret Questions</label>
          <select id="secret" class="form-control"
                  [ngModel]="'pet'"
                  name="secret">
            <option value="pet">Your first Pet?</option>
            <option value="teacher">Your first teacher?</option>
          </select>
          <div class="form-group">
            <textarea name="questionAnswer" rows="3" class="form-control"
                      [(ngModel)]="answer"></textarea>
          </div>
        </div>
        <div>Your replay: {{answer}}</div>
        <div class="radio" *ngFor="let gender of genders">
          <label>
            <input type="radio" required name="gender" ngModel [value]="gender">
            {{gender}}
          </label>
        </div>
        <button class="btn btn-primary" type="submit"
                [disabled]="!myForm.valid">Submit
        </button>
      </form>
    </div>
  </div>
</div>

 

Grouping Form Controls in Angular Template-driven forms

app.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form (ngSubmit)="onSubmit()" #myForm="ngForm">
        <div id="user-data"
             ngModelGroup="myUserData"
             #myUserData="ngModelGroup">
          <div class="form-group">
            <label for="username">Username</label>
            <input type="text" id="username" class="form-control"
                   ngModel name="username"
                   required>
          </div>
          <button class="btn btn-default" type="button">Suggest an Username</button>
          <div class="form-group">
            <label for="email">Mail</label>
            <input type="email" id="email" class="form-control"
                   ngModel name="email"
                   required email
                   #myEmail="ngModel">
            <span class="help-block" *ngIf="!myEmail.valid && myEmail.touched">Please enter a valid email!</span>
          </div>
        </div>
        <p *ngIf="!myUserData.valid && myUserData.touched">User Data is invalid!</p>
        <div class="form-group">
          <label for="secret">Secret Questions</label>
          <select id="secret" class="form-control"
                  [ngModel]="'pet'"
                  name="secret">
            <option value="pet">Your first Pet?</option>
            <option value="teacher">Your first teacher?</option>
          </select>
          <div class="form-group">
            <textarea name="questionAnswer" rows="3" class="form-control"
                      [(ngModel)]="answer"></textarea>
          </div>
        </div>
        <div>Your replay: {{answer}}</div>
        <button class="btn btn-primary" type="submit"
                [disabled]="!myForm.valid">Submit
        </button>
      </form>
    </div>
  </div>
</div>

 

Using ngModel with Two-Way-Binding in Angular Template-driven forms

app.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form (ngSubmit)="onSubmit()" #myForm="ngForm">
        <div id="user-data">
          <div class="form-group">
            <label for="username">Username</label>
            <input type="text" id="username" class="form-control"
                   ngModel name="username"
                   required>
          </div>
          <button class="btn btn-default" type="button">Suggest an Username</button>
          <div class="form-group">
            <label for="email">Mail</label>
            <input type="email" id="email" class="form-control"
                   ngModel name="email"
                   required email
                   #myEmail="ngModel">
            <span class="help-block" *ngIf="!myEmail.valid && myEmail.touched">Please enter a valid email!</span>
          </div>
        </div>
        <div class="form-group">
          <label for="secret">Secret Questions</label>
          <select id="secret" class="form-control"
                  [ngModel]="'pet'"
                  name="secret">
            <option value="pet">Your first Pet?</option>
            <option value="teacher">Your first teacher?</option>
          </select>
          <div class="form-group">
            <textarea name="questionAnswer" rows="3" class="form-control"
                      [(ngModel)]="answer"></textarea>
          </div>
        </div>
        <div>Your replay: {{answer}}</div>
        <button class="btn btn-primary" type="submit"
                [disabled]="!myForm.valid">Submit
        </button>
      </form>
    </div>
  </div>
</div>