Accordions are commonly used graphical control element. The Yahoo Design Pattern Library has a good explanation on the purpose of accordions, as well as recommendations on their usage.

Accordions are usually used when you have limited space and a long list of related items. Seriously, the Yahoo Design Pattern Library is a valuable reference for all designers. I recommend you bookmark it.

There are a number of Drupal modules that help implement accordions (just google drupal accordion), but they didn’t really fit my particular use-case, so I did my accordions differently. This method was a little complicated and required some jQuery, but fit my use-case well.

Create the Accordion content type

Required modules

  1. Install the required modules.
drush dl field_collection entity -y
  1. Enable the required modules.
drush en field_collection entity -y
  1. Go to admin/structure/types/add and create a new content type, called Accordion.
  2. Add a new field of type Field collection and set Widget to Embedded.You should also remove the default Body field as it won’t be used. Create content type
  3. Set Number of values to Unlimited, because you want to be able to create as many accordion sections as you need. Accordion field settings
  4. Go to admin/structure/field-collections and you should see your newly created field. Create field collection field
  5. Click on manage fields and add the fields you require. I only needed a title and body field. Create accordion fields
  6. Click on manage fields and add the fie
  7. Click on Manage display and hide the labels for both fields. You probably should do the same for the Accordion content type. Hide labels
  8. Optional steps: To setup display for the new content type You can choose to use the default Drupal markup to write your accordion. But I find it neater to tweak the markup via Display Suite first. You don’t have to do this if you don’t want to. Instructions here.

Writing the accordion functionality

Note: I have tweaked my markup as per step 9 above, you may have to adjust your selectors accordingly.

There are a couple of recommendations from the Yahoo Design Pattern Library on accordion presentation, like highlighting the current panel and having the most important panel open by default. I just chose to open the first panel by default.

  1. The accordion functionality requires use of basic jQuery. There are a number of ways to add Javascript to your site. I suggest reading this article by Kirill Cebotari to familiarise yourself with all of them. I’m using the second method, including it in the .info file of my theme.
  2. If you don’t have one already, create a js folder in your theme folder, and create a file called script.js in this new folder.
YOUR_THEME/
|-- _css/                    
|-- img/                
|-- js/             
|   |-- script.js  <-- This is where you'll write your code
|-- layouts/                           
|-- logo.png
|-- YOUR_THEME.info
|-- screenshot.png
|-- template.php
`-- templates/
  1. There are some best practices when using Javascript in Drupal, and I strongly recommend everyone to read the documentation. As a general tip, wrap your code in a closure.
 (function ($) {
  $(document).ready(function() {
    // Place jQuery code here
  });
})(jQuery);
  1. Display only the first accordion item on load.
 $('.field-collection-item-field-accordion-content').first().addClass('active');
$('.field-collection-item-field-accordion-content:not(.active)').find('.field-name-field-accordion-body').hide();
  1. Toggle the accordion item body when clicking on the accordion item title.
 $('.field-name-field-accordion-title').click(function(e) {
  e.preventDefault(); // prevent the default action
  e.stopPropagation(); // stop the click from bubbling
  if(!$(this).parent().hasClass('active')) {
    $('.field-collection-item-field-accordion-content').removeClass('active');
    $(this).parent().addClass('active');
    $('.field-collection-item-field-accordion-content').find('.field-name-field-accordion-body').slideUp();
    $(this).next().slideDown();
  }
});

Styling the accordion

The field collection module comes with some default styles that you may wish to override. The module’s CSS file, field_collection.theme.css is in the root of the field_collection folder.

My preferred method requires a module called Magic. It’s one of my favourite modules. You’ll see why once you visit the project page. Magic provides a simple way to remove exclude stylesheets from core and contrib modules. You can also use the hook_css_alter() function to exclude stylesheets, but unless you need to exclude stylesheets from libraries, Magic works brilliantly.

Even when making changes to only one or two selectors, I still prefer to exclude the original stylesheet, then copy the required styles into my theme. I have a thing against repeating selectors to override them. Anyway, style your accordion any way you like. I chose to add an active class to the active accordion item for easier styling.

Styling accordion

Using the accordion with panels

I’m assuming a level of familiarity with using Panels to display content.

  1. Navigate to the Content section of your panel, and click the gear icon on the top left corner to add content. Add panel content
  2. Click on Existing node and enter the NID of the required accordion. Set Build mode to Full content, unless you have a specific view mode for how the accordion should be displayed. Configure node
  3. You should see the title of your node in the layout. Remember to click Update and save. Panel layout

Wrapping things up

This is just one opinionated method of creating an accordion in Drupal. There are lots of other ways to do it, as with everything else in Drupal. I tend to use Panels quite a bit, so I felt this was a pretty Panels-friendly implementation. Another plus is that accordion content can be easily edited by content editors. Hopefully this can provide some inspiration for alternative ways of presenting content in Drupal.