jQuery Accordion (play that tune m8!)

I have found lots of jQuery plugins that offer the solution to the problem of the accordion. But, if I find a problem easy to solve, I prefer to rely on my own design. So, here goes:

Problem

You want to create an accordion, that is, a group a divs (or any other kind of block DOM elements for that matter) that appear when a “button” is pressed.

Analysis

Actually we’re talking about groups of divs (the slaves) and the relevant “buttons” (the masters), that control the slaves, toggle them on and off and concurrently instruct any group of slaves that was visible, to disappear. Check what we are after, here (click the divs).

  1. When you press a master button, it reveals the group of its slaves and concurrently it closes any other potentially open slaves-group.
  2. The color of the pressed button changes (a trick from the previous post) and concurrently the previously pressed master button, return to its original state (that is, its original style).

Before we start coding…

First, the css stylesheet:

.accordion {
	width:150px;
	font-family:Verdana, Geneva, sans-serif;
}

.accordionButton {
	width:150px;
	color:#333;
	line-height:20px;
	background-color:#ccc;
	border-top:1px solid #ddd;
	padding-left:10px;
	cursor:pointer;
	clear:both;
	float:left;
	font-size:12px;
	font-weight:bold;
}

.accordionButton:hover {
	color:#ddd;
	background-color:#555;
	color:#fff;
}

.accordionContent{
	width:150px;
	color:#666;
	display:none;
	line-height:18px;
	padding-left:5px;
	padding-right:3px;
	cursor:pointer;
	border:1px solid #ccc;
	float:left;
	clear:both;
	font-size:11px;
}

.accordionContent div{
	padding: 1px 2px 2px 5px;
	margin: 2px 0px 1px 0px;
}

.accordionContent div:hover{
	color:#000;
	background-color:#DAEAF6;
}

OK, I know, I’m not very good with css and graphics stuff. So what? 😛

Next, the HTML. We wrap everything into a div with the id “accordion”, so to make sure that jQuery will select only the ones we want to affect:

<div class="accordion"> <!--start accordion-->
    <div class="accordionButton" data-tbs-id="f1"> <!--start accordion button-->
    	Button 1
    </div> <!--end accordion button-->
    <div class="accordionContent" > <!--start accordion content-->
        <div>Subject 11</div>
        <div>Subject 12</div>
    </div> <!--end accordion content-->
    <!-- ******************************* -->
	<div class="accordionButton" data-tbs-id="f2"> <!--start accordion button-->
    	Button 2
    </div> <!--end accordion button-->
    <div class="accordionContent" id="f2"> <!--start accordion content-->
        <div>Subject 21</div>
        <div>Subject 22</div>
        <div>Subject 23</div>
        <div>Subject 24</div>
        <div>Subject 25</div>
        <div>Subject 26</div>
    </div> <!--end accordion content-->
	<!-- ******************************* -->
	<div class="accordionButton" data-tbs-id="f3"> <!--start accordion button-->
    	Button 3
    </div> <!--end accordion button-->
    <div class="accordionContent" id="f3"> <!--start accordion content-->
        <div>Subject 31</div>
        <div>Subject 32</div>
        <div>Subject 33</div>
    </div> <!--end accordion content-->
    <!-- ******************************* -->
	<div class="accordionButton" data-tbs-id="f4"> <!--start accordion button-->
    	Button 4
    </div> <!--end accordion button-->
    <div class="accordionContent" id="f4"> <!--start accordion content-->
        <div>Subject 41</div>
        <div>Subject 42</div>
        <div>Subject 43</div>
        <div>Subject 44</div>
        <div>Subject 45</div>
    </div> <!--end accordion content-->
</div> <!--end accordion-->

You haven’t noticed – I’m pretty sure about it! Check the HTML closely:

<div class="accordionButton" data-tbs-id="f1"> <!--start accordion button-->
    	Button 1
    </div> <!--end accordion button-->
    <div class="accordionContent" > <!--start accordion content-->
        <div>Subject 11</div>
        <div>Subject 12</div>
    </div> <!--end accordion content-->

There’s an unusual attribute at the first master div:  data-tbs-id=”f1″. It’s an idea by HTML5, fortunately implemented in all browsers – even MSIE 7.

You can use an attribute of your own, provided you start its name with data-. This is great because it allows us to parameterize our DOM objects and therefore code less (did I mention that I am notoriously lazy?).

So, our first master div holds an attribute (data-tbs-id) with a value “f1”. The idea is that, when clicked upon, jQuery will read the value of [data-tbs-id], get “f1″, and reveal a div with id=”f1”. This will result to a compact, small, yet flexible jOuery code. The same trick is used for all master/slave pairs in our accordion.

On to coding

So, here’s the jQuery (javascript) code:

<script type="text/javascript">

$(
  function() {
      //set a speed for sliding
      var slidingSpeed=300;
      var menus=$('.accordionContent');
      //hide the menus on page load
      //not really needed though, since
      //their css is set to display:none
      menus.hide();
      //bind the event listener on the buttons
      $('.accordionButton').bind('click', onClick);

      function onClick() {
          //reset the background-color to the original at all buttons
          //removing any style added through jQuery
          $('.accordionButton').removeAttr('style');
          //set a style for the pressed button
          $(this).css({"background-color":"#155A6F","color":"#fff"});
          //get the data-tbs-id attr that reflects the id value of the slave div
          var buttonID=$(this).attr('data-tbs-id');
          //select the div that has an id attr equal to the data-tbs-id attr of the master div
          var slave=$("#"+buttonID);
          //close everything that might be opened already
          menus.slideUp(slidingSpeed);
          //toggle the slave div
          if (slave.is(':hidden')) {
              slave.slideDown(slidingSpeed);
          } else {    
              slave.slideUp(slidingSpeed);
              //and reset the css
              $(this).removeAttr('style');
          }    
      }
  }
)

</script>

OK, that is all!What – they don’t disappear, they slide? Well, thank jQuery for that, I just called those slideUp() and slideDown() functions 😉

Any comments are welcomed. Cheers and happy developing (and remember: be lazy! Write your code as compact as you can!)

4 responses to “jQuery Accordion (play that tune m8!)

  1. I trust other visitors find your write-up here as useful as I have. I manage a site by myself and would be very happy for you or the readers on your own site to visit. Please go ahead and search through my website like I have with yours and post a remark or two if you find anything interesting. Many thanks.

  2. Strongly suggest adding a “google+” button for the blog!

  3. This blog is definitely rather handy since I’m at the moment creating an internet floral website – although I am only starting out therefore it’s really fairly small, nothing like this site. Can link to a few of the posts here as they are quite. Thanks much. Zoey Olsen

  4. Hiya. Mainly wanted to post and mention that I valued this article. I’ll be bookmarking your blogging site and looking to see if you post any new ones. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *