From cbd8787c898941b50181777f130170154c21e8d9 Mon Sep 17 00:00:00 2001 From: MattMo Date: Wed, 20 Nov 2024 07:54:07 -0800 Subject: [PATCH] Added the ability to limit the number of lines that are allowed to be rendered before collapsing. Cleaned up code and simplified a few things. Renamed limit to maxLength. Fixed an issue where newlines would not render because of the text element, switched to a span instead. --- readmore.js | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/readmore.js b/readmore.js index 9ae29b0..993b0df 100644 --- a/readmore.js +++ b/readmore.js @@ -1,6 +1,6 @@ import { IgniteHtml, IgniteProperty } from '../ignite-html/ignite-html.js'; import { IgniteElement } from "../ignite-html/ignite-element.js"; -import { IgniteTemplate, slot, list, div, text, button } from "../ignite-html/ignite-template.js"; +import { IgniteTemplate, slot, list, div, text, button, span } from "../ignite-html/ignite-template.js"; class ReadMore extends IgniteElement { constructor() { @@ -9,29 +9,52 @@ class ReadMore extends IgniteElement { get properties() { return { - limit: 125, + maxLength: 125, + maxLines: 1, value: new IgniteProperty(null, { - onChange: (oldValue, newValue) => { - this.collapsed = true; - } + onChange: () => this.collapsed = true }), collapsed: true, collapsedValue: null, - collapseButtonClass: "btn btn-none p-0 d-block text-primary" + collapseButtonClass: "btn btn-none p-0 ps-1 d-inline text-primary" }; } render() { return this.template.child( - new text([this.collapsed, this.value, this.limit], (collapsed, value, limit) => collapsed && value && value.length > limit ? value.substring(0, limit).trimEnd() + "..." : (value ? value : "")), + new span().innerText([this.collapsed, this.value, this.maxLength, this.maxLines], (collapsed, value, maxLength, maxLines) => collapsed ? this.truncate() : value), new button() - .show([this.value, this.limit], (value, limit) => value && value.length > limit) + .show([this.value, this.maxLength, this.maxLines], (value, maxLength, maxLines) => this.truncate() != value) .class(this.collapseButtonClass) .innerText(this.collapsed, collapsed => collapsed ? "Read more" : "Read less") .onClick(() => this.collapsed = !this.collapsed) ) } + + truncate() { + //Only do this if the value isn't null. + if (this.value) { + //Speed up, if we are not restricting lines, then just check the length. + if (this.maxLines < 0 && this.value.length > this.maxLength) { + return value.substring(0, this.maxLength).trimEnd() + "..."; + } else { + //Check for lines and length, whichever we hit first stop. + var lines = 0; + for (var i = 0; i < this.value.length; i++) { + if (this.value[i] == '\n') { + lines++; + } + + if (i > this.maxLength || lines > this.maxLines) { + return this.value.substring(0, i).trimEnd() + "..."; + } + } + } + } + + return this.value; + } } class ReadMoreTemplate extends IgniteTemplate {