Reputation: 59
I have spent roughly an hour looking through stack-overflow answers looking for a solution to my problem. I have been unsuccessful in my attempts so now I will ask showing exactly the code I am working with. The Code is originally from w3schools.
Due to the amount of data that is going to be displayed in each section, it only makes sense to close them after the user is done reading other wise yup could be scrolling for a while.
Any help is appreciated.
EDIT: tl:dr I want to make it so only one of the accordions is active at a time and hide the content of the rest.
Styling
<style>
.fom {
position: relative;
z-index: 1;
max-width: 700px;
background: #fff;
margin: 0 auto 100px;
padding: 45px;
text-align: center;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
background-image: url('pelican.jpg');
}
button.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
border-bottom: 2px solid #fff;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
button.accordion:after {
content: '\02795'; /* Unicode character for "plus" sign (+) */
font-size: 5px;
color: #777;
float: right;
margin-left: 5px;
}
button.accordion.active:after {
content: "\2796"; /* Unicode character for "minus" sign (-) */
}
div.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
</style>
HTML
<div class="fom">
<h2>Police SOP's </h2>
<p>These SOP's will be updated frequently so check them often</p>
<button class="accordion">Section 1</button>
<div class="panel">
<p><?php echo$row['loadout']; ?></p>
</div>
<button class="accordion">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">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>
Script
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + 'px';
}
}
}
</script>
The styling is wrapped in a head tag, and all the main html and script is wrapped in the body tag
Upvotes: 0
Views: 2354
Reputation: 1
A slightly modified version of the code previously posted: You can close all buttons if you click on one AND it can close the clicked button/accordion again:
var acc = document.getElementsByClassName('accordion');
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener('click', function() {
this.classList.toggle('active');
var panel = this.nextElementSibling;
if (panel.style.display === 'block') {
panel.style.display = 'none';
} else {
panel.style.display = 'block';
for(let j=0;j<acc.length;j++){
if(this.classList != acc[j].classList){
acc[j].classList.remove('active');
acc[j].nextElementSibling.style.display = 'none';
}
}
}
});
}
Upvotes: 0
Reputation: 453
Here is the working example with minor changes in your code:
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
for (let i = 0; i < acc.length; i++) {
acc[i].classList.remove('active');
acc[i].style.maxHeight = null;
acc[i].nextElementSibling.style.maxHeight = null;
}
this.style.maxHeight = this.scrollHeight+'px';
this.classList.add('active');
var panel = this.nextElementSibling;
panel.style.maxHeight = panel.scrollHeight + 'px'
}
}
.fom {
position: relative;
z-index: 1;
max-width: 700px;
background: #fff;
margin: 0 auto 100px;
padding: 45px;
text-align: center;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
background-image: url('pelican.jpg');
}
button.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
border-bottom: 2px solid #fff;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
button.accordion.active,
button.accordion:hover {
background-color: #ddd;
}
button.accordion:after {
content: '\02795';
/* Unicode character for "plus" sign (+) */
font-size: 5px;
color: #777;
float: right;
margin-left: 5px;
}
button.accordion.active:after {
content: "\2796";
/* Unicode character for "minus" sign (-) */
}
div.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<div class="fom">
<h2>Police SOP's </h2>
<p>These SOP's will be updated frequently so check them often</p>
<button class="accordion">Section 1</button>
<div class="panel">
<p>
<?php echo$row['loadout']; ?>
</p>
</div>
<button class="accordion">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">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>
NOTE: the same thing would be much easier if you use jQuery. Give it a shot.
Update: @Craig Mason solution on the comment has an handled closing the active accordion. https://jsfiddle.net/at9wjbde/1/ is the fiddle that he mentioned
Upvotes: 2
Reputation: 168
You mentioned your interest in a jquery solution so here it is:
$(".accordion").click(function(){
$(".accordion").removeClass("active");
$(".accordion").next().css('max-height', '0');
$(this).addClass("active");
$(this).next().css('max-height', $(this).next().prop('scrollHeight'));
});
See it at work in this fiddle
Upvotes: 0
Reputation: 5059
So, if I understand correctly, you want the content below every accordion button to be hidden unless the button is pushed. One way you could do this is to add an active
class to the currently clicked button, like so:
acc[i].onclick = function() {
var accs = document.querySelectorAll('.accordion');
for (let i = 0; i < accs.length; ii++) {
accs[i].classList.remove('active');
}
acc[i].classList.add('active');
}
And then in your CSS, you could automatically hide all the content after non-active buttons like so:
.accordion:not(.active) + .panel {
display: none;
}
+
is used to select the element that directly follows the preceding selector.
Upvotes: 0