@@ -70,6 +70,7 @@ class MyTelInput {
70
70
```
71
71
72
72
### Providing our component as a MatFormFieldControl
73
+
73
74
The first step is to provide our new component as an implementation of the ` MatFormFieldControl `
74
75
interface that the ` <mat-form-field> ` knows how to work with. To do this, we will have our class
75
76
implement ` MatFormFieldControl ` . Since this is a generic interface, we'll need to include a type
@@ -95,12 +96,15 @@ the `MatFormFieldControl` interface, see the
95
96
properties in this guide.)
96
97
97
98
### Implementing the methods and properties of MatFormFieldControl
99
+
98
100
#### ` value `
101
+
99
102
This property allows someone to set or get the value of our control. Its type should be the same
100
103
type we used for the type parameter when we implemented ` MatFormFieldControl ` . Since our component
101
104
already has a value property, we don't need to do anything for this one.
102
105
103
106
#### ` stateChanges `
107
+
104
108
Because the ` <mat-form-field> ` uses the ` OnPush ` change detection strategy, we need to let it know
105
109
when something happens in the form field control that may require the form field to run change
106
110
detection. We do this via the ` stateChanges ` property. So far the only thing the form field needs to
@@ -122,6 +126,7 @@ ngOnDestroy() {
122
126
```
123
127
124
128
#### ` id `
129
+
125
130
This property should return the ID of an element in the component's template that we want the
126
131
` <mat-form-field> ` to associate all of its labels and hints with. In this case, we'll use the host
127
132
element and just generate a unique ID for it.
@@ -133,6 +138,7 @@ static nextId = 0;
133
138
```
134
139
135
140
#### ` placeholder `
141
+
136
142
This property allows us to tell the ` <mat-form-field> ` what to use as a placeholder. In this
137
143
example, we'll do the same thing as ` matInput ` and ` <mat-select> ` and allow the user to specify it
138
144
via an ` @Input() ` . Since the value of the placeholder may change over time, we need to make sure to
@@ -152,6 +158,7 @@ private _placeholder: string;
152
158
```
153
159
154
160
#### ` ngControl `
161
+
155
162
This property allows the form field control to specify the ` @angular/forms ` control that is bound to
156
163
this component. Since we haven't set up our component to act as a ` ControlValueAccessor ` , we'll just
157
164
set this to ` null ` in our component. In any real component, you would probably want to implement
@@ -170,6 +177,7 @@ constructor(..., @Optional() @Self() public ngControl: NgControl) { ... }
170
177
```
171
178
172
179
#### ` focused `
180
+
173
181
This property indicates whether or not the form field control should be considered to be in a
174
182
focused state. When it is in a focused state, the form field is displayed with a solid color
175
183
underline. For the purposes of our component, we want to consider it focused if any of the part
@@ -195,6 +203,7 @@ ngOnDestroy() {
195
203
```
196
204
197
205
#### ` empty `
206
+
198
207
This property indicates whether the form field control is empty. For our control, we'll consider it
199
208
empty if all of the parts are empty.
200
209
@@ -206,6 +215,7 @@ get empty() {
206
215
```
207
216
208
217
#### ` shouldPlaceholderFloat `
218
+
209
219
This property is used to indicate whether the placeholder should be in the floating position. We'll
210
220
use the same logic as ` matInput ` and float the placeholder when the input is focused or non-empty.
211
221
Since the placeholder will be overlapping our control when when it's not floating, we should hide
@@ -228,6 +238,7 @@ span {
228
238
```
229
239
230
240
#### ` required `
241
+
231
242
This property is used to indicate whether the input is required. ` <mat-form-field> ` uses this
232
243
information to add a required indicator to the placeholder. Again, we'll want to make sure we run
233
244
change detection if the required state changes.
@@ -245,6 +256,7 @@ private _required = false;
245
256
```
246
257
247
258
#### ` disabled `
259
+
248
260
This property tells the form field when it should be in the disabled state. In addition to reporting
249
261
the right state to the form field, we need to set the disabled state on the individual inputs that
250
262
make up our component.
@@ -269,6 +281,7 @@ private _disabled = false;
269
281
```
270
282
271
283
#### ` errorState `
284
+
272
285
This property indicates whether the associated ` NgControl ` is in an error state. Since we're not
273
286
using an ` NgControl ` in this example, we don't need to do anything other than just set it to ` false ` .
274
287
@@ -277,6 +290,7 @@ errorState = false;
277
290
```
278
291
279
292
#### ` controlType `
293
+
280
294
This property allows us to specify a unique string for the type of control in form field. The
281
295
` <mat-form-field> ` will add an additional class based on this type that can be used to easily apply
282
296
special styles to a ` <mat-form-field> ` that contains a specific type of control. In this example
@@ -288,6 +302,7 @@ controlType = 'my-tel-input';
288
302
```
289
303
290
304
#### ` setAriaDescribedByIds(ids: string[]) `
305
+
291
306
This method is used by the ` <mat-form-field> ` to specify the IDs that should be used for the
292
307
` aria-describedby ` attribute of your component. The method has one parameter, the list of IDs, we
293
308
just need to apply the given IDs to our host element.
@@ -301,6 +316,7 @@ setDescribedByIds(ids: string[]) {
301
316
```
302
317
303
318
#### ` onContainerClick(event: MouseEvent) `
319
+
304
320
This method will be called when the form field is clicked on. It allows your component to hook in
305
321
and handle that click however it wants. The method has one parameter, the ` MouseEvent ` for the
306
322
click. In our case we'll just focus the first ` <input> ` if the user isn't about to click an
@@ -315,6 +331,7 @@ onContainerClick(event: MouseEvent) {
315
331
```
316
332
317
333
### Trying it out
334
+
318
335
Now that we've fully implemented the interface, we're ready to try our component out! All we need to
319
336
do is place it inside of a ` <mat-form-field> `
320
337
0 commit comments