Reputation: 5040
I'm trying to make a multi-select dropdown component using angular material CDK overlay. As in the code below (taken from angular material select component)
<div class="multi-select-dd">
<label class="multi-select-dd-text">{{ label }}</label>
<div class="multi-select-dd-text-container">
<ul class="taggle_list"
cdk-overlay-origin
(click)="toggle()"
#origin="cdkOverlayOrigin"
#trigger>
<li>
<input type="text"
class="taggle_input"
tabindex="1"
style="padding-left: 0px; padding-right: 0px;"
autocomplete="off">
</li>
</ul>
</div>
</div>
<ng-template cdk-connected-overlay
cdkConnectedOverlayHasBackdrop
cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
[cdkConnectedOverlayOrigin]="origin"
[cdkConnectedOverlayOpen]="panelOpen"
[cdkConnectedOverlayPositions]="_positions"
[cdkConnectedOverlayMinWidth]="_triggerRect?.width"
[cdkConnectedOverlayOffsetY]="_offsetY"
(backdropClick)="close()"
(attach)="_onAttached()"
(detach)="close()">
<div style="background-color: lightgreen;">
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
</ul>
</div>
</ng-template>
So whenever an item is selected from dropdown, It'll be shown as a chip in the box which is the connected position. which will change the height of origin element.
Question: Is there any standard way in the overlay to reposition it startY position on overlay-origin height change?
Upvotes: 3
Views: 13734
Reputation: 6963
Found an easier way.
// data you want to show is contained in the matDialogConfig
let mc = this.getConfig(data);
// Tell Matdialog which Angular component to use.
let mdRef = this.md.open(MessageComponent, mc);
Grab the data out of MessageComponent
import { MAT_DIALOG_DATA } from "@angular/material/dialog";
import { Component, OnInit, AfterViewInit, Inject } from "@angular/core";
import { inject } from "@angular/core/testing";
@Component({
selector: "lib-message",
templateUrl: "./message.component.html",
styleUrls: ["./message.component.css"],
})
export class MessageComponent implements OnInit, AfterViewInit {
constructor(@Inject(MAT_DIALOG_DATA) public data: any) {
// get the injected dialog data
this.data = data;
}
ngOnInit(): void {}
ngAfterViewInit() {}
}
In HTML, this is only markup needed.
{{data}}
The CSS in the MessageComponent allows full control on position.
:host {
display: grid;
justify-content: center;
align-items: center;
background-color: yellow;
position: absolute;
top: 10em;
left: 20em;
height: 10em;
width: 20em;
box-shadow: 0 0 5px rgb(0, 0, 0, 0.27);
}
Your message component takes precedence over the CDK Overlay! Very nice.
Upvotes: 0
Reputation: 352
I was having the same issue and I found this way to update the position after it has been opened.
@ViewChild(CdkConnectedOverlay) cdkConnectedOverlay: CdkConnectedOverlay;
constructor() { }
ngOnInit() {
// this is triggered when its opened for the first time and each time you modify the position
// posChange is an Object ConnectedOverlayPositionChange that contains
// connectionPair: with originX/Y,Overlay X/Y and offsetsX/Y
// scrollableViewProperties
this.cdkConnectedOverlay.positionChange.pipe(first()).subscribe(posChange => {
// change any properties that you need about the connectedOverlay
this.cdkConnectedOverlay.offsetY = 0;
// this will trigger again positionChange thats why we only take the first
this.cdkConnectedOverlay.overlayRef.updatePosition();
});
}
Upvotes: 5