I am trying to add a form field with custom telephone number input control. I used the example of the phone from https://material.angular.io/components/form-field/examples.
Here is the code:
<mat-form-field> <example-tel-input placeholder="Phone number" required></example-tel-input> <mat-icon matSuffix>phone</mat-icon> <mat-hint>Include area code</mat-hint> </mat-form-field>
import {FocusMonitor} from '@angular/cdk/a11y'; import {coerceBooleanProperty} from '@angular/cdk/coercion'; import {Component, ElementRef, Input, OnDestroy} from '@angular/core'; import {FormBuilder, FormGroup} from '@angular/forms'; import {MatFormFieldControl} from '@angular/material'; import {Subject} from 'rxjs'; /** @title Form field with custom telephone number input control. */ @Component({ selector: 'form-field-custom-control-example', templateUrl: 'form-field-custom-control-example.html', styleUrls: ['form-field-custom-control-example.css'], }) export class FormFieldCustomControlExample {} /** Data structure for holding telephone number. */ export class MyTel { constructor(public area: string, public exchange: string, public subscriber: string) {} } /** Custom `MatFormFieldControl` for telephone number input. */ @Component({ selector: 'example-tel-input', templateUrl: 'example-tel-input-example.html', styleUrls: ['example-tel-input-example.css'], providers: [{provide: MatFormFieldControl, useExisting: MyTelInput}], host: { '[class.example-floating]': 'shouldLabelFloat', '[id]': 'id', '[attr.aria-describedby]': 'describedBy', } }) export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy { static nextId = 0; parts: FormGroup; stateChanges = new Subject<void>(); focused = false; ngControl = null; errorState = false; controlType = 'example-tel-input'; id = `example-tel-input-${MyTelInput.nextId++}`; describedBy = ''; get empty() { const {value: {area, exchange, subscriber}} = this.parts; return !area && !exchange && !subscriber; } get shouldLabelFloat() { return this.focused || !this.empty; } @Input() get placeholder(): string { return this._placeholder; } set placeholder(value: string) { this._placeholder = value; this.stateChanges.next(); } private _placeholder: string; @Input() get required(): boolean { return this._required; } set required(value: boolean) { this._required = coerceBooleanProperty(value); this.stateChanges.next(); } private _required = false; @Input() get disabled(): boolean { return this._disabled; } set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value); this.stateChanges.next(); } private _disabled = false; @Input() get value(): MyTel | null { const {value: {area, exchange, subscriber}} = this.parts; if (area.length === 3 && exchange.length === 3 && subscriber.length === 4) { return new MyTel(area, exchange, subscriber); } return null; } set value(tel: MyTel | null) { const {area, exchange, subscriber} = tel || new MyTel('', '', ''); this.parts.setValue({area, exchange, subscriber}); this.stateChanges.next(); } constructor(fb: FormBuilder, private fm: FocusMonitor, private elRef: ElementRef<HTMLElement>) { this.parts = fb.group({ area: '', exchange: '', subscriber: '', }); fm.monitor(elRef, true).subscribe(origin => { this.focused = !!origin; this.stateChanges.next(); }); } ngOnDestroy() { this.stateChanges.complete(); this.fm.stopMonitoring(this.elRef); } setDescribedByIds(ids: string[]) { this.describedBy = ids.join(' '); } onContainerClick(event: MouseEvent) { if ((event.target as Element).tagName.toLowerCase() != 'input') { this.elRef.nativeElement.querySelector('input')!.focus(); } } }
example-tel-input-example.html
<div [formGroup]="parts" class="example-tel-input-container"> <input class="example-tel-input-element" formControlName="area" size="3"> <span class="example-tel-input-spacer">–</span> <input class="example-tel-input-element" formControlName="exchange" size="3"> <span class="example-tel-input-spacer">–</span> <input class="example-tel-input-element" formControlName="subscriber" size="4"> </div>
But I get the following error:
ERROR Error: mat-form-field must contain a MatFormFieldControl.