What I am trying to do:
I am trying to have collapsible accordion style items on a page which will expand and collapse on a click event. They will expand when a certain class is added collapsible-panel--expanded
.
How I am trying to achieve it:
On each of the items I have set a click event like so:
<div (click)="toggleClass()" [class.collapsible-panel--expanded]="expanded" class="collapsible-panel" *ngFor="let category of categories">
....
</div>
<div (click)="toggleClass()" [class.collapsible-panel--expanded]="expanded" class="collapsible-panel" *ngFor="let category of categories">
....
</div>
and in the function toggleClass()
I have the following:
expanded = false;
toggleClass() {
this.expanded = !this.expanded;
console.log(this.expanded)
}
The issue im facing:
When I have multiple of this on the same page and I click one, they all seem to expand.
I cannot seen to get one to expand.
Edit:
The amount of collapsible links will be dynamic and will change as they are generated and pulled from the database. It could be one link today but 30 tomorrow etc... so having set variable names like expanded 1
or expanded 2
will not be viable
Edit 2:
Ok, so the full code for the click handler is like so:
toggleClass(event) {
event.stopPropagation();
const className = 'collapsible-panel--expanded';
if (event.target.classList.contains(className)) {
event.target.classList.remove(className);
console.log("contains class, remove it")
} else {
event.target.classList.add(className);
console.log("Does not contain class, add it")
}
}
and the code in the HTML is like so:
<div (click)="toggleClass($event)" class="collapsible-panel" *ngFor="let category of categories" >
<h3 class="collapsible-panel__title">{{ category }}</h3>
<ul class="button-list button-list--small collapsible-panel__content">
<div *ngFor="let resource of resources | resInCat : category">
<a href="{{ resource.fields.resource.fields.file.url }}" target="_blank" class="button-list__inner no-decoration doc"><span class="underline display-block margin-bottom">{{ resource.fields.title }}</span><span class="secondary" *ngIf="resource.fields.description display-block">{{ resource.fields.description }}</span></a>
</div>
</ul>
</div>
What I am trying to do:
I am trying to have collapsible accordion style items on a page which will expand and collapse on a click event. They will expand when a certain class is added collapsible-panel--expanded
.
How I am trying to achieve it:
On each of the items I have set a click event like so:
<div (click)="toggleClass()" [class.collapsible-panel--expanded]="expanded" class="collapsible-panel" *ngFor="let category of categories">
....
</div>
<div (click)="toggleClass()" [class.collapsible-panel--expanded]="expanded" class="collapsible-panel" *ngFor="let category of categories">
....
</div>
and in the function toggleClass()
I have the following:
expanded = false;
toggleClass() {
this.expanded = !this.expanded;
console.log(this.expanded)
}
The issue im facing:
When I have multiple of this on the same page and I click one, they all seem to expand.
I cannot seen to get one to expand.
Edit:
The amount of collapsible links will be dynamic and will change as they are generated and pulled from the database. It could be one link today but 30 tomorrow etc... so having set variable names like expanded 1
or expanded 2
will not be viable
Edit 2:
Ok, so the full code for the click handler is like so:
toggleClass(event) {
event.stopPropagation();
const className = 'collapsible-panel--expanded';
if (event.target.classList.contains(className)) {
event.target.classList.remove(className);
console.log("contains class, remove it")
} else {
event.target.classList.add(className);
console.log("Does not contain class, add it")
}
}
and the code in the HTML is like so:
<div (click)="toggleClass($event)" class="collapsible-panel" *ngFor="let category of categories" >
<h3 class="collapsible-panel__title">{{ category }}</h3>
<ul class="button-list button-list--small collapsible-panel__content">
<div *ngFor="let resource of resources | resInCat : category">
<a href="{{ resource.fields.resource.fields.file.url }}" target="_blank" class="button-list__inner no-decoration doc"><span class="underline display-block margin-bottom">{{ resource.fields.title }}</span><span class="secondary" *ngIf="resource.fields.description display-block">{{ resource.fields.description }}</span></a>
</div>
</ul>
</div>
Share
Improve this question
edited Jun 20, 2020 at 9:12
CommunityBot
11 silver badge
asked Jul 4, 2019 at 13:42
modusTollensmodusTollens
41711 silver badges26 bronze badges
5 Answers
Reset to default 2you could apply your class through javascript
<div (click)="handleClick($event)">
some content
</div>
then your handler
handleClick(event) {
const className = 'collapsible-panel--expanded';
if (event.target.classList.contains(className)) {
event.target.classList.remove(className);
} else {
event.target.classList.add(className);
}
}
In plain html and js it could be done like this
function handleClick(event) {
const className = 'collapsible-panel--expanded';
if (event.target.classList.contains(className)) {
event.target.classList.remove(className);
} else {
event.target.classList.add(className);
}
console.log(event.target.classList.value);
}
<div onclick="handleClick(event)">
some content
</div>
Try to pass unique Id. (little modification)Ex: -
in ponent.ts file:
selectedFeature: any;
categories:any[] = [
{
id: "collapseOne",
heading_id: "headingOne",
},
{
id: "collapseTwo",
heading_id: "headingTwo",
},
{
id: "collapseThree",
heading_id: "headingThree",
}
];
toggleClass(category) {
this.selectedFeature = category;
};
ngOnInit() {
this.selectedFeature = categories[0]
}
in html:-
<div class="collapsible-panel" *ngFor="let category of categories">
<!-- here you can check the condition and use it:-
ex:
<h4 class="heading" [ngClass]="{'active': selectedFeature.id==category.id}" (click)="toggleClass(category)">
<p class="your choice" *ngIf="selectedFeature.id==category.id" innerHtml={{category.heading}}></p>
enter code here
-->
.....
</div>
Try maintaining an array of expanded items.
expanded = []; // take array of boolean
toggleClass(id: number) {
this.expanded[i] = !this.expanded[i];
console.log(this.expanded[i]);
}
Your solution will be the usage of template local variables:
see this: https://stackoverflow./a/38582320/3634274
You are using the same property expanded
to toggle for all the divs, so when you set to true for one div, it sets it true for all the divs.
Try setting different properties like this:
<div (click)="toggleClass("1")" [class.collapsible-panel--expanded]="expanded1" class="collapsible-panel" *ngFor="let category of categories">
....
</div>
<div (click)="toggleClass("2")" [class.collapsible-panel--expanded]="expanded2" class="collapsible-panel" *ngFor="let category of categories">
....
</div>
TS:
expanded1 = false;
expanded2 = false;
toggleClass(number:any) {
this["expanded" + number] = !this["expanded" + number];
console.log(this["expanded" + number])
}