Skip to content

Commit ef4c6bf

Browse files
crisbetodevversion
authored andcommitted
fix(input): not floating the label when updating the value programmatically with reactive forms
Fixes the input placeholder not being floating when the value is updated programmatically via `FormControl.setValue`. This was because the listener that handles the value changes gets initialized before the `FormControl`. Fixes angular#2441.
1 parent dccbe41 commit ef4c6bf

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

src/lib/input/input-container.spec.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {async, TestBed, inject} from '@angular/core/testing';
22
import {Component} from '@angular/core';
3-
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
3+
import {FormsModule, ReactiveFormsModule, FormControl} from '@angular/forms';
44
import {By} from '@angular/platform-browser';
55
import {MdInputModule} from './input';
6-
import {MdInputContainer} from './input-container';
6+
import {MdInputContainer, MdInputDirective} from './input-container';
77
import {Platform} from '../core/platform/platform';
88
import {PlatformModule} from '../core/platform/index';
99
import {
@@ -41,7 +41,8 @@ describe('MdInputContainer', function () {
4141
MdInputContainerZeroTestController,
4242
MdTextareaWithBindings,
4343
MdInputContainerWithDisabled,
44-
MdInputContainerMissingMdInputTestController
44+
MdInputContainerMissingMdInputTestController,
45+
MdInputContainerWithFormControl
4546
],
4647
});
4748

@@ -293,6 +294,21 @@ describe('MdInputContainer', function () {
293294
const textarea: HTMLTextAreaElement = fixture.nativeElement.querySelector('textarea');
294295
expect(textarea).not.toBeNull();
295296
});
297+
298+
it('should update the value when using FormControl.setValue', () => {
299+
let fixture = TestBed.createComponent(MdInputContainerWithFormControl);
300+
fixture.detectChanges();
301+
302+
let input = fixture.debugElement.query(By.directive(MdInputDirective))
303+
.injector.get(MdInputDirective) as MdInputDirective;
304+
305+
expect(input.value).toBeFalsy();
306+
307+
fixture.componentInstance.formControl.setValue('something');
308+
309+
expect(input.value).toBe('something');
310+
});
311+
296312
});
297313

298314
@Component({
@@ -446,6 +462,13 @@ class MdTextareaWithBindings {
446462
})
447463
class MdInputContainerMissingMdInputTestController {}
448464

465+
@Component({
466+
template: `<md-input-container><input md-input [formControl]="formControl"></md-input-container>`
467+
})
468+
class MdInputContainerWithFormControl {
469+
formControl = new FormControl();
470+
}
471+
449472
/**
450473
* Gets a RegExp used to detect an angular wrapped error message.
451474
* See https://github.com/angular/angular/issues/8348

src/lib/input/input-container.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
Optional,
1212
Output,
1313
EventEmitter,
14-
Renderer
14+
Renderer,
15+
OnInit,
1516
} from '@angular/core';
1617
import {coerceBooleanProperty} from '../core';
1718
import {NgControl} from '@angular/forms';
@@ -77,7 +78,7 @@ export class MdHint {
7778
'(input)': '_onInput()',
7879
}
7980
})
80-
export class MdInputDirective implements AfterContentInit {
81+
export class MdInputDirective implements AfterContentInit, OnInit {
8182
/** Whether the element is disabled. */
8283
@Input()
8384
get disabled() { return this._disabled; }
@@ -142,14 +143,14 @@ export class MdInputDirective implements AfterContentInit {
142143

143144
constructor(private _elementRef: ElementRef,
144145
private _renderer: Renderer,
145-
@Optional() public _ngControl: NgControl) {
146+
@Optional() public _ngControl: NgControl) { }
147+
148+
ngOnInit() {
146149
// Force setter to be called in case id was not specified.
147150
this.id = this.id;
148151

149152
if (this._ngControl && this._ngControl.valueChanges) {
150-
this._ngControl.valueChanges.subscribe((value) => {
151-
this.value = value;
152-
});
153+
this._ngControl.valueChanges.subscribe(value => this.value = value);
153154
}
154155
}
155156

0 commit comments

Comments
 (0)