Skip to content

Commit 83135e1

Browse files
swseverancejelbourn
authored andcommitted
fix(examples): fix form-field-custom-control (#15147)
* Update `MyTelInput` to implement `ControlValueAccessor` interface * Resolves #14810
1 parent 0bf7ccb commit 83135e1

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div [formGroup]="parts" class="example-tel-input-container">
2-
<input class="example-tel-input-element" formControlName="area" size="3">
2+
<input class="example-tel-input-element" formControlName="area" size="3" (input)="_handleInput()">
33
<span class="example-tel-input-spacer">&ndash;</span>
4-
<input class="example-tel-input-element" formControlName="exchange" size="3">
4+
<input class="example-tel-input-element" formControlName="exchange" size="3" (input)="_handleInput()">
55
<span class="example-tel-input-spacer">&ndash;</span>
6-
<input class="example-tel-input-element" formControlName="subscriber" size="4">
6+
<input class="example-tel-input-element" formControlName="subscriber" size="4" (input)="_handleInput()">
77
</div>

src/material-examples/form-field-custom-control/form-field-custom-control-example.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {FocusMonitor} from '@angular/cdk/a11y';
22
import {coerceBooleanProperty} from '@angular/cdk/coercion';
3-
import {Component, ElementRef, Input, OnDestroy} from '@angular/core';
4-
import {FormBuilder, FormGroup} from '@angular/forms';
3+
import {Component, ElementRef, Input, OnDestroy, Optional, Self} from '@angular/core';
4+
import {FormBuilder, FormGroup, ControlValueAccessor, NgControl} from '@angular/forms';
55
import {MatFormFieldControl} from '@angular/material';
66
import {Subject} from 'rxjs';
77

@@ -30,17 +30,18 @@ export class MyTel {
3030
'[attr.aria-describedby]': 'describedBy',
3131
}
3232
})
33-
export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy {
33+
export class MyTelInput implements ControlValueAccessor, MatFormFieldControl<MyTel>, OnDestroy {
3434
static nextId = 0;
3535

3636
parts: FormGroup;
3737
stateChanges = new Subject<void>();
3838
focused = false;
39-
ngControl = null;
4039
errorState = false;
4140
controlType = 'example-tel-input';
4241
id = `example-tel-input-${MyTelInput.nextId++}`;
4342
describedBy = '';
43+
onChange = (_: any) => {};
44+
onTouched = () => {};
4445

4546
get empty() {
4647
const {value: {area, exchange, subscriber}} = this.parts;
@@ -89,17 +90,29 @@ export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy {
8990
this.stateChanges.next();
9091
}
9192

92-
constructor(fb: FormBuilder, private fm: FocusMonitor, private elRef: ElementRef<HTMLElement>) {
93+
constructor(
94+
fb: FormBuilder,
95+
private fm: FocusMonitor,
96+
private elRef: ElementRef<HTMLElement>,
97+
@Optional() @Self() public ngControl: NgControl) {
98+
9399
this.parts = fb.group({
94100
area: '',
95101
exchange: '',
96102
subscriber: '',
97103
});
98104

99105
fm.monitor(elRef, true).subscribe(origin => {
106+
if (this.focused && !origin) {
107+
this.onTouched();
108+
}
100109
this.focused = !!origin;
101110
this.stateChanges.next();
102111
});
112+
113+
if (this.ngControl != null) {
114+
this.ngControl.valueAccessor = this;
115+
}
103116
}
104117

105118
ngOnDestroy() {
@@ -116,4 +129,24 @@ export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy {
116129
this.elRef.nativeElement.querySelector('input')!.focus();
117130
}
118131
}
132+
133+
writeValue(tel: MyTel | null): void {
134+
this.value = tel;
135+
}
136+
137+
registerOnChange(fn: any): void {
138+
this.onChange = fn;
139+
}
140+
141+
registerOnTouched(fn: any): void {
142+
this.onTouched = fn;
143+
}
144+
145+
setDisabledState(isDisabled: boolean): void {
146+
this.disabled = isDisabled;
147+
}
148+
149+
_handleInput(): void {
150+
this.onChange(this.parts.value);
151+
}
119152
}

0 commit comments

Comments
 (0)