Reputation: 2061
I am a beginner for angular and I am trying to Accordions using below code but it's not working and showing error like event.getElementsByClassName is not a function can someone help me please where did I do wrong
h2>Accordion</h2>
<button class="accordion" (click) = "expand($event)">Section 1</button>
<div class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button class="accordion" (click) = "expand($event)">Section 2</button>
<div class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button class="accordion" (click) = "expand($event)">Section 3</button>
<div class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
export class HomePage {
expand(event){
var panel = event.getElementsByClassName("accordion");
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
}
}
Upvotes: 1
Views: 3911
Reputation: 39482
If you have a dynamic list that you'd get from some API and then you want to render that in the accordion, you can create a CSS class(visible
say) to apply a display: block
Then, create a property(currentIndex
) in your Component Class. Whenever you click on a section, just set the currentIndex
to the index of the section that was clicked. And based on the currentIndex
, apply the visible
CSS class via [ngClass]
Template:
<h2>Accordion</h2>
<div *ngFor="let section of sections; let i = index;">
<button class="accordion" (click) = "expand(i)">{{section.name}}</button>
<div class="panel"
[ngClass]="{ 'visible' : currentIndex === i }">
<p>{{section.content}}</p>
</div>
</div>
Class:
export class HomePage {
currentIndex = -1;
sections = [
{ name: 'Section 1', content: 'Content 1' },
{ name: 'Section 2', content: 'Content 2' },
{ name: 'Section 3', content: 'Content 3' },
...
];
expand(index) {
if(this.currentIndex === index) {
this.currentIndex = null;
return;
}
this.currentIndex = index;
}
}
CSS:
...
.visible {
display: block;
}
Here's a StackBlitz for your ref.
Upvotes: 0
Reputation:
Although you have the good idea, you should stop using "old ways".
Angular is a framework with very powerful features. If you don't take advantage of them to their full extent, then you should not use it !
For instance look at this stackblitz : although very minimal, it shows the power of Angular. No code in the component, and you already have an (non-animated) accordion !
<div class="accordion">
<h2 class="title" (click)="opened = !opened">Title of the accordion</h2>
<div class="content-container" [class.opened]="opened">
<p class="content">Content of the accordion</p>
</div>
</div>
I would suggest you to read the documentation so that you see everything Angular can do. I know it's long, but trust me, it's worth it.
Upvotes: 2
Reputation: 9678
Change your Ts function to:
expand(event){
if (event.style.display === "block") {
event.style.display = "none";
} else {
event.style.display = "block";
}
}
And your HTML part should be:
<h2>Accordion</h2>
<button class="accordion" (click) = "expand(panel1)">Section 1</button>
<div #panel1 class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button class="accordion" (click) = "expand(panel2)">Section 2</button>
<div #panel2 class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button class="accordion" (click) = "expand(panel3)">Section 3</button>
<div #panel3 class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
Here a working stackblitz
PS: You can reach the same result in various different ways.
Upvotes: 1