0

I have an accordion FAQ section on my site. It currently expands when you click the headline, but I'd like it to collapse when you click the headline again. How do I make it collapse when I click an expanded section? I included a snippet of the code i'm using from the tutorial, hopefully that works.

EDITED: Fixed the snippet, it should expand now, I want to know how to make it collapse when I click the title again on an expanded section.

HTML:

   $(document).ready(function(){
  var animTime = 300,
      clickPolice = false;
  
  $(document).on('touchstart click', '.acc-btn', function(){
    if(!clickPolice){
       clickPolice = true;
      
      var currIndex = $(this).index('.acc-btn'),
          targetHeight = $('.acc-content-inner').eq(currIndex).outerHeight();
   
      $('.acc-btn h1').removeClass('selected');
      $(this).find('h1').addClass('selected');
      
      $('.acc-content').stop().animate({ height: 0 }, animTime);
      $('.acc-content').eq(currIndex).stop().animate({ height: targetHeight }, animTime);

      setTimeout(function(){ clickPolice = false; }, animTime);
    }
    
  });
  
});
* { 
  -webkit-box-sizing:border-box;
  -moz-box-sizing:border-box;
  -o-box-sizing:border-box;
  box-sizing:border-box;
}

html, body {
  background:#FFFFFF;
}

.acc-container {
  width:90%;
  margin:30px auto 0 auto;
  -webkit-border-radius:8px;
  -moz-border-radius:8px;
  -o-border-radius:8px;
  border-radius:8px;
  overflow:hidden;
}

.acc-btn { 
  width:100%;
  margin:0 auto;
  padding:20px 25px;
  cursor:pointer;
  background:#34495E;
  border-bottom:1px solid #2C3E50;
}

.acc-content {
  height:0px;
  width:100%;
  margin:0 auto;
  overflow:hidden;
  background:#2C3E50;
}

.acc-content-inner {
  padding:30px;
}

.open {
  height: auto;
}

h1 {
  font:700 20px/26px 'Lato', sans-serif;
  color:#ffffff;
}

p { 
  font:400 16px/24px 'Lato', sans-serif;
  color:#798795;
}

