Skip to content

Commit 219a8ae

Browse files
willshowelljelbourn
authored andcommitted
fix(input): placeholder covering value when using OnPush (#5660)
1 parent e036473 commit 219a8ae

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

src/demo-app/input/input-demo.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ <h4>Textarea</h4>
382382
<button md-raised-button color="primary" (click)="ctrlDisabled = !ctrlDisabled">
383383
DISABLE TD CTRL
384384
</button>
385+
<div>
386+
<md-input-container>
387+
<input mdInput placeholder="delayed value" [formControl]="delayedFormControl">
388+
</md-input-container>
389+
</div>
385390
</md-card-content>
386391
</md-card>
387392

src/demo-app/input/input-demo.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component} from '@angular/core';
1+
import { Component, ChangeDetectionStrategy } from '@angular/core';
22
import {FormControl, Validators} from '@angular/forms';
33

44

@@ -8,6 +8,7 @@ const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA
88

99
@Component({
1010
moduleId: module.id,
11+
changeDetection: ChangeDetectionStrategy.OnPush,
1112
selector: 'input-demo',
1213
templateUrl: 'input-demo.html',
1314
styleUrls: ['input-demo.css'],
@@ -38,8 +39,13 @@ export class InputDemo {
3839
rows = 8;
3940
formControl = new FormControl('hello', Validators.required);
4041
emailFormControl = new FormControl('', [Validators.required, Validators.pattern(EMAIL_REGEX)]);
42+
delayedFormControl = new FormControl('');
4143
model = 'hello';
4244

45+
constructor() {
46+
setTimeout(() => this.delayedFormControl.setValue('hello'), 100);
47+
}
48+
4349
addABunch(n: number) {
4450
for (let x = 0; x < n; x++) {
4551
this.items.push({ value: ++max });

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {async, ComponentFixture, inject, TestBed} from '@angular/core/testing';
2-
import {Component, ViewChild} from '@angular/core';
2+
import {Component, ViewChild, ChangeDetectionStrategy} from '@angular/core';
33
import {
44
FormControl,
55
FormGroup,
@@ -61,6 +61,7 @@ describe('MdInputContainer without forms', function () {
6161
MdInputContainerWithValueBinding,
6262
MdTextareaWithBindings,
6363
MdInputContainerWithNgIf,
64+
MdInputContainerOnPush,
6465
],
6566
});
6667

@@ -587,6 +588,22 @@ describe('MdInputContainer without forms', function () {
587588
expect(prefixEl.nativeElement.innerText.trim()).toEqual('Prefix');
588589
expect(suffixEl.nativeElement.innerText.trim()).toEqual('Suffix');
589590
});
591+
592+
it('should update empty class when value changes programmatically and OnPush', () => {
593+
let fixture = TestBed.createComponent(MdInputContainerOnPush);
594+
fixture.detectChanges();
595+
596+
let component = fixture.componentInstance;
597+
let placeholder = fixture.debugElement
598+
.query(By.css('.mat-input-placeholder')).nativeElement;
599+
600+
expect(placeholder.classList).toContain('mat-empty', 'Input initially empty');
601+
602+
component.formControl.setValue('something');
603+
fixture.detectChanges();
604+
605+
expect(placeholder.classList).not.toContain('mat-empty', 'Input no longer empty');
606+
});
590607
});
591608

592609
describe('MdInputContainer with forms', () => {
@@ -1201,3 +1218,15 @@ class MdInputContainerWithPrefixAndSuffix {}
12011218
class MdInputContainerWithNgIf {
12021219
renderInput = true;
12031220
}
1221+
1222+
@Component({
1223+
changeDetection: ChangeDetectionStrategy.OnPush,
1224+
template: `
1225+
<md-input-container>
1226+
<input mdInput placeholder="Label" [formControl]="formControl">
1227+
</md-input-container>
1228+
`
1229+
})
1230+
class MdInputContainerOnPush {
1231+
formControl = new FormControl('');
1232+
}

src/lib/input/input-container.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,12 @@ export class MdInputContainer implements AfterViewInit, AfterContentInit, AfterC
410410
// Re-validate when things change.
411411
this._hintChildren.changes.subscribe(() => this._processHints());
412412
this._mdInputChild._placeholderChange.subscribe(() => this._validatePlaceholders());
413+
414+
// Mark for check when the input's value changes to recalculate whether input is empty
415+
const control = this._mdInputChild._ngControl;
416+
if (control && control.valueChanges) {
417+
control.valueChanges.subscribe(() => this._changeDetectorRef.markForCheck());
418+
}
413419
}
414420

415421
ngAfterContentChecked() {

0 commit comments

Comments
 (0)