Angular: Slice and *ngIf for Conditional Ellipsis / Tooltip on Data

Ria Pacheco - Nov 17 '21 - - Dev Community

Problem: Conditional Ellipsis without CSS

I want to add an ellipsis to data that's brought in from a service without having to use CSS' text-overflow: ellipsis feature, since it's unreliable and could break overtime if not monitored during refactoring.


Using Slice Pipe

Determine character max overflow limit

  • Determine max overflow by number of characters (instead of max-width)
  • Example: max overflow characters 20 (inclusive, aka 20 or more)
  • I use slice pipe where you add the start and end of the slice to the interpolated string
<!--Template-->
<a *ngFor="let item of items">
  {{ item.name | slice: 0 : 20 }}
</a>
Enter fullscreen mode Exit fullscreen mode

Add ellipsis as conditional span

  • Conditional span is based on data's length
<!--Template-->
<a *ngFor="let item of items">
  {{ item.name | slice:0:20 }}<span *ngIf="item.name.length >= 20">...</span>
</a>
Enter fullscreen mode Exit fullscreen mode

If Problems with String vs. Object

Sometimes typescript or certain db packages make this harder by making it so strings are but aren't considered strings. Solve this programmatically, by saving a new boolean value, when the data is either stored or updated:

// Component
onSave(event: any, item: Iitem): void {
  if (String(this.item.name).length >= 20) {
    this.item.maxChar == true;
  }
  if (event) {
    this.dataService.addItem(this.item);
  }
}
Enter fullscreen mode Exit fullscreen mode

Thus, can then apply in template as

<!--Template-->
<span *ngIf="item.maxChar == true">...</span>
Enter fullscreen mode Exit fullscreen mode

Show Tooltip Conditionally

I want the tooltip to appear when this maxChar is true; but to remove itself from the DOM when no longer hovering over the item.

<!--Template-->
<a
  *ngFor="let item of items"
  (mouseover)="(item.name.length >= 20) ? onHover($event, item.name) : ''"
  (mouseout)="showsTooltip ? (showsTooltip = !showsTooltip) : ''">
  {{ item.name | slice:0:20 }}<span *ngIf="item.name.length >= 20">...</span>
<a>

<!--Tooltip-->
<div
  *ngIf="showsTooltip"
  [style.top]="tooltipTopY"
  [style.left]="tooltipLeftX"
  class="tooltip"
  >
  {{ tooltipText }}
</div>
Enter fullscreen mode Exit fullscreen mode

Component

Catches coordinates of event and binds them

export class SomeComponent implements OnInit {
  // Properties
  showsTooltip = false; // show or not
  tooltipText = ''; // text to be binded
  tooltipTopY!: any;
  tooltipLeftX!: any;

  // Methods
  onHover(event: any, itemName: string): void {
    this.tooltipText = itemName;
    if (event) {
      this.showsTooltip = true;
      this.tooltipTopY = event.clientY + 'px';
      this.tooltipLeftX = event.clientX + 'px';
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . .