Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to open/close all panels at once? #34

Open
bendur opened this issue Nov 15, 2018 · 1 comment
Open

Is there a way to open/close all panels at once? #34

bendur opened this issue Nov 15, 2018 · 1 comment

Comments

@bendur
Copy link

bendur commented Nov 15, 2018

It would be nice to have an open/close all method to act on everything in the accordion at once.

@LordPachelbel
Copy link

I wrote some code to do this a while back. You can see a working example at https://ssbhibbing.com/faq.html

HTML

<div class="js-accordion">

  <!-- add this button to the accordion parent/wrapper element -->
  <button type="button" class="expand-collapse" aria-pressed="false">
    <span class="expand">Expand all</span>
    <span class="collapse">Collapse all</span>
  </button>

  <div class="js-accordion__panel">
    <h2 class="js-accordion__header">First tab</h2>
    <p>here is the content of the 1st tab</p>   
 </div>

  // and so on …

</div>

jQuery

$('.expand-collapse').click(function(e) {
  e.preventDefault();

  // toggle this button's ARIA attribute and a status variable we'll use to only expand and collapse stuff that isn't already expanded or collapsed
  var expandedStateToggle = 'false';
  if($(this).attr('aria-pressed') === 'false') {  // button is in the "off" state, so we're going to expand the accordions
    $(this).attr('aria-pressed', 'true');
    expandedStateToggle = 'false';
  } else {                    // button is in the "on" state, so we're going to collapse the accordions
    $(this).attr('aria-pressed', 'false');
    expandedStateToggle = 'true';
  }

  // set up an event handler that will return focus to the Expand/Collapse button after we expand/collapse all of the accordion panels (because the accordion plugin leaves the focus on whichever accordion heading button was clicked, and we're about to click all of them at once)
  // the .one() function is not a misspelled .on() function -- .one() fires only once
  // (code based on http://blog.teamtreehouse.com/using-jquery-to-detect-when-css3-animations-and-transitions-end)
  $(this)
    .siblings('.js-accordion__panel')
    .one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function() {
    // NOTE: inside this event handler, $(this) refers to the panel element[s] that fired this event, so we have to use e.target to refer to the Expand/Collapse button

    //console.log('transitions are done');

    e.target.focus(); // return the focus to the Expand/Collapse button
    });

  // trigger the accordion heading buttons' click events to expand/collapse their associated panels, but only the ones that aren't already affected
  $(this).siblings('.js-accordion__header[aria-expanded="' + expandedStateToggle + '"]').click();

  // scroll the page back to Expand/Collapse button
  $([document.documentElement, document.body]).animate({
    scrollTop: $(this).offset().top - 15
  }, 500);
});

Notes

Multiple Buttons Per Set of Accordions

The code is written with the assumption that there will be only one expand/collapse button within the .js-accordion parent/wrapper. If you want to have two or more buttons, e.g. one at the top of the accordions and one at the bottom, then the code will need to be changed to keep buttons' states in sync. The way it's currently written, clicking the top button will expand all of the accordions, and the bottom button will still say Expand All, and if you click that second button nothing will happen except the page will scroll a bit and the text will change to say Collapse All, and then a second click on that button will collapse all of the accordions, but the top button will still say Collapse All … and I'm sure you understand the problem.

Multiple Sets of Accordions

However, the above code can handle the situation where there are multiple .js-accordion sections on the page, because it's targeting sibling elements of the button to expand/collapse.

Minor Simplification

The part of the code that handles the ARIA attributes could perhaps be simplified by using https://github.com/marcus-herrmann/toggleAria but I haven't gotten around to that yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants