I have added 2 tables in stackblitz link, if I hover in first table(1st column) alst rows the tooltip opens above(expected) but when we scroll down the page and then hover on the last rows of 2nd table, the tooltip gets hidden in the bottom of the screen, as was not the case if I have a single table. I was expecting the tooltip to be opened above instead of getting hidden in the bottom. Please suggest.
Stacblitz link
.html
tooltip-overview-example.html
<ng-container matColumnDef="Column1">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Alert </th>
<td mat-cell *matCellDef="let row; let i = index" customToolTip [contentTemplate]="template">
<span >{{row.Column1}}</span>
<!--TOOLTIP-->
<ng-template #template>
<div style="display: flex; flex-direction: column">
<span>{{row.conditionals | json}}</span>
<button (click)="onClick(i)">Click</button>
</div>
</ng-template>
</td>
</ng-container>
Extended the Angular material TooltipComponent in CustomToolTipComponent
custom-tool-tipponent.ts
import {
Component,
OnInit,
OnDestroy,
Input,
TemplateRef
} from "@angular/core";
import {TooltipComponent} from "@angular/material/tooltip"
import { Observable, Subject } from "rxjs";
@Component({
selector: "app-custom-tool-tip",
templateUrl: "./custom-tool-tipponent.html",
styleUrls: ["./custom-tool-tipponent.css"]
})
export class CustomToolTipComponent extends TooltipComponent {
@Input() text: string;
@Input() contentTemplate: TemplateRef<any>;
}
custom-tool-tipponent.html
<div>
<div class="tooltip-conatiner">
<ng-template #simpleText>
{{text}}
</ng-template>
<ng-container *ngTemplateOutlet="contentTemplate || simpleText">
</ng-container>
</div>
</div>
tool-tip-renderer.directive.ts
@Directive({
selector: "[customToolTip]"
})
export class ToolTipRendererDirective {
@Input() showToolTip: boolean = true;
//If this is specified then specified text will be showin in the tooltip
@Input(`customToolTip`) text: string;
//If this is specified then specified template will be rendered in the tooltip
@Input() contentTemplate: TemplateRef<any>;
private _overlayRef: OverlayRef;
private _tooltipInstance;
private _mouseInTooltip: boolean = false;
private _hasListeners: boolean = false;
constructor(
private _overlay: Overlay,
private _overlayPositionBuilder: OverlayPositionBuilder,
private _elementRef: ElementRef,
private _r2: Renderer2
) {}
ngOnInit() {
if (!this.showToolTip) {
return;
}
const positionStrategy = this._overlayPositionBuilder
.flexibleConnectedTo(this._elementRef)
.withPositions([
{
originX: "center",
originY: "bottom",
overlayX: "center",
overlayY: "top",
offsetY: -10
}
]);
this._overlayRef = this._overlay.create({ positionStrategy });
}
@HostListener("mouseenter")
show(e) {
if (this._overlayRef && !this._overlayRef.hasAttached()) {
//set tooltip instance
this._tooltipInstance = this._overlayRef.attach(
new ComponentPortal(CustomToolTipComponent)
).instance;
//set CustomToolTipComponenet content/inputs
this._tooltipInstance.text = this.text;
this._tooltipInstance.contentTemplate = this.contentTemplate;
//render tooltip
this._tooltipInstance!.show(0);
//sub to detach after hide anitmation is plete
this._tooltipInstance
.afterHidden()
.pipe(take(1))
.subscribe(() => {
this._overlayRef.detach();
});
if (!this._hasListeners) {
this._hasListeners = true;
//attach mouseleave listener to detach when mouseleave on tooltip
this._r2.listen(this._overlayRef.overlayElement, "mouseleave", () => {
//call hide function in this directive
this._mouseInTooltip = false;
this.hide();
});
this._r2.listen(this._overlayRef.overlayElement, "mouseenter", () => {
//call hide function in this directive
this._mouseInTooltip = true;
});
}
}
}
@HostListener("mouseleave")
hide(buttonClicked = null) {
if(buttonClicked)
this._mouseInTooltip = false;
setTimeout(() => {
if (!this._mouseInTooltip) this._tooltipInstance!._onHide.next();
}, 20);
}
}
I have added 2 tables in stackblitz link, if I hover in first table(1st column) alst rows the tooltip opens above(expected) but when we scroll down the page and then hover on the last rows of 2nd table, the tooltip gets hidden in the bottom of the screen, as was not the case if I have a single table. I was expecting the tooltip to be opened above instead of getting hidden in the bottom. Please suggest.
Stacblitz link
https://stackblitz./edit/angular-mat-tooltip-ctvigc?file=app%2Ftooltip-overview-example.html
tooltip-overview-example.html
<ng-container matColumnDef="Column1">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Alert </th>
<td mat-cell *matCellDef="let row; let i = index" customToolTip [contentTemplate]="template">
<span >{{row.Column1}}</span>
<!--TOOLTIP-->
<ng-template #template>
<div style="display: flex; flex-direction: column">
<span>{{row.conditionals | json}}</span>
<button (click)="onClick(i)">Click</button>
</div>
</ng-template>
</td>
</ng-container>
Extended the Angular material TooltipComponent in CustomToolTipComponent
custom-tool-tip.ponent.ts
import {
Component,
OnInit,
OnDestroy,
Input,
TemplateRef
} from "@angular/core";
import {TooltipComponent} from "@angular/material/tooltip"
import { Observable, Subject } from "rxjs";
@Component({
selector: "app-custom-tool-tip",
templateUrl: "./custom-tool-tip.ponent.html",
styleUrls: ["./custom-tool-tip.ponent.css"]
})
export class CustomToolTipComponent extends TooltipComponent {
@Input() text: string;
@Input() contentTemplate: TemplateRef<any>;
}
custom-tool-tip.ponent.html
<div>
<div class="tooltip-conatiner">
<ng-template #simpleText>
{{text}}
</ng-template>
<ng-container *ngTemplateOutlet="contentTemplate || simpleText">
</ng-container>
</div>
</div>
tool-tip-renderer.directive.ts
@Directive({
selector: "[customToolTip]"
})
export class ToolTipRendererDirective {
@Input() showToolTip: boolean = true;
//If this is specified then specified text will be showin in the tooltip
@Input(`customToolTip`) text: string;
//If this is specified then specified template will be rendered in the tooltip
@Input() contentTemplate: TemplateRef<any>;
private _overlayRef: OverlayRef;
private _tooltipInstance;
private _mouseInTooltip: boolean = false;
private _hasListeners: boolean = false;
constructor(
private _overlay: Overlay,
private _overlayPositionBuilder: OverlayPositionBuilder,
private _elementRef: ElementRef,
private _r2: Renderer2
) {}
ngOnInit() {
if (!this.showToolTip) {
return;
}
const positionStrategy = this._overlayPositionBuilder
.flexibleConnectedTo(this._elementRef)
.withPositions([
{
originX: "center",
originY: "bottom",
overlayX: "center",
overlayY: "top",
offsetY: -10
}
]);
this._overlayRef = this._overlay.create({ positionStrategy });
}
@HostListener("mouseenter")
show(e) {
if (this._overlayRef && !this._overlayRef.hasAttached()) {
//set tooltip instance
this._tooltipInstance = this._overlayRef.attach(
new ComponentPortal(CustomToolTipComponent)
).instance;
//set CustomToolTipComponenet content/inputs
this._tooltipInstance.text = this.text;
this._tooltipInstance.contentTemplate = this.contentTemplate;
//render tooltip
this._tooltipInstance!.show(0);
//sub to detach after hide anitmation is plete
this._tooltipInstance
.afterHidden()
.pipe(take(1))
.subscribe(() => {
this._overlayRef.detach();
});
if (!this._hasListeners) {
this._hasListeners = true;
//attach mouseleave listener to detach when mouseleave on tooltip
this._r2.listen(this._overlayRef.overlayElement, "mouseleave", () => {
//call hide function in this directive
this._mouseInTooltip = false;
this.hide();
});
this._r2.listen(this._overlayRef.overlayElement, "mouseenter", () => {
//call hide function in this directive
this._mouseInTooltip = true;
});
}
}
}
@HostListener("mouseleave")
hide(buttonClicked = null) {
if(buttonClicked)
this._mouseInTooltip = false;
setTimeout(() => {
if (!this._mouseInTooltip) this._tooltipInstance!._onHide.next();
}, 20);
}
}
Share
Improve this question
edited Jun 20, 2020 at 9:12
CommunityBot
11 silver badge
asked Apr 13, 2020 at 16:10
EnthuEnthu
5322 gold badges15 silver badges42 bronze badges
3
- where is stackblitz link? – Gourav Garg Commented Apr 14, 2020 at 17:05
- @GouravGarg, my bad missed it , have added now, thanks – Enthu Commented Apr 14, 2020 at 20:07
- Can you update your project to angular 7? – Gourav Garg Commented Apr 15, 2020 at 7:08
2 Answers
Reset to default 3To fix this, you need to upgrade your cdk version to 7.3.7 which has a new method on OverlayRef as updatePositionStrategy.
According to this method you can change the position strategy of an overlay after attach.
In your show function after attaching the ponent you need to update position strategy as below:
this._overlayRef.updatePositionStrategy(this._overlayPositionBuilder
.flexibleConnectedTo(this._elementRef)
.withPositions([{
originX: "center",
originY: "bottom",
overlayX: "center",
overlayY: "top",
offsetY: this.getOffsetY()
}]));
this._overlayRef.updatePosition();
where this.getOffsetY() is private method provide offset y value based on element current position. You may need to update this logic.
private getOffsetY() {
if (this._elementRef.nativeElement.getBoundingClientRect().bottom > 500)
return -400;
if (this._elementRef.nativeElement.getBoundingClientRect().bottom > 400)
return -300;
if (this._elementRef.nativeElement.getBoundingClientRect().bottom > 300)
return -200;
return -10;
}
Here is stackblitz link
You can get the event.screenX and Event event.screenY position and using that check the height of the screen by getting screen height and screen width .
screen.height
Then check if the event is not near to the screen height if then make the [matTooltipPosition]="position.value"
to be above..
Like this you have to check
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745298099a4621265.html
评论列表(0条)