6

I would like to create a directive which apply ... when overflow. I have used dotdotdot jQuery plugin in the past but it doesn't really work in angular 5.

What I have till now is creating a directive called DotdotdotDirective with the selector [appDotdotdot] as shown below:

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

declare var $: any;

@Directive({
  selector: '[appDotdotdot]'
})
export class DotdotdotDirective {

  constructor(private el: ElementRef) { }

}

The usage is simple:

<h3><a href="#" appDotdotdot>{{data.trip.name}}</a></h3>

I have also imported the jQuery plugin in case this can be used inside the directive. index.html :

<script src="assets/js/jquery.dotdotdot.js"></script>

I'm expecting that the code should be implemented in the constructor but I don't know how to use it in angular 5 ? Should I use the directive as a wrapper to the jQuery plugin or maybe angular has different solution for this requirement? Thanks in advance!

R. Richards
  • 21,615
  • 9
  • 55
  • 58
user2304483
  • 777
  • 3
  • 11
  • 32

5 Answers5

17

You can do this only with css. Try this on your sentence div :

 white-space: nowrap;
 overflow: hidden;
 text-overflow: ellipsis;

... will appears if sentence is too long for the container div.

ghuntheur
  • 362
  • 1
  • 5
  • 16
6

Solution 1:

{{ (myString.length > 10) ? (myString | slice:0:10) + '...' : myString }}

Solution 2:

@Pipe({
    name: 'dotdotdot'
})

export class DotDotDotPipe implements PipeTransform {

    transform(value: string, limit: number): string {
        return value.length > limit ? value.substring(0, limit) + '...' : value;
    }
}

usage:

{{ myString | dotdotdot:10 }}
Balázs Takács
  • 1,148
  • 1
  • 5
  • 18
  • 1
    the solution has to be responsive, I assume that indicate the number of characters allowed explicitly won't work. The jQuery worked beautifully but I couldn't get it to work inside a directive – user2304483 Sep 22 '18 at 16:09
1

I haven't got the required 50 reputation points in order to post it as a comment therefore I post it as an answer: you may be interested into taking a look here: How to truncate text in Angular2? There are quite a few options available from using a simple {{str | slice:0:n}} to writing your own pipe.

Maciej21592
  • 114
  • 1
  • 13
  • the solution has to be responsive, I assume that indicate the number of characters allowed explicitly won't work. The jQuery worked beautifully but I couldn't get it to work inside a directive. – user2304483 Sep 22 '18 at 16:08
  • By dynamic I understand that you mean that it has to be responsive to changes happening to underlying values in the corresponding class which indeed is the case with the above solution; take a look at the snippet demonstrating it here: https://stackblitz.com/edit/angular-z6eet1?file=src%2Fapp%2Fapp.component.html – Maciej21592 Sep 22 '18 at 16:28
  • Just noticed the other answer, haha glad you found the solution ^^ – Maciej21592 Sep 22 '18 at 16:29
0

Although it'd be better to find a native angular solution, if you really want to use the jquery plugin you need to instantiate the dotdotdot plugin on the dom element.

The code below assumes that you have imported jquery and the dotdotdot plugin in your project.

From your component

component.ts

import { Component , ViewChild} from '@angular/core';
declare let $: any;
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  @ViewChild('test') elt; //get a reference to the element


  ngAfterViewInit()
  {
    $(this.elt.nativeElement).dotdotdot(
      {
        height: 70,watch: true
      }
    )
  }
}

Add the reference to your template

template.html

<div #test>content here </div>

Using a directive

If you want to use a directive, you could try this

directive.ts

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

declare var $: any;

@Directive({
  selector: '[dotdotdot]'
})
export class DotdotdotDirective {

constructor(private el: ElementRef) {

setTimeout(()=>{  
  $(el.nativeElement).dotdotdot({
   watch: true,
   height: 70
  });
});
 }

}

template.ts

Add the reference to your template

template.html

<div dotdotdot>content here </div>

Note: I added the setTimeout as it did not seem to work without, probably because there is no content yet in the element when the plugin is initiated

Stackblitz demo

David
  • 28,746
  • 10
  • 68
  • 95
  • The demo is working as expected I guess but I couldn't get it to work in my environment. I'm using the template:

    {{data.trip.name}}

    – user2304483 Sep 22 '18 at 17:46
  • The setTimeout is working fine cause I was able to use alert() command but the code for the dotdotdot didn't work $(el.nativeElement).dotdotdot({ truncate: "letter" }); – user2304483 Sep 22 '18 at 17:55
  • @user2304483 well if it only does not work on your environment I cannot really do much more – David Sep 22 '18 at 18:44
  • Unless the problem is that the plugin only works for the text that the element has when initialising the plugin. I haven't tested with dynamic text though ( it's late here) – David Sep 22 '18 at 20:04
0

There is an alternative solution for multiline text. It is pure angular directive, without jquery:

https://www.npmjs.com/package/multiline-dotdotdot

tdev
  • 136
  • 4