Skip to content

Commit

Permalink
fix(input): placeholder covering value when using OnPush (#5660)
Browse files Browse the repository at this point in the history
  • Loading branch information
willshowell authored and jelbourn committed Jul 14, 2017
1 parent e036473 commit 219a8ae
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/demo-app/input/input-demo.html
Expand Up @@ -382,6 +382,11 @@ <h4>Textarea</h4>
<button md-raised-button color="primary" (click)="ctrlDisabled = !ctrlDisabled">
DISABLE TD CTRL
</button>
<div>
<md-input-container>
<input mdInput placeholder="delayed value" [formControl]="delayedFormControl">
</md-input-container>
</div>
</md-card-content>
</md-card>

Expand Down
8 changes: 7 additions & 1 deletion src/demo-app/input/input-demo.ts
@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import { Component, ChangeDetectionStrategy } from '@angular/core';
import {FormControl, Validators} from '@angular/forms';


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

@Component({
moduleId: module.id,
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'input-demo',
templateUrl: 'input-demo.html',
styleUrls: ['input-demo.css'],
Expand Down Expand Up @@ -38,8 +39,13 @@ export class InputDemo {
rows = 8;
formControl = new FormControl('hello', Validators.required);
emailFormControl = new FormControl('', [Validators.required, Validators.pattern(EMAIL_REGEX)]);
delayedFormControl = new FormControl('');
model = 'hello';

constructor() {
setTimeout(() => this.delayedFormControl.setValue('hello'), 100);
}

addABunch(n: number) {
for (let x = 0; x < n; x++) {
this.items.push({ value: ++max });
Expand Down
31 changes: 30 additions & 1 deletion src/lib/input/input-container.spec.ts
@@ -1,5 +1,5 @@
import {async, ComponentFixture, inject, TestBed} from '@angular/core/testing';
import {Component, ViewChild} from '@angular/core';
import {Component, ViewChild, ChangeDetectionStrategy} from '@angular/core';
import {
FormControl,
FormGroup,
Expand Down Expand Up @@ -61,6 +61,7 @@ describe('MdInputContainer without forms', function () {
MdInputContainerWithValueBinding,
MdTextareaWithBindings,
MdInputContainerWithNgIf,
MdInputContainerOnPush,
],
});

Expand Down Expand Up @@ -587,6 +588,22 @@ describe('MdInputContainer without forms', function () {
expect(prefixEl.nativeElement.innerText.trim()).toEqual('Prefix');
expect(suffixEl.nativeElement.innerText.trim()).toEqual('Suffix');
});

it('should update empty class when value changes programmatically and OnPush', () => {
let fixture = TestBed.createComponent(MdInputContainerOnPush);
fixture.detectChanges();

let component = fixture.componentInstance;
let placeholder = fixture.debugElement
.query(By.css('.mat-input-placeholder')).nativeElement;

expect(placeholder.classList).toContain('mat-empty', 'Input initially empty');

component.formControl.setValue('something');
fixture.detectChanges();

expect(placeholder.classList).not.toContain('mat-empty', 'Input no longer empty');
});
});

describe('MdInputContainer with forms', () => {
Expand Down Expand Up @@ -1201,3 +1218,15 @@ class MdInputContainerWithPrefixAndSuffix {}
class MdInputContainerWithNgIf {
renderInput = true;
}

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<md-input-container>
<input mdInput placeholder="Label" [formControl]="formControl">
</md-input-container>
`
})
class MdInputContainerOnPush {
formControl = new FormControl('');
}
6 changes: 6 additions & 0 deletions src/lib/input/input-container.ts
Expand Up @@ -410,6 +410,12 @@ export class MdInputContainer implements AfterViewInit, AfterContentInit, AfterC
// Re-validate when things change.
this._hintChildren.changes.subscribe(() => this._processHints());
this._mdInputChild._placeholderChange.subscribe(() => this._validatePlaceholders());

// Mark for check when the input's value changes to recalculate whether input is empty
const control = this._mdInputChild._ngControl;
if (control && control.valueChanges) {
control.valueChanges.subscribe(() => this._changeDetectorRef.markForCheck());
}
}

ngAfterContentChecked() {
Expand Down

0 comments on commit 219a8ae

Please sign in to comment.