Toggle visibility of dynamic created content with jQuery

Hey,

this might be kind of a basic question, but I can’t solve the problem:

I have multiple elements which are dynamic. Each element should have a visibility toggle Button. How do I do that? Obviously right now, only the excerpt of the first element will be toggled.

I guess it can work with <?= $data->id() ?>, but I don’t know how to tell jQuery, that it should address the specific id.

      <div id="job-excerpt">
        <?= $data->jobbeschreibung()->kt() ?>
      </div>

    <div>
      <div id="excerpt-button"><img src="<?= url('assets/images/dropdown_icon.svg') ?>" alt="<?= $page->title()->html() ?>"></div>

    </div>
$(document).ready(function(){
  $("#excerpt-button").click(function(){
    $("#job-excerpt").toggle(500);
  });
});


Hi there,
the main problem is that you are working with ID’s. An ID should be unique, just change them to classes. You will see that now all job-excerpts will toggle when you click a button. So you have to go through your DOM to find the right element (Tree Traversal | jQuery API Documentation). The final code should look something like this in your loop:

      <div class="job-excerpt">
        <?= $data->jobbeschreibung()->kt() ?>
      </div>

    <div>
      <div class="excerpt-button"><img src="<?= url('assets/images/dropdown_icon.svg') ?>" alt="<?= $page->title()->html() ?>"></div>
    </div>

and this would be the jQuery:

$(document).ready(function(){
$(".job-excerpt").hide();
  $(".excerpt-button").click(function(e){
    e.preventDefault();
    var jobExcerpt = $(this).parent().prev(".job-excerpt");
    $(jobExcerpt).toggle(500);
  });
});

I hope this helps a little

cheers
tom

Hello!

I’m sorry, but I have a similar problem as well. I have a homepage that contains information populated by different pages. I have “read more” and “read less” as a general idea—the hope is that the viewer can press “read more” and expand the content individually.

<div class="container">
<main class="main">
             <?php foreach($site->children()->listed() as $item): ?>
                     <p>
                         <?php if ($item->excerpt()->isNotEmpty()): ?>
                             <?= $item->excerpt()->kirbytextinline() ?>
                         <?php endif ?>
                         <?php if ($item->text()->isNotEmpty()): ?>
                             <span class="readmore" id="<?= $page->title() ?>"><a href="#">(more)</a></span>
                                 <span class="extension" id="<?= $page->title() ?>">
                                     <?= $item->text()->kirbytextinline() ?>
                                     <span class="readless" id="<?= $page->title() ?>"><a href="#">(less)</a></span>
                                 </span>
                         <?php endif ?>
                     </p>
                 <?php endforeach ?>
         </main> 
     </div>

Currently, the jquery is like this, but of course, it ends up expanding everything at once instead of just the section the “read more button” is under.

$(document).ready(function() {
     console.log( "ready!" );
     $(".extension").hide();
     $("#less" ).hide();
 
     $(".readmore").click(function() {
         $("span.extension" ).show(),
         $(".readless" ).show(),
         $(".readmore").hide();
     });
 
     $(".readless").click(function() {
         $("span.extension" ).hide(),
         $(".readless" ).hide(),
         $(".readmore").show();
     });
 });

You would have to use $this.next('extension') to get the next sibling element or for showing less, then get the parent element.

1 Like