I have done slideup and slidedown div using jquery. Here i have three boxes.Once we click the head, the content will open. then click another head, that content will open and old content close. But i cont close same content. All time any one of the content is open. I need once we click head that content need to close.
$(document).ready(function() {
$("p").click(function() {
$this = $(this);
var parent = $this.closest('.acc');
$("p").removeClass('open');
$this.addClass('open');
$('.acc-body').slideUp();
parent.find('.acc-body').slideDown();
});
});
body {
padding: 0;
margin: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
.acc {
padding: 0px;
margin: 0;
}
.acc-head {
padding: 15px;
margin: 0;
background: #ccc;
}
.acc-head.open {
background: #000;
color: #fff;
}
.acc-body {
border: 1px solid #ccc;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="max-width: 500px;">
<div class="acc">
<p class="acc-head">
head
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
<div class="acc">
<p class="acc-head">
head
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
<div class="acc">
<p class="acc-head">
head
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
</div>
To fix this use slideToggle() on .acc-body, and use not() to exclude it from the slideUp(). The same pattern works for adding and removing the open class on the p elements.
$(document).ready(function() {
$("p").click(function() {
var $this = $(this);
var $target = $this.next();
$("p").not($this).removeClass('open');
$this.toggleClass('open');
$('.acc-body').not($target).slideUp();
$target.slideToggle();
});
});
body {
padding: 0;
margin: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
.acc {
padding: 0px;
margin: 0;
}
.acc-head {
padding: 15px;
margin: 0;
background: #ccc;
}
.acc-head.open {
background: #000;
color: #fff;
}
.acc-body {
border: 1px solid #ccc;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="max-width: 500px;">
<div class="acc">
<p class="acc-head">
head
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
<div class="acc">
<p class="acc-head">
head
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
<div class="acc">
<p class="acc-head">
head
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
</div>
Just look first for the head owning the class open.
Fixed it like this
$(document).ready(function(){
$("p").click(function(){
$this = $(this);
if($this.hasClass('open')){
$this.removeClass('open');
$this.siblings('.acc-body').slideUp();
}else{
var parent = $this.closest('.acc');
$("p").removeClass('open');
$this.addClass('open');
$('.acc-body').slideUp();
parent.find('.acc-body').slideDown();
}
});
});
Hope it helps! :)
Here is the Solution for You!!!
Using Jquery hasClass() function we can solve this problem. First we need to check clicked element has class or not. if has 'open' class then do the slideup function, else do the slideDown function.and remove all open class for other 'p'.
we solve this function using slideToggle() also.
$(document).ready(function(){
$("p").click(function(){
$this = $(this);
if($this.hasClass('open')){
$this.removeClass('open');
$('.acc-body').slideUp();
}else{
var parent = $this.closest('.acc');
$('p').removeClass('open');
$this.addClass('open')
$('.acc-body').slideUp();
parent.find('.acc-body').slideDown();
};
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
body{
padding: 0;
margin: 0;
}
*, *:before, *:after{
box-sizing: border-box;
}
.acc{
padding: 0px;
margin: 0;
}
.acc-head{
padding: 15px;
margin: 0;
background: #ccc;
}
.acc-head.open{
background: #000;
color: #fff;
}
.acc-body{
border: 1px solid #ccc;
display: none;
}
</style>
<div style="max-width: 500px;">
<div class="acc">
<p class="acc-head">
head1
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
<div class="acc">
<p class="acc-head">
head2
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
<div class="acc">
<p class="acc-head">
head3
</p>
<div class="acc-body">
Learn by examples! At W3Schools you will find a lot of jQuery examples to edit and test yourself.
</div>
</div>
Use Simple Accordion:
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";
}
});
}
.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;
}
<div class="accordion">Section 1</div>
<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>
<div class="accordion">Section 2</div>
<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>
<div class="accordion">Section 3</div>
<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>
Related
I'm using the code for an animated collapsible on this link:
https://www.w3schools.com/howto/howto_js_collapsible.asp
HTML:
<button type="button" class="collapsible">Open Collapsible</button>
<div class="content">
<p>Lorem ipsum...</p>
</div>
CSS:
/* Style the button that is used to open and close the collapsible content
*/
.collapsible {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
.active, .collapsible:hover {
background-color: #ccc;
}
/* Style the collapsible content. Note: hidden by default */
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
JS:
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
I want to implement another collapsible button inside the first collapsible drop down. As of right now my nested button does nothing when I click the + icon other than change to a -. Here is my html:
<button type="button" class="collapsible">Options:</button>
<div class="content">
<button class="collapsible">Check</button>
<div id="content">
TEST
</div>
</div>
CSS and JS are the same as in the link.
I created first loop to calculate all class content heights to be able to use this number as max-height to the main container. you can use css display block and none instead, but i do this to create animation.
var allHeights = 0;
var contents = document.getElementsByClassName("content");
var j;
for (j = 0; j < contents.length; j++) {
var h = document.getElementsByClassName("content")[j].scrollHeight;
allHeights += h;
}
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight == allHeights + "px"){
content.style.maxHeight = "0px";
} else {
content.style.maxHeight = allHeights + "px";
}
});
}
.collapsible {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active, .collapsible:hover {
background-color: #ccc;
}
.content {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.collapsible:after {
content: '\02795'; /* Unicode character for "plus" sign (+) */
font-size: 13px;
color: white;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2796"; /* Unicode character for "minus" sign (-) */
}
<button type="button" class="collapsible">First Collapsible</button>
<div class="content">
<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>
<button type="button" class="collapsible">Second Collapsible</button>
<div class="content">
<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 type="button" class="collapsible">Third Collapsible</button>
<div class="content">
<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>
</div>
You made a mistake in nested content div element. Instead of id="content" there should be class="content" to have it working correctly. Take a look at the snippet below.
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
/* Style the button that is used to open and close the collapsible content */
.collapsible {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
.active, .collapsible:hover {
background-color: #ccc;
}
/* Style the collapsible content. Note: hidden by default */
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
<button type="button" class="collapsible">Options:</button>
<div class="content">
<button type="button" class="collapsible">Check</button>
<div class="content">
TEST
</div>
</div>
I am trying to have an Expand All button on my website. I have two levels of expanding and collapsing links and would like to have an option to Expand All when someone wants to see everything without clicking. I think I know what I need to do - loop through all accordions and set them to display. Could you give me some tips.
This is the code. Please help.
function ExpandAll() {
var acc = document.getElementsByClassName("accordionMain");
var i;
for (i = 0; i < acc.length; i++) {
var panel = this.Children
panel.style.display = "block";
}
}
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.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
}
}
button.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;
}
button.accordion.active,
button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
<!DOCTYPE html>
<head>
</head>
<body>
<h2>Accordion</h2>
<button onclick="ExpandAll();">Expand All</button>
<button class="accordion">Section 2</button>
<div class="panel">
<button class="accordion">Section 1</button>
<div class="panel">
<p>
content
</p>
</div>
</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>
</body>
</html>
You can ask document to give you all .panel elements to show as below
function ExpandAll() {
var pannels = document.querySelectorAll('.panel');
for (panel of pannels)
panel.style.display = "block";
}
button.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;
}
button.accordion.active,
button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
<h2>Accordion</h2>
<button onclick="ExpandAll();">Expand All</button>
<button class="accordion">Section 2</button>
<div class="panel">
<button class="accordion">Section 1</button>
<div class="panel">
<p>
content
</p>
</div>
</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>
ExpandAll() should be expandAll() (May not matter but it bothered me)
Make sure to change it for the onclick for your button as well.
<button onclick="expandAll();">Expand All</button>
Then change your code to not look for acordionMain but for the panel. The getElementsByClassName(X) returns and array. So you can just iterate through that array and set the style to display: "block" via JS. The code is below.
<script>
function expandAll ()
{
var elements = document.getElementsByClassName("panel");
for (var i = 0; i < elements.length; i++) {
var panel = elements[i];
panel.style["display"] = "block";
}
}
</script>
EDIT:
Here is a Fiddle: https://jsfiddle.net/CraftingGamerTom/f6y96c2e/
I have a nested lists:
<ol id="warningType">
<li id="Other">Other
<ul class="toggle_menu">
<li>Create() is conflict with Delete() when you are creating.</li>
<li>View() must have the same parent with Delete().</li>
</ul>
</li>
<li id="Input">Input
<ul class="toggle_menu">
<li>Get() can be the input of Create().</li>
</ul>
</li>
<li id="Exception">Exception
<ul class="toggle_menu">
<li>If you forget to delete all elements, Post() will throw Error A.</li>
<li>View() will throw IllegalException.</li>
</ul>
</li>
</ol>
I would like to click "Other""Input" and "Exception" to get or hide the nested list. Any help with it would be appreciated.
It is called Accordion, and actually it's not neccessary to insert tag into li tag. Here is example.
Your html:
<ul class="accordion">
<li>
<h3>Section 1</h3>
<p>Text 1 of this section Lorem ipsum.</p>
</li>
<li>
<h3>Section 2</h3>
<p>Text 1 of this section Lorem ipsum.</p>
</li>
<li>
<h3>Section 3</h3>
<p>Text 1 of this section Lorem ipsum.</p>
</li>
</ul>
Css:
* {
box-sizing: border-box;
}
body {
width: 100%;
margin: 0 auto;
background: #009788;
}
ul.accordion {
list-style-type: none;
width: 40%;
padding: 0px;
margin: 5% auto 0 auto;;
}
.accordion > li {
width: 100%;
display: block;
}
.accordion li > h3 {
background: #f5f5f5;
text-align: center;
margin: 0;
border-bottom: 2px solid #d6d6d6;
cursor: pointer;
padding: 10px 0px;
font-size: 24px;
}
.accordion li > h3:hover {
background: #ccc;
}
.accordion li > h3:after {
content: "+";
float: right;
margin-right: 2%;
}
.accordion li > p {
display: none;
background: #fff;
padding: 10px;
border-bottom: 2px solid #d6d6d6;
font-size: 20px;
margin: 0;
}
.accordion li h3.active:after {
content: "-";
float: right;
margin-right: 2%;
}
and Jquery code:
$(document).ready(function() {
$('h3').click(function(){
$(this).toggleClass('active');
$(this).siblings().not(':animated').slideToggle();
});
});
Are you looking for something like this accordion :
https://www.w3schools.com/howto/howto_js_accordion.asp
<!DOCTYPE html>
<html>
<head>
<style>
button.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;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
</style>
</head>
<body>
<h2>Animated Accordion</h2>
<p>Click on the buttons to open the collapsible content.</p>
<button class="accordion">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">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>
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>
</body>
</html>
You can achieve this via accordion
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">
Other</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse in">
<div class="panel-body">
<ul class="toggle_menu">
<li>Create() is conflict with Delete() when you are creating.</li>
<li>View() must have the same parent with Delete().</li>
</ul></div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse2">
Input</a>
</h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body"><ul class="toggle_menu">
<li>Get() can be the input of Create().</li>
</ul></div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse3">
Exception</a>
</h4>
</div>
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body"><ul class="toggle_menu">
<li>If you forget to delete all elements, Post() will throw Error A.</li>
<li>View() will throw IllegalException.</li>
</ul></div>
</div>
</div>
</div>
This is using bootstrap's collapsible accordion
I am new to this forum. I hope I am not breaking any rules. I am trying to include accordion within accordion and after a lot of research found this solution on your website. I thought I would start with this and modify what I need to make it work for my specific situation, but this solution does not seem to work for me and looks like it worked for the person asking. What am I doing wrong here? Please help.
<!DOCTYPE html>
<head>
<style>
button.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;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
</style>
<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.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
}
}
</script>
</head>
<body>
<h2>Accordion</h2>
<button class="accordion">Section 2</button>
<div class="panel">
<button class="accordion">Section 1</button>
<div class="panel">
<p>
content
</p>
</div>
</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>
</body>
</html>
Include the <script> after the accordeon
<!DOCTYPE html>
<head>
<style>
button.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;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
</style>
</head>
<body>
<h2>Accordion</h2>
<button class="accordion">Section 2</button>
<div class="panel">
<button class="accordion">Section 1</button>
<div class="panel">
<p>content</p>
</div>
</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>
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.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
}
}
</script>
</body>
</html>
Or else wrap your script in:
document.addEventListener("DOMContentLoaded", function(event) {
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.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
}
}
});
Otherwise, when it gets to the part:
var acc = document.getElementsByClassName("accordion");
it cannot get the element by class name that does not yet exist, and acc will be an empty array.
Here you go with a solution using jQuery https://jsfiddle.net/apjnf4xf/1/
$('.accordion').click(function(){
$('.panel').slideUp();
$(this).next('div.panel').slideDown();
});
button.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;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Accordion</h2>
<button class="accordion">Section 2</button>
<div class="panel">
<p>content</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>
Hope this will help you.
You are running the script before the browser even knows that your document has elements with class accordion. Run the script after the window has loaded or as the other answers here suggest, include the script after the accordion HTML markup.
<!DOCTYPE html>
<head>
<style>
button.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;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
</style>
<script>
window.addEventListener('load',setUpAccordion);
function setUpAccordion(){
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.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
}
}
}
</script>
</head>
<body>
<h2>Accordion</h2>
<button class="accordion">Section 2</button>
<div class="panel">
<button class="accordion">Section 1</button>
<div class="panel">
<p>
content
</p>
</div>
</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>
</body>
</html>
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
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
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.
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
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';
}
}
}
});
}