Essex
Essex

Reputation: 6128

How to create dynamic accordion?

I'm trying to make my accordion dynamical in my html template and I don't know how I can do that.

My html template is good, but I don't know how I can add javascript part in order to open/close subpanels with variable {{category}} as primary panel.

This is my HTML code :

{% for category in category_list %}
    <div class="panel-group accordion" id="accordion" role="tablist" aria-multiselectable="true">

      <div class="panel panel-default">
          <div class="panel-heading" role="tab">
              <h4 class="panel-title">
                  <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
                      <i class="more-less glyphicon glyphicon-plus"></i>
                      {{ category }}
                  </a>
              </h4>
          </div>
          {% for publication in category.publication.all %}
          <div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="accordion">
              <div class="panel-body">
                    {{ publication }}
              </div>
           </div>
          {% endfor %}
      </div>

    </div>
{% endfor %}

I'm pretty new with Javascript and I made something like that, but it doesn't work :

function toggleIcon(e) {
    $(e.target)
        .prev('.panel-heading')
        .find(".more-less")
        .toggleClass('glyphicon-plus glyphicon-minus');
}
$('.panel-group').on('hidden.bs.collapse', toggleIcon);
$('.panel-group').on('shown.bs.collapse', toggleIcon);

I don't know why, but it opens only the first accordion panel, even if I click over the second one or the third one ..

enter image description here

Upvotes: 2

Views: 3026

Answers (1)

Nomis
Nomis

Reputation: 904

The code you're showing doesn't deal with the hiding/showing of panels, so I'm gonna assume you're using a JS library AND that this library is using ids and datas to map things.

If that's the case, all you need is using unique ids, or else it'll always stop at the first accordion it find.

To do it, use your loop indexes :

<div class="panel-group accordion" id="accordion_{{ category.id }}" role="tablist" aria-multiselectable="true">

And link it to your a like so :

<a role="button" data-toggle="collapse" data-parent="#accordion_{{ category.id }}" href="#collapseOne_{{ issue }}" aria-expanded="true" aria-controls="collapseOne">

Here we have an issue : you also need to have one unique id for each CollapseOne, but the publication loop is after the a creation. Anyway, it's weird to have one a open multiple elements, so why not make it only one ?

<div id="collapseOne_{{ category.id }}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="accordion">
{% for publication in category.publication.all %}
          <div class="panel-body">
                {{ publication }}
          </div>
{% endfor %}
</div>

Replace the previous {{ issue }} in the a with {{ category }} and you should be set. Now to find if your library work as assumed ^^

You have to set {{category.id}} because if your category field contains spaces, it won't work.

Also I'm not used to templates so I hope it let you do that :p

Upvotes: 2

Related Questions