I am trying to create an accordion element that can be used throughout my website. I've managed to get the logic working, sort off... I will select any of the accordions to open and effectively add a class called 'show', however it only works for the first accordion in the parent container holding each accordion element.
And sometimes it opens all of them at once, I want it to have to functionality of the user being able open and close any of the accordions displayed on the page.
(function ($) {
$(".accord").on("click", function (e) {
console.log(this);
$(".accordian-content").toggleClass("show");
});
})(jQuery);
.accord {
background-color: $primary;
color: #111;
cursor: pointer;
padding: 10px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
.accordian-content {
display: none;
}
.accordian-content.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<ul>
<li>
<button >
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div >
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
<li>
<button >
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div >
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
<li>
<button >
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div >
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
</ul>
CodePudding user response:
Your line $(".accordian-content").toggleClass("show");
searches the entire DOM-Tree for all matching elements that have the class '.accordian-content', and toggling the class show
for all those elements.
As your content is always a child of the .accord
element, you can use $(this)
in the click callback to recieve the clicked element. With this, we can then use .find(SELECTOR)
to search the childs for a matching element, in this case .accordian-content
. This will result in the expected element to show.
(function ($) {
$(".accord").on("click", function (e) {
// Changed this Line to find the Accordian-content thats a child of the clicked 'accord'-button
$(this).find('.accordian-content').toggleClass("show");
});
})(jQuery);
.accord {
background-color: $primary;
color: #111;
cursor: pointer;
padding: 10px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
.accordian-content {
display: none;
}
.accordian-content.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<ul>
<li>
<button >
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div >
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
<li>
<button >
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div >
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
<li>
<button >
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div >
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
</ul>
CodePudding user response:
There may be a more efficient method, but I've always found that using unique identifiers to pick up which item has been clicked and apply that ID to the accordian template works best.
I've added some ID's to your text, and changed the javascript slightly to apply the number from the clicked div to the accordian content control.
The added benefit of the unique id method is that if you wanted to open the page and target a specific accordian to open on load, it can be done via the ID, whereas it gets a little more complicated without an ID. That may or may not be something you need to accomplish.
(function ($) {
$(".accord").on("click", function (e) {
let accordian = this.id.replace('accord', 'accordian-content')
$('#' accordian).toggleClass("show");
});
})(jQuery);
.accord {
background-color: $primary;
color: #111;
cursor: pointer;
padding: 10px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
.accordian-content {
display: none;
}
.accordian-content.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<ul>
<li>
<button id="accord1">
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div id="accordian-content1">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
<li>
<button id="accord2">
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div id="accordian-content2">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
<li>
<button id="accord3">
<div >
<div ><?php echo $title; ?></div>
<span > </span>
</div>
<div id="accordian-content3">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
</div>
</button>
</li>
</ul>