@@ -79,6 +79,10 @@ class MDCTextfieldFoundation extends MDCFoundation {
79
79
this . receivedUserInput_ = false ;
80
80
/** @private {boolean} */
81
81
this . useCustomValidityChecking_ = false ;
82
+ /** @private {boolean} */
83
+ this . labelFloatIsActive_ = false ;
84
+ /** @private {boolean} */
85
+ this . setValueIsProcessing_ = false ;
82
86
/** @private {function(): undefined} */
83
87
this . inputFocusHandler_ = ( ) => this . activateFocus_ ( ) ;
84
88
/** @private {function(): undefined} */
@@ -96,9 +100,7 @@ class MDCTextfieldFoundation extends MDCFoundation {
96
100
init ( ) {
97
101
this . adapter_ . addClass ( MDCTextfieldFoundation . cssClasses . UPGRADED ) ;
98
102
// Ensure label does not collide with any pre-filled value.
99
- if ( this . getNativeInput_ ( ) . value ) {
100
- this . adapter_ . addClassToLabel ( MDCTextfieldFoundation . cssClasses . LABEL_FLOAT_ABOVE ) ;
101
- }
103
+ this . updateLabelFloat_ ( ) ;
102
104
103
105
this . adapter_ . registerInputInteractionHandler ( 'focus' , this . inputFocusHandler_ ) ;
104
106
this . adapter_ . registerInputInteractionHandler ( 'blur' , this . inputBlurHandler_ ) ;
@@ -155,13 +157,13 @@ class MDCTextfieldFoundation extends MDCFoundation {
155
157
* @private
156
158
*/
157
159
activateFocus_ ( ) {
158
- const { BOTTOM_LINE_ACTIVE , FOCUSED , LABEL_FLOAT_ABOVE , LABEL_SHAKE } = MDCTextfieldFoundation . cssClasses ;
160
+ const { BOTTOM_LINE_ACTIVE , FOCUSED , LABEL_SHAKE } = MDCTextfieldFoundation . cssClasses ;
161
+ this . isFocused_ = true ;
162
+ this . updateLabelFloat_ ( ) ;
159
163
this . adapter_ . addClass ( FOCUSED ) ;
160
164
this . adapter_ . addClassToBottomLine ( BOTTOM_LINE_ACTIVE ) ;
161
- this . adapter_ . addClassToLabel ( LABEL_FLOAT_ABOVE ) ;
162
165
this . adapter_ . removeClassFromLabel ( LABEL_SHAKE ) ;
163
166
this . showHelptext_ ( ) ;
164
- this . isFocused_ = true ;
165
167
}
166
168
167
169
/**
@@ -196,21 +198,18 @@ class MDCTextfieldFoundation extends MDCFoundation {
196
198
* @private
197
199
*/
198
200
updateLabelFloat_ ( ) {
199
- // Don't do anything if the input is focused.
200
- if ( ! this . isFocused_ ) {
201
- const { LABEL_FLOAT_ABOVE , LABEL_SHAKE } = MDCTextfieldFoundation . cssClasses ;
202
- const input = this . getNativeInput_ ( ) ;
201
+ const input = this . getNativeInput_ ( ) ;
202
+ const { LABEL_FLOAT_ABOVE } = MDCTextfieldFoundation . cssClasses ;
203
203
204
- if ( input . value ) {
204
+ if ( this . isFocused_ || input . value ) {
205
+ if ( ! this . labelFloatIsActive_ ) {
206
+ this . labelFloatIsActive_ = true ;
205
207
this . adapter_ . addClassToLabel ( LABEL_FLOAT_ABOVE ) ;
206
- } else {
207
- this . adapter_ . removeClassFromLabel ( LABEL_FLOAT_ABOVE ) ;
208
208
}
209
-
210
- if ( ! this . useCustomValidityChecking_ ) {
211
- this . adapter_ . removeClassFromLabel ( LABEL_SHAKE ) ;
212
- this . showHelptext_ ( ) ;
213
- this . changeValidity_ ( input . checkValidity ( ) ) ;
209
+ } else {
210
+ if ( this . labelFloatIsActive_ ) {
211
+ this . labelFloatIsActive_ = false ;
212
+ this . adapter_ . removeClassFromLabel ( LABEL_FLOAT_ABOVE ) ;
214
213
}
215
214
}
216
215
}
@@ -246,19 +245,24 @@ class MDCTextfieldFoundation extends MDCFoundation {
246
245
* @private
247
246
*/
248
247
deactivateFocus_ ( ) {
249
- const { FOCUSED , LABEL_FLOAT_ABOVE , LABEL_SHAKE } = MDCTextfieldFoundation . cssClasses ;
248
+ const { FOCUSED , LABEL_SHAKE } = MDCTextfieldFoundation . cssClasses ;
250
249
const input = this . getNativeInput_ ( ) ;
251
250
252
251
this . isFocused_ = false ;
253
252
this . adapter_ . removeClass ( FOCUSED ) ;
254
253
this . adapter_ . removeClassFromLabel ( LABEL_SHAKE ) ;
255
254
256
255
if ( ! input . value && ! this . isBadInput_ ( ) ) {
257
- this . adapter_ . removeClassFromLabel ( LABEL_FLOAT_ABOVE ) ;
256
+ this . updateLabelFloat_ ( ) ;
258
257
this . receivedUserInput_ = false ;
259
258
}
260
259
260
+ this . updateDefaultValidity_ ( ) ;
261
+ }
262
+
263
+ updateDefaultValidity_ ( ) {
261
264
if ( ! this . useCustomValidityChecking_ ) {
265
+ const input = this . getNativeInput_ ( ) ;
262
266
this . changeValidity_ ( input . checkValidity ( ) ) ;
263
267
}
264
268
}
@@ -273,8 +277,11 @@ class MDCTextfieldFoundation extends MDCFoundation {
273
277
if ( isValid ) {
274
278
this . adapter_ . removeClass ( INVALID ) ;
275
279
} else {
276
- this . adapter_ . addClassToLabel ( LABEL_SHAKE ) ;
277
280
this . adapter_ . addClass ( INVALID ) ;
281
+
282
+ if ( this . isFocused_ ) {
283
+ this . adapter_ . addClassToLabel ( LABEL_SHAKE ) ;
284
+ }
278
285
}
279
286
this . updateHelptext_ ( isValid ) ;
280
287
}
@@ -343,6 +350,20 @@ class MDCTextfieldFoundation extends MDCFoundation {
343
350
}
344
351
}
345
352
353
+ /**
354
+ * @param {string } value The value of the textfield.
355
+ */
356
+ setValue ( value ) {
357
+ this . setValueIsProcessing_ = true ;
358
+
359
+ const input = this . getNativeInput_ ( ) ;
360
+ input . value = value ;
361
+ this . updateLabelFloat_ ( ) ;
362
+ this . updateDefaultValidity_ ( ) ;
363
+
364
+ this . setValueIsProcessing_ = false ;
365
+ }
366
+
346
367
/**
347
368
* @return {!Element|!NativeInputType } The native text input from the
348
369
* host environment, or a dummy if none exists.
@@ -379,8 +400,10 @@ class MDCTextfieldFoundation extends MDCFoundation {
379
400
const nativeInputElementDesc = /** @type {!ObjectPropertyDescriptor } */ ( {
380
401
get : desc . get ,
381
402
set : ( value ) => {
382
- desc . set . call ( nativeInputElement , value ) ;
383
- this . updateLabelFloat_ ( ) ;
403
+ if ( ! this . setValueIsProcessing_ ) {
404
+ desc . set . call ( nativeInputElement , value ) ;
405
+ this . setValue ( value ) ;
406
+ }
384
407
} ,
385
408
configurable : desc . configurable ,
386
409
enumerable : desc . enumerable ,
0 commit comments