.selected {
  color:#1ABC9C;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="acc-container">
<div class="acc-btn"><h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Proin sodales, nibh eget sollicitudin consectetur, elit nisl malesuada urna, ac fermentum turpis urna id augue. Vestibulum eu consectetur nunc. In ultricies erat nisl, a fringilla risus viverra sed. Phasellus vel sodales elit. Morbi nec adipiscing dolor. Vivamus volutpat vitae velit vel sagittis.</p>
  </div>
</div>

<div class="acc-btn"><h1>Curabitur et diam vitae dolor accumsan aliquet et in massa.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Nulla facilisi. Proin sodales dolor in odio lacinia, ut venenatis massa lobortis. Morbi congue dignissim nisi gravida consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sed egestas diam. Nunc ut mauris tempus, rutrum massa vel, pellentesque velit. Nullam eget diam sit amet diam pretium scelerisque. Nunc sed odio nisi. Nunc odio est, rhoncus vitae risus a, sagittis ultrices mauris. Fusce scelerisque posuere pulvinar.</p>
  </div>
</div>

<div class="acc-btn"><h1>Proin faucibus sem sed dapibus dapibus.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Praesent ultricies risus quis magna convallis, ac condimentum tellus laoreet. Donec dictum velit enim, nec hendrerit leo mattis sit amet.</p>
  </div>
</div>

<div class="acc-btn"><h1>Praesent lobortis urna non est faucibus, vestibulum mattis diam sollicitudin.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Fusce eget ultricies ante. In augue urna, rhoncus ac tellus non, porta malesuada magna. Nulla tincidunt orci in metus rhoncus, at malesuada quam varius. Mauris sed tincidunt massa, ut cursus magna. Pellentesque cursus sapien turpis, id blandit magna tempus at.</p>
  </div>
</div>
</div>
aynber
  • 22,380
  • 8
  • 50
  • 63
Jen
  • 156
  • 1
  • 3
  • 17

3 Answers3

1

Basically, just check if your heading is already expanded and if so, remove the selected class and change the targetHeight to 0.

$(document).ready(function() {
  var animTime = 300,
    clickPolice = false;

  $(document).on('touchstart click', '.acc-btn', function() {
    if (!clickPolice) {
      clickPolice = true;

      var currIndex = $(this).index('.acc-btn'),
          isExpanded = $(this).find('h1').hasClass('selected'),
          targetHeight = isExpanded ? 0 : $('.acc-content-inner').eq(currIndex).outerHeight();

      $('.acc-btn h1').removeClass('selected');
      $(this).find('h1').toggleClass('selected', !isExpanded);

      $('.acc-content').stop().animate({
        height: 0
      }, animTime);
      $('.acc-content').eq(currIndex).stop().animate({
        height: targetHeight
      }, animTime);

      setTimeout(function() {
        clickPolice = false;
      }, animTime);
    }

  });

});
* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
}
html,
body {
  background: #FFFFFF;
}
.acc-container {
  width: 90%;
  margin: 30px auto 0 auto;
  -webkit-border-radius: 8px;
  -moz-border-radius: 8px;
  -o-border-radius: 8px;
  border-radius: 8px;
  overflow: hidden;
}
.acc-btn {
  width: 100%;
  margin: 0 auto;
  padding: 20px 25px;
  cursor: pointer;
  background: #34495E;
  border-bottom: 1px solid #2C3E50;
}
.acc-content {
  height: 0px;
  width: 100%;
  margin: 0 auto;
  overflow: hidden;
  background: #2C3E50;
}
.acc-content-inner {
  padding: 30px;
}
.open {
  height: auto;
}
h1 {
  font: 700 20px/26px'Lato', sans-serif;
  color: #ffffff;
}
p {
  font: 400 16px/24px'Lato', sans-serif;
  color: #798795;
}
.selected {
  color: #1ABC9C;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="acc-container">
  <div class="acc-btn">
    <h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h1>
  </div>
  <div class="acc-content">
    <div class="acc-content-inner">
      <p>Proin sodales, nibh eget sollicitudin consectetur, elit nisl malesuada urna, ac fermentum turpis urna id augue. Vestibulum eu consectetur nunc. In ultricies erat nisl, a fringilla risus viverra sed. Phasellus vel sodales elit. Morbi nec adipiscing
        dolor. Vivamus volutpat vitae velit vel sagittis.</p>
    </div>
  </div>

  <div class="acc-btn">
    <h1>Curabitur et diam vitae dolor accumsan aliquet et in massa.</h1>
  </div>
  <div class="acc-content">
    <div class="acc-content-inner">
      <p>Nulla facilisi. Proin sodales dolor in odio lacinia, ut venenatis massa lobortis. Morbi congue dignissim nisi gravida consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sed egestas diam. Nunc ut mauris tempus, rutrum massa
        vel, pellentesque velit. Nullam eget diam sit amet diam pretium scelerisque. Nunc sed odio nisi. Nunc odio est, rhoncus vitae risus a, sagittis ultrices mauris. Fusce scelerisque posuere pulvinar.</p>
    </div>
  </div>

  <div class="acc-btn">
    <h1>Proin faucibus sem sed dapibus dapibus.</h1>
  </div>
  <div class="acc-content">
    <div class="acc-content-inner">
      <p>Praesent ultricies risus quis magna convallis, ac condimentum tellus laoreet. Donec dictum velit enim, nec hendrerit leo mattis sit amet.</p>
    </div>
  </div>

  <div class="acc-btn">
    <h1>Praesent lobortis urna non est faucibus, vestibulum mattis diam sollicitudin.</h1>
  </div>
  <div class="acc-content">
    <div class="acc-content-inner">
      <p>Fusce eget ultricies ante. In augue urna, rhoncus ac tellus non, porta malesuada magna. Nulla tincidunt orci in metus rhoncus, at malesuada quam varius. Mauris sed tincidunt massa, ut cursus magna. Pellentesque cursus sapien turpis, id blandit magna
        tempus at.</p>
    </div>
  </div>
</div>
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
1

You just need to check whether the clicked section is the expanded one and do your animation in reverse and remove your 'selected' class from it. I will add though, this is far better handled by simply using CSS3 for the animation and sizing and JS just to add and remove classes. Check this link out.

How can I transition height: 0; to height: auto; using CSS?

   $(document).ready(function(){
  var animTime = 300,
      clickPolice = false;
  
  $(document).on('touchstart click', '.acc-btn', function(){
    if(!clickPolice){
       clickPolice = true;
      
      var currIndex = $(this).index('.acc-btn'),
          targetHeight = $('.acc-content-inner').eq(currIndex).outerHeight();
   
      if($(this).find('h1').hasClass('selected')){
        $('.acc-btn h1').removeClass('selected');
        $('.acc-content').stop().animate({ height: targetHeight }, animTime);
        $('.acc-content').eq(currIndex).stop().animate({ height: 0 }, animTime);

        setTimeout(function(){ clickPolice = false; }, animTime);  
      }else{
        $('.acc-btn h1').removeClass('selected');
        $(this).find('h1').addClass('selected');
        $('.acc-content').stop().animate({ height: 0 }, animTime);
        $('.acc-content').eq(currIndex).stop().animate({ height: targetHeight }, animTime);

        setTimeout(function(){ clickPolice = false; }, animTime);  
      }
      
     
    }
    
  });
  
});
* { 
  -webkit-box-sizing:border-box;
  -moz-box-sizing:border-box;
  -o-box-sizing:border-box;
  box-sizing:border-box;
}

html, body {
  background:#FFFFFF;
}

.acc-container {
  width:90%;
  margin:30px auto 0 auto;
  -webkit-border-radius:8px;
  -moz-border-radius:8px;
  -o-border-radius:8px;
  border-radius:8px;
  overflow:hidden;
}

.acc-btn { 
  width:100%;
  margin:0 auto;
  padding:20px 25px;
  cursor:pointer;
  background:#34495E;
  border-bottom:1px solid #2C3E50;
}

.acc-content {
  height:0px;
  width:100%;
  margin:0 auto;
  overflow:hidden;
  background:#2C3E50;
}

.acc-content-inner {
  padding:30px;
}

.open {
  height: auto;
}

h1 {
  font:700 20px/26px 'Lato', sans-serif;
  color:#ffffff;
}

p { 
  font:400 16px/24px 'Lato', sans-serif;
  color:#798795;
}

.selected {
  color:#1ABC9C;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="acc-container">
<div class="acc-btn"><h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Proin sodales, nibh eget sollicitudin consectetur, elit nisl malesuada urna, ac fermentum turpis urna id augue. Vestibulum eu consectetur nunc. In ultricies erat nisl, a fringilla risus viverra sed. Phasellus vel sodales elit. Morbi nec adipiscing dolor. Vivamus volutpat vitae velit vel sagittis.</p>
  </div>
</div>

<div class="acc-btn"><h1>Curabitur et diam vitae dolor accumsan aliquet et in massa.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Nulla facilisi. Proin sodales dolor in odio lacinia, ut venenatis massa lobortis. Morbi congue dignissim nisi gravida consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sed egestas diam. Nunc ut mauris tempus, rutrum massa vel, pellentesque velit. Nullam eget diam sit amet diam pretium scelerisque. Nunc sed odio nisi. Nunc odio est, rhoncus vitae risus a, sagittis ultrices mauris. Fusce scelerisque posuere pulvinar.</p>
  </div>
</div>

<div class="acc-btn"><h1>Proin faucibus sem sed dapibus dapibus.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Praesent ultricies risus quis magna convallis, ac condimentum tellus laoreet. Donec dictum velit enim, nec hendrerit leo mattis sit amet.</p>
  </div>
</div>

<div class="acc-btn"><h1>Praesent lobortis urna non est faucibus, vestibulum mattis diam sollicitudin.</h1></div>
<div class="acc-content">
  <div class="acc-content-inner">
    <p>Fusce eget ultricies ante. In augue urna, rhoncus ac tellus non, porta malesuada magna. Nulla tincidunt orci in metus rhoncus, at malesuada quam varius. Mauris sed tincidunt massa, ut cursus magna. Pellentesque cursus sapien turpis, id blandit magna tempus at.</p>
  </div>
</div>
</div>
Community
  • 1
  • 1
1

This seems like it's coming from an old tutorial. It's way too much code for an accordion!

You need two things: some switching and some CSS.

The switching:

$(document).ready(function(){

  $(document).on('touchstart click', '.acc-btn', function(){

    $(this).toggleClass('selected');

  });

});

The CSS:

.acc-content {
  height:0px;
}
.selected + .acc-content {
    height: auto;
}
.selected h1 {
  color:#1ABC9C;
}

If you want it so that only one pane is visible at a time...

$(document).ready(function(){

  $(document).on('touchstart click', '.acc-btn', function(){

    // Next line 'closes' everything by removing the class selected from everything
    // except the one we just clicked, otherwise it wouldn't toggle—
    // the class would get removed and then added back two lines down.
    $('.acc-container').find('.selected').not(this).removeClass('selected');

    $(this).toggleClass('selected');

  });

});

If you want to have them animate on open and close, you can do it with CSS:

.acc-content {
  max-height:0px; //since we can't animate to height: auto;
  -webkit-transition: all 0.35s ease-in-out 0s;
  -moz-transition: all 0.35s ease-in-out 0s;
  transition: all 0.35s ease-in-out 0s;
}
.selected + .acc-content {
    max-height: 400px; // or whatever you think you'd need as a max
}

Here's a fiddle: http://jsfiddle.net/0sfn0gqk/

Will
  • 4,075
  • 1
  • 17
  • 28