Blog>
Snippets

Custom Form Control Implementation

Illustrate the steps required to create a fully custom form control that integrates with Angular's form API, including the use of ControlValueAccessor.
import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

@Component({
  selector: 'custom-form-control',
  template: `<input type="text" (input)="onInput($event.target.value)" [value]="value">`,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CustomFormControlComponent),
      multi: true
    }
  ]
})
export class CustomFormControlComponent implements ControlValueAccessor {
  value: string = '';
  onChange: any = () => {};
  onTouched: any = () => {};

  writeValue(value: any): void {
    this.value = value;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  onInput(value: string): void {
    this.value = value;
    this.onChange(value);
  }

  setDisabledState(isDisabled: boolean): void {
    // Implement if needed to handle the disabled state
  }
}
This code snippet defines a custom form control component in Angular that implements the ControlValueAccessor interface. It allows the component to interact with Angular's form API. The component has an input field which updates the internal value and notifies the form API about the changes when the user types in it.
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { CustomFormControlComponent } from './custom-form-control.component';

@NgModule({
  declarations: [
    CustomFormControlComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule
  ],
  exports: [
    CustomFormControlComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
This second piece of code sets up an Angular module that includes the ReactiveFormsModule necessary for working with forms, declares the CustomFormControlComponent, and exports it so it can be used in other components.
import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `<form [formGroup]="form">
    <custom-form-control formControlName="customControl"></custom-form-control>
  </form>`
})
export class AppComponent {
  form: FormGroup;

  constructor() {
    this.form = new FormGroup({
      customControl: new FormControl('')
    });
  }
}
This code snippet illustrates how to use the custom form control within an Angular form. It creates a form with a FormGroup that includes the custom form control, and binds it to the 'customControl' form control within the form.