4

I have the following template with a "dotdotdot" css class which add ellipsis on overflow correctly.

<div class="dotdotdot">{{data.trip.name}}</div>

What I'm trying to do here is to implement a directive which add a tooltip when the ellipsis is activated only.

Here is the current code from the directive:

import { Directive, OnInit, ElementRef } from '@angular/core';

declare var $: any;

@Directive({
  selector: '.dotdotdot'
})
export class DotdotdotDirective implements OnInit {

  private el: HTMLElement;
  constructor(elRef: ElementRef) {
    this.el = elRef.nativeElement;
}

ngOnInit() {           
         if (this.isEllipsisActive(this.el)) {   
            // TODO add title attribute to the div with value from text         
            $(this.el).tooltip();     
         }         
}

isEllipsisActive(e) {
     return (e.offsetWidth < e.scrollWidth);
}

}

I have two problems in the code above:

  1. isEllipsisActive is not working, I need the way to identified the ellipsis.
  2. I need to know how to add title or [title] attribute dynamically from $(this.el). The value is the text from the div.

Thanks!

user2304483
  • 1,462
  • 6
  • 28
  • 50
  • Possible duplicate of [HTML text-overflow ellipsis detection](https://stackoverflow.com/questions/7738117/html-text-overflow-ellipsis-detection) – tao Sep 24 '18 at 13:24
  • It works without jQuery. See [this stackblitz](https://stackblitz.com/edit/angular-problem-databinding-svyhec). – ConnorsFan Sep 24 '18 at 14:33
  • A bit more robust answer can be found [here](https://stackoverflow.com/a/55106043/540352). It works with `ngAfterViewChecked` so no `setTimeout` required + also clears the title if it is not necessary anymore when the `innerText` changes. – Laoujin Mar 11 '19 at 17:41

4 Answers4

13

You can create this directive:

import { AfterViewInit, Directive, ElementRef, EventEmitter, Output } from 

'@angular/core';

@Directive({
  selector: '[isEllipsisActive]'
})
export class IsEllipsisActiveDirective implements AfterViewInit {

  constructor(private elementRef: ElementRef) {}

  ngAfterViewInit(): void {
    setTimeout(() => {
      const element = this.elementRef.nativeElement;
      if(element.offsetWidth < element.scrollWidth){
        element.title = element.innerHTML;
      }
    }, 500);
  }
}

take a look on this https://stackblitz.com/edit/angular-qjmg7m?file=src%2Fapp%2Fis-ellipsis-active.directive.ts

ofir fridman
  • 2,691
  • 2
  • 17
  • 27
7

Great answer by ofir - Here's a modified version that will work if text changes after initialization.

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[isEllipsisActive]'
})

export class isEllipsisActiveDirective {

  constructor(private elementRef: ElementRef) {}

  @HostListener('mouseenter')
  onMouseEnter(): void {
    setTimeout(() => {
      const element = this.elementRef.nativeElement;
      if (element.offsetWidth < element.scrollWidth) {
        element.title = element.textContent;
      }
      else if (element.title) element.removeAttribute('title'); 
    }, 500);
  }
}
Chris
  • 1,154
  • 10
  • 15
  • The setTimeout isn't necessary but great idea. Helped me out a lot. – Jimeh Oct 29 '21 at 23:49
  • there should be a little bit different solution if you want to show it with delay on each hover, other than that, thank you for this. btw, it works strangely with kendo slider for angular. when I hover - code works, but title shows only when I do mousemove again (looks like it needs to recalculate UI based on mouse movement or something). Cant defeat it :) – Heorhii Hehelia Mar 27 '23 at 13:54
1
  isEllipsisActive(e: HTMLElement): boolean {
    return e ? (e.offsetWidth < e.scrollWidth) : false;
  }
<mat-card>
    <mat-card-title #galleryTitle [matTooltip]="gallery.name"
        [matTooltipDisabled]="!isEllipsisActive(galleryTitle)">
        {{gallery.name}}
    </mat-card-title>
<mat-card>
Austen Stone
  • 948
  • 1
  • 10
  • 21
0

You can use the disableTooltip property, and make a function for return if disable or not.

https://stackblitz.com/edit/sample-smart-tooltip