Skip to content

Commit 4913c36

Browse files
crisbetovivian-hu-zz
authored andcommittedJan 16, 2019
fix(autocomplete): not updating origin if it changes after init (#14677)
* Fixes changes to the `matAutocompleteOrigin` input being ignored if they happen after the overlay has been initialized. * Fixes the `MatAutocompleteOrigin` class not being exported as a part of the public API.
1 parent 4f755cf commit 4913c36

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed
 

‎src/lib/autocomplete/autocomplete-trigger.ts

+15-9
Original file line numberDiff line numberDiff line change
@@ -569,13 +569,16 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
569569
throw getMatAutocompleteMissingPanelError();
570570
}
571571

572-
if (!this._overlayRef) {
572+
let overlayRef = this._overlayRef;
573+
574+
if (!overlayRef) {
573575
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
574-
this._overlayRef = this._overlay.create(this._getOverlayConfig());
576+
overlayRef = this._overlay.create(this._getOverlayConfig());
577+
this._overlayRef = overlayRef;
575578

576579
// Use the `keydownEvents` in order to take advantage of
577580
// the overlay event targeting provided by the CDK overlay.
578-
this._overlayRef.keydownEvents().subscribe(event => {
581+
overlayRef.keydownEvents().subscribe(event => {
579582
// Close when pressing ESCAPE or ALT + UP_ARROW, based on the a11y guidelines.
580583
// See: https://www.w3.org/TR/wai-aria-practices-1.1/#textbox-keyboard-interaction
581584
if (event.keyCode === ESCAPE || (event.keyCode === UP_ARROW && event.altKey)) {
@@ -586,18 +589,21 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
586589

587590
if (this._viewportRuler) {
588591
this._viewportSubscription = this._viewportRuler.change().subscribe(() => {
589-
if (this.panelOpen && this._overlayRef) {
590-
this._overlayRef.updateSize({width: this._getPanelWidth()});
592+
if (this.panelOpen && overlayRef) {
593+
overlayRef.updateSize({width: this._getPanelWidth()});
591594
}
592595
});
593596
}
594597
} else {
595-
// Update the panel width and direction, in case anything has changed.
596-
this._overlayRef.updateSize({width: this._getPanelWidth()});
598+
const position = overlayRef.getConfig().positionStrategy as FlexibleConnectedPositionStrategy;
599+
600+
// Update the trigger, panel width and direction, in case anything has changed.
601+
position.setOrigin(this._getConnectedElement());
602+
overlayRef.updateSize({width: this._getPanelWidth()});
597603
}
598604

599-
if (this._overlayRef && !this._overlayRef.hasAttached()) {
600-
this._overlayRef.attach(this._portal);
605+
if (overlayRef && !overlayRef.hasAttached()) {
606+
overlayRef.attach(this._portal);
601607
this._closingActionsSubscription = this._subscribeToClosingActions();
602608
}
603609

‎src/lib/autocomplete/autocomplete.spec.ts

+32-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {
4747
MatAutocompleteModule,
4848
MatAutocompleteSelectedEvent,
4949
MatAutocompleteTrigger,
50+
MatAutocompleteOrigin,
5051
} from './index';
5152

5253

@@ -2218,6 +2219,34 @@ describe('MatAutocomplete', () => {
22182219
const fixture = createComponent(AutocompleteWithDifferentOrigin);
22192220

22202221
fixture.detectChanges();
2222+
fixture.componentInstance.connectedTo = fixture.componentInstance.alternateOrigin;
2223+
fixture.detectChanges();
2224+
fixture.componentInstance.trigger.openPanel();
2225+
fixture.detectChanges();
2226+
zone.simulateZoneExit();
2227+
2228+
const overlayRect =
2229+
overlayContainerElement.querySelector('.cdk-overlay-pane')!.getBoundingClientRect();
2230+
const originRect = fixture.nativeElement.querySelector('.origin').getBoundingClientRect();
2231+
2232+
expect(Math.floor(overlayRect.top)).toBe(Math.floor(originRect.bottom),
2233+
'Expected autocomplete panel to align with the bottom of the new origin.');
2234+
});
2235+
2236+
it('should be able to change the origin after the panel has been opened', () => {
2237+
const fixture = createComponent(AutocompleteWithDifferentOrigin);
2238+
2239+
fixture.detectChanges();
2240+
fixture.componentInstance.trigger.openPanel();
2241+
fixture.detectChanges();
2242+
zone.simulateZoneExit();
2243+
2244+
fixture.componentInstance.trigger.closePanel();
2245+
fixture.detectChanges();
2246+
2247+
fixture.componentInstance.connectedTo = fixture.componentInstance.alternateOrigin;
2248+
fixture.detectChanges();
2249+
22212250
fixture.componentInstance.trigger.openPanel();
22222251
fixture.detectChanges();
22232252
zone.simulateZoneExit();
@@ -2603,7 +2632,7 @@ class AutocompleteWithNumberInputAndNgModel {
26032632
<input
26042633
matInput
26052634
[matAutocomplete]="auto"
2606-
[matAutocompleteConnectedTo]="origin"
2635+
[matAutocompleteConnectedTo]="connectedTo"
26072636
[(ngModel)]="selectedValue">
26082637
</mat-form-field>
26092638
</div>
@@ -2623,8 +2652,10 @@ class AutocompleteWithNumberInputAndNgModel {
26232652
})
26242653
class AutocompleteWithDifferentOrigin {
26252654
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
2655+
@ViewChild(MatAutocompleteOrigin) alternateOrigin: MatAutocompleteOrigin;
26262656
selectedValue: string;
26272657
values = ['one', 'two', 'three'];
2658+
connectedTo?: MatAutocompleteOrigin;
26282659
}
26292660

26302661
@Component({

‎src/lib/autocomplete/public-api.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
export * from './autocomplete';
1010
export * from './autocomplete-module';
1111
export * from './autocomplete-trigger';
12-
12+
export * from './autocomplete-origin';

0 commit comments

Comments
 (0)
Please sign in to comment.