mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(autocomplete): placeholder not resetting properly (#6141)
Fixes the following regressions that were introduced by the switch to OnPush change detection: * The floating placeholder not resetting when the user closes the panel without selecting a value. * The placeholder overlapping the input value when the autocomplete has a preselected value and `floatPlaceholder="never"`.
This commit is contained in:
committed by
tinayuangao
parent
a780052090
commit
e4e7ee90f8
@@ -409,9 +409,18 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
|
||||
|
||||
private _setTriggerValue(value: any): void {
|
||||
const toDisplay = this.autocomplete.displayWith ? this.autocomplete.displayWith(value) : value;
|
||||
|
||||
// Simply falling back to an empty string if the display value is falsy does not work properly.
|
||||
// The display value can also be the number zero and shouldn't fall back to an empty string.
|
||||
this._element.nativeElement.value = toDisplay != null ? toDisplay : '';
|
||||
const inputValue = toDisplay != null ? toDisplay : '';
|
||||
|
||||
// If it's used in a Material container, we should set it through
|
||||
// the property so it can go through the change detection.
|
||||
if (this._inputContainer) {
|
||||
this._inputContainer._mdInputChild.value = inputValue;
|
||||
} else {
|
||||
this._element.nativeElement.value = inputValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,8 @@ describe('MdAutocomplete', () => {
|
||||
AutocompleteWithNumbers,
|
||||
AutocompleteWithOnPushDelay,
|
||||
AutocompleteWithNativeInput,
|
||||
AutocompleteWithoutPanel
|
||||
AutocompleteWithoutPanel,
|
||||
AutocompleteWithFormsAndNonfloatingPlaceholder
|
||||
],
|
||||
providers: [
|
||||
{provide: OverlayContainer, useFactory: () => {
|
||||
@@ -1314,6 +1315,21 @@ describe('MdAutocomplete', () => {
|
||||
}).toThrow(getMdAutocompleteMissingPanelError());
|
||||
}));
|
||||
|
||||
it('should hide the placeholder with a preselected form control value ' +
|
||||
'and a disabled floating placeholder', fakeAsync(() => {
|
||||
const fixture = TestBed.createComponent(AutocompleteWithFormsAndNonfloatingPlaceholder);
|
||||
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
|
||||
const input = fixture.nativeElement.querySelector('input');
|
||||
const placeholder = fixture.nativeElement.querySelector('.mat-input-placeholder');
|
||||
|
||||
expect(input.value).toBe('California');
|
||||
expect(placeholder.classList).not.toContain('mat-empty');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
it('should have correct width when opened', () => {
|
||||
@@ -1501,7 +1517,6 @@ class AutocompleteWithoutForms {
|
||||
onInput(value: any) {
|
||||
this.filteredStates = this.states.filter(s => new RegExp(value, 'gi').test(s));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1531,7 +1546,6 @@ class AutocompleteWithNgModel {
|
||||
onInput(value: any) {
|
||||
this.filteredStates = this.states.filter(s => new RegExp(value, 'gi').test(s));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -1611,3 +1625,19 @@ class AutocompleteWithNativeInput {
|
||||
class AutocompleteWithoutPanel {
|
||||
@ViewChild(MdAutocompleteTrigger) trigger: MdAutocompleteTrigger;
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<md-input-container floatPlaceholder="never">
|
||||
<input placeholder="State" mdInput [mdAutocomplete]="auto" [formControl]="formControl">
|
||||
</md-input-container>
|
||||
|
||||
<md-autocomplete #auto="mdAutocomplete">
|
||||
<md-option value="California">California</md-option>
|
||||
</md-autocomplete>
|
||||
`
|
||||
})
|
||||
class AutocompleteWithFormsAndNonfloatingPlaceholder {
|
||||
formControl = new FormControl('California');
|
||||
}
|
||||
|
||||
@@ -566,6 +566,25 @@ describe('MdInputContainer without forms', function () {
|
||||
expect(labelEl.classList).not.toContain('mat-float');
|
||||
});
|
||||
|
||||
it('should be able to toggle the floating placeholder programmatically', () => {
|
||||
const fixture = TestBed.createComponent(MdInputContainerWithId);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const inputContainer = fixture.debugElement.query(By.directive(MdInputContainer));
|
||||
const containerInstance = inputContainer.componentInstance as MdInputContainer;
|
||||
const placeholder = inputContainer.nativeElement.querySelector('.mat-input-placeholder');
|
||||
|
||||
expect(containerInstance.floatPlaceholder).toBe('auto');
|
||||
expect(placeholder.classList).toContain('mat-empty', 'Expected input to be considered empty.');
|
||||
|
||||
containerInstance.floatPlaceholder = 'always';
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(placeholder.classList)
|
||||
.not.toContain('mat-empty', 'Expected input to be considered not empty.');
|
||||
});
|
||||
|
||||
it('should not have prefix and suffix elements when none are specified', () => {
|
||||
let fixture = TestBed.createComponent(MdInputContainerWithId);
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -207,7 +207,12 @@ export class MdInputDirective implements OnChanges, OnDestroy, DoCheck {
|
||||
|
||||
/** The input element's value. */
|
||||
get value() { return this._elementRef.nativeElement.value; }
|
||||
set value(value: string) { this._elementRef.nativeElement.value = value; }
|
||||
set value(value: string) {
|
||||
if (value !== this.value) {
|
||||
this._elementRef.nativeElement.value = value;
|
||||
this._stateChanges.next();
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether the input is empty. */
|
||||
get empty() {
|
||||
@@ -443,7 +448,10 @@ export class MdInputContainer implements AfterViewInit, AfterContentInit, AfterC
|
||||
@Input()
|
||||
get floatPlaceholder() { return this._floatPlaceholder; }
|
||||
set floatPlaceholder(value: FloatPlaceholderType) {
|
||||
this._floatPlaceholder = value || this._placeholderOptions.float || 'auto';
|
||||
if (value !== this._floatPlaceholder) {
|
||||
this._floatPlaceholder = value || this._placeholderOptions.float || 'auto';
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
}
|
||||
private _floatPlaceholder: FloatPlaceholderType;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user