Skip to content

Instantly share code, notes, and snippets.

@harbirchahal
Last active October 16, 2022 15:04
Show Gist options
  • Save harbirchahal/6b404c0486f45e176724ff5843e97a56 to your computer and use it in GitHub Desktop.
Save harbirchahal/6b404c0486f45e176724ff5843e97a56 to your computer and use it in GitHub Desktop.
Show more/less button to toggle extra list items
import {
AfterContentInit,
ContentChildren,
Directive,
ElementRef,
Input,
QueryList,
Renderer2,
} from '@angular/core';
import { startWith } from 'rxjs/operators';
enum Text {
MORE = 'more',
LESS = 'less',
}
enum Display {
BLOCK = 'block',
NONE = 'none',
}
/**
* Usage:
* <ul fcMoreLessItems limit="5">
* <li #fcToggleItem *ngFor="let item of list">{{ item }}</li>
* </ul>
*/
@Directive({
selector: '[fcMoreLessItems]',
})
export class MoreLessItemsDirective implements AfterContentInit {
@Input() limit: number = 0;
@Input() display: string = Display.BLOCK; // block | grid | flex | ...
@ContentChildren('fcToggleItem') togglableItems!: QueryList<ElementRef>;
expanded: boolean = false;
readonly toggleEl: HTMLElement;
constructor(readonly renderer: Renderer2, readonly element: ElementRef) {
this.toggleEl = this.createToggleElement();
}
ngAfterContentInit() {
this.renderer.appendChild(this.element.nativeElement, this.toggleEl);
this.togglableItems.changes
.pipe(startWith(new QueryList()))
.subscribe(() => {
if (!this.expanded) {
// Hide extra items
this.updateItemsDisplay(Display.NONE);
}
});
}
private createToggleElement(): HTMLElement {
const button = this.renderer.createElement('button');
button.innerText = Text.MORE;
button.onclick = () => {
if (this.expanded) {
this.updateItemsDisplay(Display.NONE);
this.toggleEl.innerText = Text.MORE;
} else {
this.updateItemsDisplay(this.display);
this.toggleEl.innerText = Text.LESS;
}
this.expanded = !this.expanded;
};
return button;
}
private updateItemsDisplay(cssClass: string) {
for (let i = this.limit; i < this.togglableItems.length; i++) {
const child = this.togglableItems.get(i)!;
child.nativeElement.style.display = cssClass;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment