@@ -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
@@ -89,18 +90,19 @@ class MyTelInput implements MatFormFieldControl<MyTel> {
89
90
90
91
This sets up our component so it can work with ` <mat-form-field> ` , but now we need to implement the
91
92
various methods and properties declared by the interface we just implemented. To learn more about
92
- the ` MatFormFieldControl ` interface, see its
93
- [ definition] ( https://github.com/angular/material2/blob/master/src/lib/form-field/form-field-control.ts ) .
94
- (Unfortunately generated API docs are not available yet, but we'll go through the methods and
95
- properties in this guide.)
93
+ the ` MatFormFieldControl ` interface, see the
94
+ [ form field API documentation] ( https://material.angular.io/components/form-field/api ) .
96
95
97
96
### Implementing the methods and properties of MatFormFieldControl
97
+
98
98
#### ` value `
99
+
99
100
This property allows someone to set or get the value of our control. Its type should be the same
100
101
type we used for the type parameter when we implemented ` MatFormFieldControl ` . Since our component
101
102
already has a value property, we don't need to do anything for this one.
102
103
103
104
#### ` stateChanges `
105
+
104
106
Because the ` <mat-form-field> ` uses the ` OnPush ` change detection strategy, we need to let it know
105
107
when something happens in the form field control that may require the form field to run change
106
108
detection. We do this via the ` stateChanges ` property. So far the only thing the form field needs to
@@ -122,6 +124,7 @@ ngOnDestroy() {
122
124
```
123
125
124
126
#### ` id `
127
+
125
128
This property should return the ID of an element in the component's template that we want the
126
129
` <mat-form-field> ` to associate all of its labels and hints with. In this case, we'll use the host
127
130
element and just generate a unique ID for it.
@@ -133,6 +136,7 @@ static nextId = 0;
133
136
```
134
137
135
138
#### ` placeholder `
139
+
136
140
This property allows us to tell the ` <mat-form-field> ` what to use as a placeholder. In this
137
141
example, we'll do the same thing as ` matInput ` and ` <mat-select> ` and allow the user to specify it
138
142
via an ` @Input() ` . Since the value of the placeholder may change over time, we need to make sure to
@@ -152,6 +156,7 @@ private _placeholder: string;
152
156
```
153
157
154
158
#### ` ngControl `
159
+
155
160
This property allows the form field control to specify the ` @angular/forms ` control that is bound to
156
161
this component. Since we haven't set up our component to act as a ` ControlValueAccessor ` , we'll just
157
162
set this to ` null ` in our component. In any real component, you would probably want to implement
@@ -170,6 +175,7 @@ constructor(..., @Optional() @Self() public ngControl: NgControl) { ... }
170
175
```
171
176
172
177
#### ` focused `
178
+
173
179
This property indicates whether or not the form field control should be considered to be in a
174
180
focused state. When it is in a focused state, the form field is displayed with a solid color
175
181
underline. For the purposes of our component, we want to consider it focused if any of the part
@@ -195,6 +201,7 @@ ngOnDestroy() {
195
201
```
196
202
197
203
#### ` empty `
204
+
198
205
This property indicates whether the form field control is empty. For our control, we'll consider it
199
206
empty if all of the parts are empty.
200
207
@@ -206,6 +213,7 @@ get empty() {
206
213
```
207
214
208
215
#### ` shouldPlaceholderFloat `
216
+
209
217
This property is used to indicate whether the placeholder should be in the floating position. We'll
210
218
use the same logic as ` matInput ` and float the placeholder when the input is focused or non-empty.
211
219
Since the placeholder will be overlapping our control when when it's not floating, we should hide
@@ -228,6 +236,7 @@ span {
228
236
```
229
237
230
238
#### ` required `
239
+
231
240
This property is used to indicate whether the input is required. ` <mat-form-field> ` uses this
232
241
information to add a required indicator to the placeholder. Again, we'll want to make sure we run
233
242
change detection if the required state changes.
@@ -245,6 +254,7 @@ private _required = false;
245
254
```
246
255
247
256
#### ` disabled `
257
+
248
258
This property tells the form field when it should be in the disabled state. In addition to reporting
249
259
the right state to the form field, we need to set the disabled state on the individual inputs that
250
260
make up our component.
@@ -269,6 +279,7 @@ private _disabled = false;
269
279
```
270
280
271
281
#### ` errorState `
282
+
272
283
This property indicates whether the associated ` NgControl ` is in an error state. Since we're not
273
284
using an ` NgControl ` in this example, we don't need to do anything other than just set it to ` false ` .
274
285
@@ -277,6 +288,7 @@ errorState = false;
277
288
```
278
289
279
290
#### ` controlType `
291
+
280
292
This property allows us to specify a unique string for the type of control in form field. The
281
293
` <mat-form-field> ` will add an additional class based on this type that can be used to easily apply
282
294
special styles to a ` <mat-form-field> ` that contains a specific type of control. In this example
@@ -288,6 +300,7 @@ controlType = 'my-tel-input';
288
300
```
289
301
290
302
#### ` setAriaDescribedByIds(ids: string[]) `
303
+
291
304
This method is used by the ` <mat-form-field> ` to specify the IDs that should be used for the
292
305
` aria-describedby ` attribute of your component. The method has one parameter, the list of IDs, we
293
306
just need to apply the given IDs to our host element.
@@ -301,6 +314,7 @@ setDescribedByIds(ids: string[]) {
301
314
```
302
315
303
316
#### ` onContainerClick(event: MouseEvent) `
317
+
304
318
This method will be called when the form field is clicked on. It allows your component to hook in
305
319
and handle that click however it wants. The method has one parameter, the ` MouseEvent ` for the
306
320
click. In our case we'll just focus the first ` <input> ` if the user isn't about to click an
@@ -315,6 +329,7 @@ onContainerClick(event: MouseEvent) {
315
329
```
316
330
317
331
### Trying it out
332
+
318
333
Now that we've fully implemented the interface, we're ready to try our component out! All we need to
319
334
do is place it inside of a ` <mat-form-field> `
320
335
0 commit comments