Search code examples
angularbootstrap-5bootstrap-accordion

Angular 12 Bootstrap 5 ngFor accordion does not close


I'm trying to create a ngFor dropdown accordion list in Angular 12 with bootstrap 5. Somehow the accordions stay open and can not be closed.

I hope someone knows how to make the accordion able to close.

https://getbootstrap.com/docs/5.0/components/accordion/

    <div class="accordion">
        <div class="accordion-item" *ngFor="let category of cateories; let i = index">
            <h2 class="accordion-header" [attr.id]="'heading' + i">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                    [attr.data-target]="'#collapse' + i" aria-expanded="true" [attr.aria-controls]="'collapse' + i">
                    {{ category.title }}
                </button>
            </h2>
            <div [attr.id]="'collapse' + i" class="accordion-collapse collapse show" [attr.aria-labelledby]="'heading' + i"
                data-bs-parent="#accordionExample">
                <div class="accordion-body">
                    <ul>
                        <li *ngFor="let childCategory of category.children">{{ childCategory.title }}</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

enter image description here


Solution

  • Somehow the accordions stay open and can not be closed.

    This is because you have not defined any way to make it close. You probably will need to configure JQuery and bootstrap script files ... Not really recommended.

    I would recommend you consider using a library for such components, something like ngx-accordion

    The other solution is to simply hard code the logic to close and open the accordion

    You can set a property to track whether the accordion is open. In your TS file

    openAccordion: boolean[] = []
    

    And in your html

    <div class="accordion">
      <div class="accordion-item" *ngFor="let category of cateories; let i = index">
        <h2 class="accordion-header" [attr.id]="'heading' + i">
          <button class="accordion-button" type="button"
                (click)='openAccordion[i] = !openAccordion[i]' data-bs-toggle="collapse"
                    [attr.data-target]="'#collapse' + i" aria-expanded="true" [attr.aria-controls]="'collapse' + i">
                    {{ category.title }}
                </button>
        </h2>
        <div [attr.id]="'collapse' + i" class="accordion-collapse collapse" [class.show]='openAccordion[i]'
          [attr.aria-labelledby]="'heading' + i" data-bs-parent="#accordionExample">
          <div class="accordion-body">
            <ul>
              <li *ngFor="let childCategory of category.children">{{ childCategory.title }}</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
    

    Sample Demo Here

    The other option is to include the bootstrap js file. Below is a demo of how this can be implemented

    <div class="accordion" id="accordionContainer">
      <div class="accordion-item" *ngFor="let category of cateories; let i = index">
        <h2 class="accordion-header" [id]="'heading' + i">
          <button class="accordion-button" type="button" data-bs-toggle="collapse" [attr.data-bs-target]="'#collapse' + i" aria-expanded="true" [attr.aria-controls]="'collapse' + i">
           {{ category.title }}
          </button>
        </h2>
        <div [id]="'collapse' + i" class="accordion-collapse collapse show" [attr.aria-labelledby]="'heading' + i"
          data-bs-parent="#accordionContainer">
          <div class="accordion-body">
            <ul>
              <li *ngFor="let childCategory of category.children">{{ childCategory.title }}</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
    

    See Demo