abhijith
abhijith

Reputation: 127

Close one accordion when another is open

I have tried a custom accordion where the first one is by default open when the page loads. There are 3 accordions in totality. I have to close an accordion when the other one is open.

I have tried giving a custom class like "active" to be attached to the accordions which are closed. The content for the accordion is coming from the API

      <div class="card-accordion">
        <div
          class="card"
          *ngFor="let q of popUpContent?.questions; let i = index"
        >
          <div
            class="card-header"
            id="headingOne"
            type="button"
            data-toggle="collapse"
            [attr.data-target]="'#collapse' + i"
            [attr.aria-expanded]="i == 0 ? true : false"
            aria-controls="collapseOne"
          >
          </div>

          <div
            id="collapse{{ i }}"
            class="collapse"
            [ngClass]="{ in: i == 0 }"
            aria-labelledby="headingOne"
            data-parent="#accordionExample"
          >
            <div class="card-body">{{ q.description }}</div>
          </div>
        </div>
      </div>

I expect that one accordion closes when the other one opens, but the actual output is that when i open the other accordion the previous one doesnt close

Upvotes: 2

Views: 4380

Answers (2)

Dhruvan Ganesh
Dhruvan Ganesh

Reputation: 1570

A simple accordion solution using *ngIf. You can use <div> tags instead of all the custom selectors in the template code below but I would advise against that as it is detrimental to the understandability of the code.

accordion.component.ts

class AccordionComponent {
  activeAccordion = 'One'

  isActive = (name: string) => this.activeAccordion === name

  setActive = (name: string) => this.activeAccordion = name
}

accordion.component.html

  <accordion-item title="Accordion One" [ngClass]="{ 'active': isActive('One') }" (click)="setActive('One')" >  
    <accordion-content *ngIf="isActive('One')"> ... </accordion-content>
  </accordion-item>

  <accordion-item title="Accordion Two" [ngClass]="{ 'active': isActive('Two') }" (click)="setActive('Two')" >
    <accordion-content *ngIf="isActive('Two')"> ... </accordion-content>
  </accordion-item>

  <accordion-item title="Accordion Three" [ngClass]="{ 'active': isActive('Three') }" (click)="setActive('Three')" >
    <accordion-content *ngIf="isActive('Three')"> ... </accordion-content>
  </accordion-item>

Working solution on StackBlitz : https://stackblitz.com/edit/angular-b57ybp

Upvotes: 1

Aravind Anil
Aravind Anil

Reputation: 153

A suggestion I can come up is:

Try adding a variable from typescript end with default value = index of the accordion with you want to be opened by default

currentAccordionindex = 0

Then apply 'active' class you mentioned(which I hope is to toggle betwwen opened and closed state of the accordion) like:

[ngClass]="currentAccordionindex === i ? 'active':'' "

Update this value for currentAccordionindex using (click) event upon the accordion.

Upvotes: 2

Related Questions