Angular Custom Form Control

Issue

hi I am trying to create a set of custom reactive form controls for easy usage in templates.
so far I have managed to create one using ControlValueAccessor interface. the editing of form is working fine but I am not able to display error messages with it. can anyone suggest a way to pass and display error message in the custom controls html

here is my code

input-form.component.html

<div style="font-size: 12px">
  <mat-form-field appearance="outline">
    <mat-label>{{ label }}</mat-label>
    <input
      matInput
      [required]="required"
      [readonly]="readonly"
      [formControl]="textInputFormControl"
      (input)="change()"
    />
  </mat-form-field>
</div>

input-form.component.ts

import { Component, Input, OnChanges } from '@angular/core';
import {
  ControlValueAccessor,
  FormControl,
  NG_VALUE_ACCESSOR,
} from '@angular/forms';
import { getErrorMessage } from '../form-fields.helper';

@Component({
  selector: 'x-text-input',
  templateUrl: './text-input.component.html',
  styleUrls: ['./text-input.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: TextInputComponent,
    },
  ],
})
export class TextInputComponent implements ControlValueAccessor {
  

  public textInputFormControl = new FormControl('');
  onTouched = () => {};
  onChange: (_: string) => {};

  @Input()
  public label: string;

  @Input()
  public readonly: boolean;


  public change() {
    this.onChange(this.textInputFormControl.value);
    this.onTouched();
  }

  writeValue(value: any): void {
    this.textInputFormControl.setValue(value);
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState(disabled: boolean) {
    disabled
      ? this.textInputFormControl.disable({ emitEvent: false })
      : this.textInputFormControl.enable({ emitEvent: false });
  }
}

thanks!

Solution

Your custom form control doesn’t have to be reactive forms specific. It can be form-module agnostic. Also, if you need validations, you will need to implement the Validator interface.

Here is a StackBlitz demo that demonstrates how to do this. See the required-field component.

You can also check this article that I wrote, which explains extensively how to create a custom form control with validations and all.

EDIT:

To answer your question in the comment, there is this guide in Material’s official documentation. Frankly speaking, I’ve never implemented a custom control with Material, but I don’t see why you wouldn’t be able to inject NgControl and omit the formControl, like in the StackBlitz demo.

Answered By – Vasileios Kagklis

Answer Checked By – Terry (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.