Angular 2 Read More Directive
I made a version that uses character length rather than div size.
import { Component, Input, ElementRef, OnChanges} from '@angular/core';@Component({ selector: 'read-more', template: ` <div [innerHTML]="currentText"> </div> <a [class.hidden]="hideToggle" (click)="toggleView()">Read {{isCollapsed? 'more':'less'}}</a> `})export class ReadMoreComponent implements OnChanges { @Input() text: string; @Input() maxLength: number = 100; currentText: string; hideToggle: boolean = true; public isCollapsed: boolean = true; constructor(private elementRef: ElementRef) { } toggleView() { this.isCollapsed = !this.isCollapsed; this.determineView(); } determineView() { if (!this.text || this.text.length <= this.maxLength) { this.currentText = this.text; this.isCollapsed = false; this.hideToggle = true; return; } this.hideToggle = false; if (this.isCollapsed == true) { this.currentText = this.text.substring(0, this.maxLength) + "..."; } else if(this.isCollapsed == false) { this.currentText = this.text; } } ngOnChanges() { this.determineView(); }}
Usage:
<read-more [text]="text" [maxLength]="100"></read-more>
I think you'll need a Component
rather then Directive
. Components
makes more sense since you need to add Read more button/link, i.e. update DOM.
@Component({ selector: 'read-more', template: ` <div [class.collapsed]="isCollapsed"> <ng-content></ng-content> </div> <div (click)="isCollapsed = !isCollapsed">Read more</div> `, styles: [` div.collapsed { height: 250px; overflow: hidden; } `]})export class ReadMoreComponent { isCollapsed = true;}
Usage:
<read-more> <!-- you HTML goes here --></read-more>
With the help from Andzhik I am able to build the below component that meets my requirements.
import { Component, Input, ElementRef, AfterViewInit } from '@angular/core';@Component({ selector: 'read-more', template: ` <div [innerHTML]="text" [class.collapsed]="isCollapsed" [style.height]="isCollapsed ? maxHeight+'px' : 'auto'"> </div> <a *ngIf="isCollapsable" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed? 'more':'less'}}</a> `, styles: [` div.collapsed { overflow: hidden; } `]})export class ReadMoreComponent implements AfterViewInit { //the text that need to be put in the container @Input() text: string; //maximum height of the container @Input() maxHeight: number = 100; //set these to false to get the height of the expended container public isCollapsed: boolean = false; public isCollapsable: boolean = false; constructor(private elementRef: ElementRef) { } ngAfterViewInit() { let currentHeight = this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight; //collapsable only if the contents make container exceed the max height if (currentHeight > this.maxHeight) { this.isCollapsed = true; this.isCollapsable = true; } }}
Usage:
<read-more [text]="details" [maxHeight]="250"></read-more>