Angular 2 Read More Directive Angular 2 Read More Directive angular angular

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>