Man playing accordion

Making accordions

By Dave

No, not those kinds of accordions...

If you take a look at our FAQ page you'll see the questions and answers expand and collapse along with bringing the set into view.

The HTML markup from Drupal is a little more detailed since we are using the Paragraphs module to create these items, but if you inspect the browser and match it to the code examples below, you'll see how simple this can be.

The HTML Markup

<div class="qa-accordions">
    <div class="field--name-field-question">
        Here is the first question
    </div>

    <div class="field--name-field-answer">
        Here is the answer to the first question
    </div>

    <div class="field--name-field-question">
        Here is the second question
    </div>

    <div class="field--name-field-answer">
        Here is the answer to the second question
    </div>

    <div class="field--name-field-question">
        Here is the third question
    </div>

    <div class="field--name-field-answer">
        Here is the answer to the third question
    </div>

    <div class="field--name-field-question">
        Here is the fourth question
    </div>

    <div class="field--name-field-answer">
        Here is the answer to the fourth question
    </div>
</div>

The Javascript

There is a function that scrolls the window to the opened answer that is called after the slideUp action. Otherwise, there is some inconsistencies when one closes and another opens.

I like to use the .hasClass(), .addClass(), and .removeClass() functions to help avoid erratic behavior as well as helping me add CSS to the elements. 

paragraph_accordions();
      
function scrollToAnswer() {
  var topMenu = $("#navbar");
  var topMenuHeight = topMenu.outerHeight()+15;
  var href = $('.opened'),
  offsetTop = href === "#" ? 0 : $(href).offset().top-topMenuHeight-75;
  $('html, body').stop().animate({ 
    scrollTop: offsetTop
  }, 600);
}
      
function paragraph_accordions() {
  var answers = $('.field--name-field-answer').hide();
  $('.field--name-field-question').click(function() {
    $this = $(this);
    $target =  $this.next();
    if($target.hasClass('active')){
      $target.removeClass('active').slideUp();
      $target.prev().removeClass('opened');
    }else{
      answers.prev().removeClass('opened');
      $target.prev().addClass('opened');
      answers.removeClass('active').slideUp(200, scrollToAnswer);
      $target.addClass('active').slideDown();
      $target.prev().addClass('opened');         
    }          
  });
}