Benito Serna Tips and tools for Ruby on Rails developers

A "read-more" behavior truncating with rails truncate helper and Stimulus.js

A code sample of a “read-more” behavior using the rails truncate method and Stimulus.js.

The example

Visit example page

The html and css

Your are going to need…

.hide { display: none; }
<div data-controller="read-more"
     data-read-more-full-content-value="This is the full content without truncation"
     data-read-more-hide-class="hide">
  <p data-read-more-target="content">
    This is the truncated....
  </p>
  <button class="hide"
    data-read-more-target="moreButton"
    data-action="read-more#showMore">
    Show more
  </button>
  <button class="hide"
    data-read-more-target="lessButton"
    data-action="read-more#showLess">
    Show less
  </button>
</div>

To truncate the content, you can use the truncate helper.

truncate("Once upon a time in a world far far away")

The javascript

Here you are going to toggle the truncated content and the full content as needed.

class ReadMoreController extends Stimulus.Controller {
  static get targets() {
    return ["content", "moreButton", "lessButton"]
  }

  static get classes() {
    return ["hide"]
  }

  static get values() {
    return { fullContent: String }
  }

  connect() {
    this.truncatedContent = this.contentTarget.textContent.trim();
    this.render()
  }

  render() {
    if (this.truncateContent != this.fullContentValue) {
      this.showLess()
    } else {
      this.hide(this.moreButtonTarget);
      this.hide(this.lessButtonTarget);
    }
  }

  showMore() {
    this.contentTarget.textContent = this.fullContentValue;
    this.hide(this.moreButtonTarget);
    this.show(this.lessButtonTarget);
  }

  showLess() {
    this.contentTarget.textContent = this.truncateContent;
    this.hide(this.lessButtonTarget);
    this.show(this.moreButtonTarget);
  }

  show(target) {
    target.classList.remove(this.hideClass)
  }

  hide(target) {
    target.classList.add(this.hideClass)
  }
}

Other ways of doing it…

If instead of number characters or words you need to truncate your content by number of lines, you can try these examples.