vogel22
vogel22

Reputation: 15

How do I loop through and toggle elements with the same class / VanillaJS?

I'm doing front-end for a search engine and I have a div that will repeat many times depending on the search results. All of them need to have truncated text and show more/less buttons. I'm using the toggle class to truncate the text. I wrote the code below, however, it only works for the first div and I don't know how to make it work for all of them. Can someone please help/explain it to me?

I have tried using a for loop, but I think I am doing something wrong

HTML

<p class="result-box-description truncate">Lorem ipsum dolor sit amet, magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit...</p>
<span class="show">show more</span>
<p class="result-box-description truncate">Lorem ipsum dolor sit amet, magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit...</p>
<span class="show">show more</span>
<p class="result-box-description truncate">Lorem ipsum dolor sit amet, magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit...</p>
<span class="show">show more</span>

CSS

p.result-box-description {
  @include tipography(14);
  color: #000;
  margin-top: 15px;
  margin-bottom: 15px;
  line-height: 1.2em;
  text-align: justify;

}
.truncate {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

JavaScript

window.onload = function () {
  document.querySelector('.show').addEventListener('click', textToggle);
};

function textToggle() {
  const paragraphs = document.getElementsByClassName('result-box-description');
  const btn = document.querySelector('.show');

  for (var i = 0; i < paragraphs.length; i++) {
    paragraphs[i].classList.toggle('truncate');
  }

  if (paragraphs.classList.contains('truncate')) {
    btn.innerHTML = 'show more';
  } else {
    btn.innerHTML = 'show less';
  }
}

I just want all of the divs to work the same way since I don't know what the actual number will be.

Upvotes: 0

Views: 68

Answers (2)

Alex Stulov
Alex Stulov

Reputation: 110

You should get all "show" buttons and attach the event to each of them. You can do it like this:

window.onload = function() {
  let shows = document.querySelectorAll('.show');
  shows.forEach((link) => { link.addEventListener('click', textToggle); });
};

function textToggle() {
  let paragraph = this.previousElementSibling;
  if (paragraph.classList.contains('truncate')) {
    paragraph.classList.remove('truncate');
    this.innerHTML = 'show less';
  } else {
    paragraph.classList.add('truncate');
    this.innerHTML = 'show more';
  }
}

I've used previousElementSibling inside textToggle to point to paragraph you want to toggle.

Here is a codepen: https://codepen.io/kinospro/pen/zVPZaJ

Upvotes: 1

shrys
shrys

Reputation: 5960

Is the following the correct outcome?

edit: Added toggling logic

window.onload = function() {
  Array.from(document.getElementsByClassName('show')).forEach(element => element.addEventListener('click', textToggle));
};

function textToggle(ev) {
  const paragraphs = document.getElementsByClassName('result-box-description');
  const btns = document.getElementsByClassName('show');

  var btn = ev.target;
  var para = ev.target.previousSibling.previousElementSibling;
  if (para.classList.contains("truncate")) {
    for (var i = 0; i < paragraphs.length; i++) {
      paragraphs[i].classList.add('truncate');
      btns[i].innerHTML = 'show more';
    }
    btn.innerHTML = "show less";
    para.classList.remove("truncate");
  } else {
    btn.innerHTML = "show more";
    para.classList.add("truncate");
  }
}
p.result-box-description {
  @include tipography(14);
  color: #000;
  margin-top: 15px;
  margin-bottom: 15px;
  line-height: 1.2em;
  text-align: justify;
}

.truncate {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
<p class="result-box-description truncate">Lorem ipsum dolor sit amet, magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis
  aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris
  nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit...</p>
<span class="show">show more</span>
<p class="result-box-description truncate">Lorem ipsum dolor sit amet, magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis
  aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris
  nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit...</p>
<span class="show">show more</span>
<p class="result-box-description truncate">Lorem ipsum dolor sit amet, magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis
  aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris
  nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptatelaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit...</p>
<span class="show">show more</span>

Upvotes: 1

Related Questions