Creating custom Form Controls in Angular

Control
Value
Accessor

What is
a
FormControl

type="color"

<textarea>

<datalist>

type="email"

type="file"

type="range"

type="password"

<datalist>

type="color"

type="file"

type="password"

<textarea>

type="email"

type="range"

What about Angular?

Angular has 2 type of Forms

Template
Driven
Forms

FormsModule

[(ngModel)]

Template Variables

...

Reactive
Forms

ReactiveFormsModule

FormControl

FormGroup

FormBuilder

FormArray

Validators

...

Guess what!!!?

NgModel is a Directive which uses a FormControl itself behind the scenes!

ControlValueAccessor

writeValue()

ControlValueAccessor

Component

formControl.value

Component.myValue

setDisabledState()

ControlValueAccessor

Component

formControl.disabled

Component.isDisabled

  registerOnChange()

ControlValueAccessor

Component

formControl.value

Component.myValue

   registerOnTouched()

ControlValueAccessor

Component

formControl.touched

Component.isDirty

Let's jump into the <CODE>

import { ControlValueAccessor } from '@angular/forms';
 
@Component({...})
export class RatingComponent implements OnInit, ControlValueAccessor {
  ...
  constructor() { }
 
  onChange: any = () => { };
  onTouched: any = () => { };
 
  ngOnInit(): void {
  }
  ...
  registerOnChange(fn: any){
    this.onChange = fn;
  }
 
  registerOnTouched(fn: any) {
    this.onTouched = fn;
  }
}
import { Component, Input, OnInit } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
 
@Component({...})
export class RatingComponent implements OnInit, ControlValueAccessor {
  ...
  
  @Input() disabled = false;
  constructor() { }
 
  ...
 
  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }
 
  writeValue(value: number) {
    this.value = value;
  }
 
}
selectRating(rating: number) {
  if (this.disabled) return;
  this.value = rating;
}
selectRating(rating: number) {
  if (this.disabled) return;
  this.value = rating
  this.onChange(rating);  
}
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
 
@Component({
  selector: 'app-rating',
  templateUrl: './rating.component.html',
  styleUrls: ['./rating.component.scss'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => RatingComponent),
    multi: true
  }]
})

That's it!

Creating your own Form Controls in Angular

By Muhammad Ahsan Ayaz

Creating your own Form Controls in Angular

  • 141
Loading comments...

More from Muhammad Ahsan Ayaz