Developer Snippet Diary

Forms and form validation

HTML CODE

1.  using  local template reference variable

<form class="contact-form needs-validation"  novalidate #myForm="ngForm" (ngSubmit)="handleForm(myForm)">
  <input required email minlength="4" type="email" #email='ngModel' name="email" ngModel>
  
  <div *ngIf="email.invalid && (email.dirty || email.touched)" class="alert alert-danger">
      <div *ngIf="email.errors?.['required']">
        Email is required.
      </div>
      <div *ngIf="email.errors?.['minlength']">
        Email must be at least 6 characters long.
      </div>
      <div *ngIf="email.errors?.['email']">
        Its not correct Email
      </div>
      
  </div>
    <input type="submit" class="btn btn-outline-primary rounded-pill btn-send mb-3" value="Subscribe" (click)="myForm.form.markAllAsTouched()">
</form>

COMPONENT

export class EmailSubscriptionComponent {
  handleForm(data:any){
    if (data.valid) {
      // Form is valid, perform submission logic here
    } else {
      // Form is invalid, handle the validation errors or display an error message
    }
    console.log(data.value);
  }
}

FOR Select dropdown

component.ts

  subsForm_frequency:string ='0';

html

<div class="col-4">
<div class="form-select-wrapper mb-4">
  <select class="form-select" aria-label="Default select example" name="frequency"  [(ngModel)]="subsForm_frequency">
    <option value="0">Alert Frequency</option>
    <option value="1">Daily</option>
    <option value="2">Weekly</option>
  </select>
</div>
</div>

Lets break down the code:

<input> element representing the email input field. It has the following attributes and directives:

  • required: Specifies that the field must be filled in before submitting the form.
  • email: Indicates that the input value should be a valid email address format.
  • minlength="4": Specifies the minimum length of the input value to be 4 characters.
  • type="email": Indicates that the input type is "email" to enable email-specific browser validation.
  • #email='ngModel': Declares a local template reference variable "email" and assigns it to the NgModel directive for the input field.

To display the validation errors when the submit button is clicked, we use

(click)="myForm.form.markAllAsTouched()"

 

SAME PASSWORD VALIDATION

<input  type="password" name="new_pass" #new_pass='ngModel' ngModel  required="required">
<input  type="password" name="new_pass_cnf" #new_pass_cnf='ngModel' ngModel  required="required">
<div *ngIf="new_pass.value != new_pass_cnf.value" class="alert alert-danger mt-2">
    Passwords don't match.
</div>

 

2. using Reactive form
>>simple form

component.ts

 /*
    Reactive forms provide a model-driven approach to handling form inputs whose values change over time.
    1. app.module.ts
      > import { ReactiveFormsModule } from '@angular/forms';
      > imports: [
         ReactiveFormsModule
       ],
    2. inside component
      import { FormControl } from '@angular/forms';
      
    3. use inside template
      <label for="name">Name: </label>
      <input id="name" type="text" [formControl]="name">
  */
      name = new FormControl('inital value');

    updateName() {
      this.name.setValue('Nancy');
    }

.html

<label for="name">Name: {{name.value}}</label><br/>
<input id="name" type="text" [formControl]="name">
<button type="button" (click)="updateName()">Update Name</button>
<hr>

>> FORM GROUP

component.ts

    /* form group: a form group instance tracks the form state of a group of form control instances (for example, a form).
      1. import { FormGroup } from '@angular/forms';
      2. USE FormGroup
      3. to save data (ngSubmit)="onSubmit()" its  captures the current value of profileForm. Use EventEmitter to keep the form encapsulated and to provide the form value outside the component. 

    
    */

    profileForm = new FormGroup({
      firstName: new FormControl(),
      address: new FormGroup({
        street: new FormControl('bhera'),
        city: new FormControl(''),          
      })
    });
    updateProfile() {
      this.profileForm.patchValue({
        firstName: 'Nancy',
        address: {
          street: '123 Drew Street'
        }
      });
    }

    onSubmit() {
      console.warn(this.profileForm.value);
    }

html

    <h2>FORM GROUP</h2>
    <form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
        <label for="first-name">First Name: </label>
        <input id="first-name" type="text" formControlName="firstName">    
        <div formGroupName="address">
            <h6>Address</h6>          
            <label for="street">Street: </label>
            <input id="street" type="text" formControlName="street">          
            <label for="city">City: </label>
            <input id="city" type="text" formControlName="city">
          </div>
          <button type="button" (click)="updateProfile()">Update Profile</button>
        <button type="submit" [disabled]="!profileForm.valid">Submit</button>
      </form>
      <hr>

>> create form using service

component.ts

    /**
     * Creating form control instances manually can become repetitive when dealing with multiple forms. The FormBuilder service provides convenient methods for generating controls.
     * 1. import { FormBuilder } from '@angular/forms';
     * 2. constructor(private fb: FormBuilder) { }
     * 3. 
     */
    constructor(private fb: FormBuilder) { }
    serviceForm = this.fb.group({
      username: [''],
      
      services: this.fb.group({
        misaj: [''],
        polish: [''],
      }),
    });

html

      <h2>SERVICE TO CREATE FORM</h2>    
      <form [formGroup]="serviceForm">
        <label>username: </label>
        <input type="text" formControlName="username">      
        <div formGroupName="services">
            <h6>services</h6>          
            <input placeholder="misaj" type="text" formControlName="misaj">          
            <input placeholder="polish" type="text" formControlName="polish">
          </div>
        <button type="submit" [disabled]="!serviceForm.valid">Submit</button>
      </form>

>> FORM VALIDATION

component.ts

    /*
      form validation: 
      1.import { Validators } from '@angular/forms'; 
      2. firstName: ['', Validators.required], //make field required
      3. <p>Form Status: {{ profileForm.status }}</p>
    */
export class FormsComponent{
     formValid = new FormGroup({
        nameis: new FormControl('', [Validators.required, Validators.minLength(4),forbiddenNameValidator(/bob/i)]),
      });
}

export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const forbidden = nameRe.test(control.value);
    return forbidden ? {forbiddenName: {value: control.value}} : null;
  };
}

html

 <h2>Form validation</h2>
      <form [formGroup]="formValid">
        <label>Name: </label>
        <input type="text" formControlName="nameis" >
        <div *ngIf="formValid.controls.nameis.invalid && (formValid.controls.nameis.dirty || formValid.controls.nameis.touched)" class="alert alert-danger">
          <div *ngIf="formValid.controls.nameis.errors?.['required']">
            Name is required.
          </div>
          <div *ngIf="formValid.controls.nameis.errors?.['minlength']">
            Name must be at least 4 characters long.
          </div>
          <div *ngIf="formValid.controls.nameis.errors?.['forbiddenName']">
            Name cannot be Bob.
          </div>
        </div> 
    <p>Form Status: {{ formValid.status }}</p>
</form>
Posted by: R GONDAL
Email: rizikmw@gmail.com