0

Can anyone please help me with this bit of code.I do not understand what is wrong and why it's not performing. Thanks.

var i = 0;
$('.course-testimonial-wrapper .testimonial-content-text').each(function() {
  // console.log(i);

  $(this).attr('id', 'testimonial-' + i);
  $(this).append('<div class="description-overlay" id="d-over-' + i + '"></div>');
  $(this).after('<div><button class="btn green show-more-' + i + ' shadow-0 p-0 medium" style="font-size: 14px;">Mostra di più <i class="fi-rr-angle-small-down"></i></button></div>');

  $('.show-more-' + i + '').click(function() {
    $('#testimonial-' + i + '').toggleClass('expand');
    $('#d-over-' + i + '').toggleClass('d-none');

    if ($('#testimonial-' + i + '').hasClass('expand')) {
      $('.show-more-' + i + '').html('Mostra di meno <i class="fi-rr-angle-small-up"></i>');
    } else {
      $('.show-more-' + i + '').html('Mostra di più <i class="fi-rr-angle-small-down"></i>');
    }
  })
  i++;
})
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
ross80
  • 23
  • 4
  • 2
    What do you mean by it is "not performing"? See how to create a [minimal, concrete and verifiable example](https://stackoverflow.com/help/minimal-reproducible-example). – Terry Feb 11 '21 at 10:44
  • not performing i mean not working sorry – ross80 Feb 11 '21 at 10:46
  • The click() function inside the each() function is not working. – ross80 Feb 11 '21 at 10:47
  • Do more logging, like `$('.show-more-' + i + '').length` or such – Christophe Roussy Feb 11 '21 at 10:48
  • Do some basic debugging. Does the callback passed to `.each()` actually run? If so, does the selector you're trying to bind the click event to (`$('.show-more-' + i + '')`) actually find an element? Etc. – Mitya Feb 11 '21 at 10:49
  • Yep, the each() function works properly, add all the stuff with all method .attr(), .append() and .after() only .click() is not working – ross80 Feb 11 '21 at 10:53
  • Do you get the click event? ie if you add an alert/console.log as the first line, does it fire? "not working" is extremely unhelpful, see https://idownvotedbecau.se/itsnotworking/ – freedomn-m Feb 11 '21 at 10:58

2 Answers2

1

You don't need to use i to make it more dynamic. You could do it like this.

$('.show-more').click(function() {
  var testimonial = $(this).parent().prev();
  testimonial.toggleClass('expand');
  testimonial.find('.description-overlay').toggleClass('d-none');

  if (testimonial.hasClass('expand')) {
    $(this).html('Mostra di meno <i class="fi-rr-angle-small-up"></i>');
  } else {
    $(this).html('Mostra di più <i class="fi-rr-angle-small-down"></i>');
  }
})

Demo

$('.testimonial-content-text').each(function(i, x) {
  // console.log(i);
  $(this).attr('id', 'testimonial-' + i);
  $(this).append('<div class="description-overlay" id="d-over-' + i + '"></div>');
  $(this).after('<div><button class="btn green show-more shadow-0 p-0 medium" style="font-size: 14px;">Mostra di più <i class="fi-rr-angle-small-down"></i></button></div>');


})

$('.show-more').click(function() {
  var testimonial = $(this).parent().prev();
  testimonial.toggleClass('expand');
  testimonial.find('.description-overlay').toggleClass('d-none');

  if (testimonial.hasClass('expand')) {
    $(this).html('Mostra di meno <i class="fi-rr-angle-small-up"></i>');
  } else {
    $(this).html('Mostra di più <i class="fi-rr-angle-small-down"></i>');
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="testimonial-content-text">test1</div>
<div class="testimonial-content-text">test2</div>
Carsten Løvbo Andersen
  • 26,637
  • 10
  • 47
  • 77
1

The issue is to do with the scope of the i variable. When your loop completes i will be the final value it was set to in the iteration. You can fix this with a closure.

However a far better approach is to get rid of the unnecessary incremental id and class attributes, and use common class names instead. Then you can traverse the DOM to find the related elements and update them as required, all within a single delegated event handler which is created once outside the loop. Try this:

$('.course-testimonial-wrapper .testimonial-content-text').each(function() {
  $(this).append('<div class="description-overlay">Description overlay...</div>');
  $(this).after('<div><button class="btn green show-more shadow-0 p-0 medium">Mostra di più <i class="fi-rr-angle-small-down"></i></button></div>');
});

$('.course-testimonial-wrapper').on('click', '.show-more', function() {
  let $btn = $(this);
  let $content = $btn.closest('.course-testimonial-wrapper').find('.testimonial-content-text').toggleClass('expand');
  $content.find('.description-overlay').toggleClass('d-none');

  if ($content.hasClass('expand')) {
    $btn.html('Mostra di meno <i class="fi-rr-angle-small-up"></i>');
  } else {
    $btn.html('Mostra di più <i class="fi-rr-angle-small-down"></i>');
  }
});
.show-more {
  font-size: 14px;
}

.d-none {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="course-testimonial-wrapper">
  <div class="testimonial-content-text"></div>
</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339