If you see a flash of yellow just below this line, the initial hiding did not occur soon enough:

  • you may see this list
  • flash before it is hidden
  • look carefully

See this page with the flash of initially hidden content

Accordion Madness

A few weeks ago I wrote about two ways we can achieve the "accordion menu" effect, and I promised to describe a third option. Well, this is it, Option 3. But first, here is a list of my other show-hide-toggle entries, as well as Jörn Zaefferer's accordion menu plug-in:

Option 3: Zero or One

Remember from More Showing, More Hiding that we are working with a simple <h3> / <div> structure:

HTML:
  1. <div class="demo-show2">
  2.   <h3>Title 1</h3>
  3.   <div>Lorem...</div>
  4.   <h3>Title 2</h3>
  5.   <div>Ipsum...</div>
  6.   <h3>Title 3</h3>
  7.   <div>Dolor...</div>
  8. </div>

With this option #3, we start with all of the <div>s hidden. If we click on one of the headings, the following <div> will slide down. If we click on the same heading again, that <div> will slide back up. Clicking on on any heading will also hide all of the other <div>s — the ones that don't immediately follow it. Therefore, no more than one <div> can be open a a time.

To achieve this, we start by hiding all of the <div>s inside the first (:eq(0)) <div class="demo-show2">:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show2> div').hide()
  3. });

Then we set up the .click() method for all of the relevant <h3> elements

JavaScript:
  1. $(document).ready(function() {
  2.   [...]
  3.   $('div.demo-show2> h3').click(function() {
  4.     [...]
  5.   });
  6. });

Finally, inside the .click(), we toggle the >div< immediately following the clicked >h3< and hide all the other >div<s that are visible siblings of the toggled one. Here is the complete script:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show2> div').hide()
  3.   $('div.demo-show2> h3').click(function() {
  4.     $(this).next('div').slideToggle('fast')
  5.     .siblings('div:visible').slideUp('fast');
  6.   });
  7. });

Now, on to the show:

Title 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 2

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 3

Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Pretty simple, straightforward effect. Let's jazz it up a bit.

Option 3b: Zero or One, Queued Effects

Here we're going to keep the same rules about having either one or no <div>s visible at a time. But now we're going to queue the effects. In other words, we'll make the visible one slide up before the next one slides down.

The first couple lines of code are the same as those in option 3a:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show2> div').hide()
  3.   $('div.demo-show2> h3').click(function() {
  4.     [...]
  5.   });
  6. });

But now things get a touch more complicated. We're going to set a couple variables—one for the next sibling of the clicked <h3> and one for all siblings of that next one, as long as they are visible <div>s:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show2> div').hide()
  3.   $('div.demo-show2> h3').click(function() {
  4.     var $nextDiv = $(this).next();
  5.     var $visibleSiblings = $nextDiv.siblings('div:visible');
  6.   });
  7. });

So, now that we have the two variables, let's put them to use. We want to slide any visible sibling <div> up first and then toggle the next <div> using .slideToggle(). But we want this queued effect to occur only if there actually is a visible div. So, we'll use an if statement.

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show2> div').hide()
  3.   $('div.demo-show2> h3').click(function() {
  4.     var $nextDiv = $(this).next();
  5.     var $visibleSiblings = $nextDiv.siblings('div:visible');
  6.  
  7.     if ($visibleSiblings.length ) {
  8.       $visibleSiblings.slideUp('fast', function() {
  9.         $nextDiv.slideToggle('fast');
  10.       });
  11.     }
  12.   });
  13. });

The trick here for getting the one effect to occur after the other is to put the .slideToggle() code in the .slideUp() method's callback function.

Now, we just need to add the else condition for those times when there aren't any visible <div>s:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show2> div').hide()
  3.   $('div.demo-show2> h3').click(function() {
  4.     var $nextDiv = $(this).next();
  5.     var $visibleSiblings = $nextDiv.siblings('div:visible');
  6.  
  7.     if ($visibleSiblings.length ) {
  8.       $visibleSiblings.slideUp('fast', function() {
  9.         $nextDiv.slideToggle('fast');
  10.       });
  11.     } else {
  12.        $nextDiv.slideToggle('fast');
  13.     }
  14.   });
  15. });

As you can see, for those cases we use a simple .slideToggle() on the next <div>.

See this code in action below. Enjoy!

Title 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 2

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 3

Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

174 Responses to “Accordion Madness”

  1. Ty

    Finally, the correct functionality required.
    I think I prefer the first non-jazzed up version, the second makes me motion sick, lol.
    Way to go, good work.

    Hint: These div's can contain image buttons not just text, and background colors and borders.'
    Dig into your Css bag-o-tricks for that people, have fun!

  2. Karl

    Yes, thanks for adding that hint, Ty. There are multifarious ways to prettify these menus, for sure.

  3. Luis Martins

    It doesn’t behave quite right on IE7, but excellent work. Thanks.

  4. Karl

    Hi Luis, by not behaving quite right in IE7, I assume you mean that there is a little bump at the end of the slide. I just fixed that by giving the paragraphs inside those <div> elements a style declaration of margin-top: 0. Thanks for the heads-up. Let me know if you see any other issues.

  5. ziggy

    --I think I prefer the first non-jazzed up version, the second makes me motion sick, lol.

    Yeah, me too. Jazzy effects look nice at first but quickly get annoying when you have to use them a lot.

  6. ziggy

    btw, in ie6 it won't open unless you click the text; after one time opening it you can click anywhere on the blocks to activate them.

    opera works but doesn't show the proper "hand" cursor at all.

    I know it's not a plugin, but thought I'd note it as people ARE going to use your code.

  7. Joram Oudenaarde

    Finally a great explanation on those slick movement-options :)
    Thanks a lot for making this, hehe.

    There's only one little question in addition to your tutorial;
    In your tutorial, the text shows up belów the buttons after you press it. Could you tell us how we could make a version where the text shows up abóve the button? So if you press that button, the button will slide down, showing the text that's been hidden "above" it. :)

    Regards,
    Joram

  8. Karl

    @ziggy: I fixed both the IE6 and the Opera issue with a little modification to the CSS. IE6 needs the width to be defined for the h3, and Opera needs the cursor to be defined. here is the relevant CSS:

    .demo-show2 {
      width: 350px;
      margin: 1em .5em;
    }
    .demo-show2 h3 {
      margin: 0;
      padding: 5px;
      width: 338px;
      background: #bfcd93;
      border-top: 1px solid #386785;
      border-bottom: 1px solid #386785;
      cursor: pointer;
    }

    @Joram: You can move the div elements above the h3s in your markup, and then use .prev() instead of .next().

  9. joram oudenaarde

    Very much appreciated :)

    One little question if you don't mind;
    I know that in JavaScript, you can set a fixed speed (don't ask me how though).
    Is it possible to make the animation slower? I see you used 'fast'
    as a tag in JavaScript... is that the speed-indicator?

    Thanks in advance (again) :)

  10. Karl

    Hey Joram, no problem.

    Yeah, I set the animation to "fast" but you can set it to whatever you want, either by using a label ("fast" or "slow" or "normal") or by using a number. Numeric speeds are in milliseconds and don't take quotation marks.

    So, if you wanted the .slideToggle() effect to take a full second, you would do this:
    .slideToggle(1000).

  11. davidbisset.com » Accordion Madness

    [...] Another way to do the “accordion menu” effect using CSS [...]

  12. Joram Oudenaarde

    Thanks again Karl :)

    Time to experiment, hehe.

  13. Chris Ovenden

    IMO the first version of this is exactly how these things should be done: accessible, usable, non-intrusive (and no motion sickness...) Excellent work, Karl!

  14. Yansky

    Hi guys, this isn't a comment on the post as such, but a tutorial suggestion. Could you write a tutorial about the use of "$(this)" within a callback and the right way to use it in different circumstances? I seem to always have trouble with understanding how it works and the proper syntax with which to use it.

    For example, I was recently trying to replace text in an array, and even though I managed to figure it out (with great help from the mailing list), I still don't fully understand "$(this)". :-)

    This was my text replace code BTW:

    $('a > span').contains('index.cfm?a=wiki&tag=').each(function(i){
    var $this = $(this);
    $this.html( $this.html().replace( /index.cfm\?\a\=wiki\&tag\=/gi, "")).css({"border-bottom": "1px dotted #773300", color: "#773300", "text-decoration": "none"}).siblings().hide();
    });

  15. Nicki

    Hi, little question: how can i show the first div visible on startup?

  16. Karl

    Hi Nicki,

    Look at Option 2 in More Showing, More Hiding for an example of making the first div initially visible. If you have any further questions after reading through that one, drop in another comment.

  17. Justin

    Hey, Karl. I love the tutorial. It's really helped me a lot. My issue is that I'm using nested lists to structure my navigation and .siblings obviously won't work for that. Do you have any insight on how I might remedy this issue? I'm new to this so I don't know how to traverse the dom to find the elements I need to hide.

    $(document).ready(function() {
    	$("ul.demo> li> ul").hide();
    	$("ul.demo> li> span").click(function() {
    		$(this).next("ul").slideToggle("fast").siblings("ul.subnav:visible").slideUp("fast");
    	});
    });
    <a href="/ccd/category.do?...">Desktop computers (+)
    			<a href="#">AMD</a>
    			<a href="#">Intel</a>
    	<a href="/ccd/category.do?...">Notebook computers (+)
    			<a href="#">AMD</a>
    			<a href="#">Intel</a>
  18. Justin

    One of the wonderful people in the #jquery irc channel was able to help me with this last night. The answer is...

    $(this).next('ul').slideToggle('fast')
    .parent().siblings('li').find('ul:visible').slideUp('fast');

  19. Karl

    Hey Justin, glad to hear you got help with that. Sorry I couldn't reply to you any sooner. (working on the book.)

  20. api3376

    hi everyone!
    i'd like to use accordion in horizontal mode..
    does anyone know a way to do that??????
    help me ;)
    thanks

  21. charles

    Hi,

    i got a list, each of its items must contain a div. in fact each of my "li class="titre"" tag corresponds to the "h3" tag of the first example and my own divs contained in each li have their proper "contenu_article" class. i'm a beginner at jquery and i'm trying to make this work

    $('div.demo-show2> div').hide();
    $('div.demo-show2> li class="titre"').click(function()
    {
    $(this).next('div').("contenu_article").slideToggle('fast').siblings('div:visible').slideUp('fast');
    });

    but it doesn't. i think that this part : ('div.demo-show2> li class="titre"') is badly written. does anyone can help me please ?

  22. Karl

    Hi Charles,

    I'm not sure exactly what you're trying to show/hide. Still, I see a couple problems with the selector expression you're using. It looks like you're using HTML syntax ( e.g. li class="titre" ) instead of CSS syntax ( e.g. li.titre ). Switching your selectors to CSS syntax will go a long way towards getting your code to work. Also, you can remove the code that is specifically related to my example ( e.g. div.demo-show2 ).

    If I'm understanding you correctly, you might want to try something like this:

    $('li.titre').click(function() {
      $(this).next('div.contenu_article').slideToggle('fast')
        .siblings('div:visible').slideUp('fast');
    });
  23. Brent

    Thanks a lot for your article, this helped me in a jam!

  24. Aaron

    I have a weird question. First let me say this code is great and almost what i am looking for.

    I want to have images that when you mouse over it fades in a div on the right side of it and when mouse over the next one it fades out the previous and fades in the next div.

    I have tried modifying this code but am having no luck.

    Here is example HTML of the layout.


    <table width="100%" border="0" cellspacing="0" cellpadding="0" id="ImageTable">
    <tr>
    <td class="images">
    <A href="#"><IMG src="Image.jpg" border="0"></A>
    <A href="#"><IMG src="Image.jpg" border="0"></A>
    <A href="#"><IMG src="Image.jpg" border="0"></A>
    </td>
    <td class="divs">
    <div>1 This is the box that will be shown and hidden and toggled at your whim.</div>
    <div>2 This is the box that will be shown and hidden and toggled at your whim.</div>
    <div>3 This is the box that will be shown and hidden and toggled at your whim.</div>
    </td>
    </tr>
    </table>

    I am so lost on how to get this to do this and can not tell you how much i would appreciate it if someone could help me out.

    Thanks again for everything and great work!!!

    Aaron

  25. GoodMixer

    I'm having problems getting this to work in ie7. Viewing this example in ie7 works fine. My html is

    <div class="demo-show2">
    <h3>Tell a Friend</h3>
    <div class="form_bg">Lorem ipsum dolor.</div>
    <h3>Subscribe to Newsletter</h3>
    <div class="form_bg">In tincidunt nisi tempus feliss.</div>
    <h3>Title 3</h3>
    <div class="form_bg">In tincidunt nisi tempus felis. Donec aliquam,</div>
    </div>

    and I'm calling 2 .js files in the <head> jquery.js and show_hide.js.

    show_hide.js is the following code

    $(document).ready(function() {
    $('div.demo-show2> div').hide();
    $('div.demo-show2> h3').click(function() {
    var $nextDiv = $(this).next();
    var $visibleSiblings = $nextDiv.siblings('div:visible');
    if ($visibleSiblings.length ) {
    $visibleSiblings.slideUp('fast', function() {
    $nextDiv.slideToggle('fast');
    });
    } else {
    $nextDiv.slideToggle('fast');
    }
    });
    });

    Any help would be great I'm really stumped on this one. Works fine in firefox.....

  26. Karl

    Hi GoodMixer, I pasted your code into another doc and tested it in IE7. Seems to be working fine for me: accordion test. Let me know if it works for you, too.

  27. GoodMixer

    Thanks for looking at that Karl. It seems to work for me when I have the script in the head tag but not when I have it in an external .js file. Is there something I am missing? I don't know. I guess I'll just forget about the external file. Thanks again.

  28. Karl

    Not a problem. I'm not sure why it's not working for you when the code is in an external .js file, though. That shouldn't really have anything to do with it. I've moved my test file's script to an external file, and it's still working. Take another look.

    A couple things to consider: Make sure you are including the jquery.js file before the other one. Also, it wouldn't hurt to double-check the path to the .js file, just in case there was a typo or something. Let me know what you discover!

  29. GoodMixer

    I'm really not getting anywhere with this. I'm running this script on an Expression Engine site and it work great in firefox but ie (6 and 7) it works sometimes and then if you refresh it will just show all 3 boxes with content and nothing clickable. I can't see why it would work sometimes??? Unless EE isn't loading the full script.

    I am running the jquery.js first. You are welcome to have a look if you want to as I'm not getting anywhere with it. http://www.mickykelleher.com/golf/ (The site is a work in progress)

  30. John Williams

    In the first menu "Option 3: Zero or One", how do I make to open the text in a certain title when the page loads? (the text inside Title1 or Title2 or Title3).

    i managed to load it with Title1 opened:

    $(document).ready(function() {
    $('div.demo-show2:eq(0) > div:gt(0)').hide();
    $('div.demo-show2> h3').click(function() {
    $(this).next('div').slideToggle('normal')
    .siblings('div:visible').slideUp('normal');
    });
    });

    or Title1 + Title2 at the same time

    $(document).ready(function() {
    $('div.demo-show2:eq(0) > div:gt(1)').hide();
    $('div.demo-show2> h3').click(function() {
    $(this).next('div').slideToggle('normal')
    .siblings('div:visible').slideUp('normal');
    });
    });

    or Title1+ Title2+Title3 at the same time

    $(document).ready(function() {
    $('div.demo-show2:eq(0) > div:gt(2)').hide();
    $('div.demo-show2> h3').click(function() {
    $(this).next('div').slideToggle('normal')
    .siblings('div:visible').slideUp('normal');
    });
    });

    Thank you.

  31. Vivek

    Hi, as i am viewing the above demos of after a tutorials, they are shuttering in the Firefox 2.0.3
    But when i view the same in IE6.0 it slides beautifully. In FF 2.0.3 it slides after a bit of shutter.

  32. John Williams

    Try removing or diminusing, in the CSS code, the top and bottom padding of demo-show2.div. Include that height in an old html variant (a table with a row of the same hight for example). I hope I understood your question write.

  33. Sérgio Pinto

    Hi Karl.

    First just wanna say thanks for this plugin, it's great.

    Just needed to know if there is any easy way to convert this plugin to an horizontal accordion.

    Thanks in advance.

    Best regards Sérgio pinto

  34. Dena

    Thanks for the clear example!

    Is there an easy way to change the h3 content on toggle? For instance, from "Open" to "Close"?

    Thanks!

  35. layZboy

    I have a question. If i want the section I click on to become the top, how do I do this? I was curious since after i used it and my sections were about 4 paragraphs longer it became annoying to scroll to the correct section each time. I was wondering if there's a way to expand/collapse, as well as scroll to the proper section all at once. Thanks.

  36. mpmchugh

    Hi,

    How would one best go about having the selected header change colors when selected? And then revert when another is selected?

    Thanks.

    -mpm

  37. huphtur

    mpmchugh: maybe look into addClass?

    Karl: Any tips on how to get anchors to work ala how moo.fx does it?

  38. Karl

    Hi huphtur,

    Maybe use this script in conjunction with Interface's .ScrollTo() method in the FX module? Take a look at the FX documentation and see if it'll do what you're shooting for. If not, let me know.

  39. huphtur

    Karl: not sure how Interface's .Scrollto() would help with this. Basically I need to know how I can use the jquery/accordion madness to open an anchor with an id attribute. For instance: Title2, or Title1 (your demo with some added markup). I've been searching jquery docs for anchor and target info, but have been unable to find anything. Maybe I'm looking at the wrong stuff?

  40. Karl

    Oh, sorry huphtur. Totally misread your question. I just took another look at the moo.fx page that you linked to, and, I have to say, I don't get why they're using those anchors in the way that they are. For example, they have <a href="whatsnew">what's new</a>, but they don't have anything on the page with id="whatsnew" or even an old-school anchor like <a name="whatsnew"></a>. It adds the hash to the URL, but since the anchors don't exist on the page, clicking on those headings keeps adding unnecessarily to the history, making for terrible "back button" navigation.

    Anyway, Klaus Hartl's Tabs plugin does a really nice job of using anchors the right way, tracking history so that the back button will actually do something. If you check that one out, I'm sure you'll be able to glean some really useful stuff from it. It's not the straightforward accordion, but it works on the same principle.

    I realize this is the second time I've urged you to take a look at another plugin to find the solution, but I'm really not trying to avoid helping you. Really!

  41. huphtur

    That's indeed what I was looking for. Thanks for the tips!

  42. Justin

    Karl,

    On the apple site they have their own version of what appears to be an accordion type menu. It's on the right and left side when you mouseover. I'm sure you've seen it already.

    My question: Have you been able to mimic this effect with jQuery. On every jQuery accordion i've seen and made, the bottom will always make some sort of bumping motion. Depending on the speed it might be a big bump or a small bump. I've been able to minimize it, but never get rid of it like Apple has. Any ideas? I probably need an entirely different approach.

    link for reference: http://www.apple.com/mac/

  43. Karl

    Hi Justin,
    I'm not seeing the "bumping motion" in the examples above for this blog entry. I might not be understanding what you mean by "bumping," though. One thing you might want to try is setting a height for the containing element like Apple does. That way, everything below it will stay in the same spot even during the sliding animations. Hope that helps point you in the right direction. If this doesn't make sense or doesn't work for you, let me know and I'll try to put up a demo over the weekend.

  44. Justin

    K. Bumping may have been a bad description. It's also more noticeable when you have more than 3 tabs. I will try to describe it better:

    In the last example on this page before these comments, if Title 1 is open and i click Title 2, then title 3 moves up with it. If you set the show and hide to the same speed, then title 3 will just make a small move down and up, a "bump" if you will. You can see it in my example here:

    http://www.robustness.org/dev/jquery/slider/slider-jquery.html
    (it's a small bump on the 4th tab, when you click any of the tabs, just moves down and up really quick)

    On the apple page, if i have the first tab open and mouseover the second tab, the third tab does not move at all. That's the effect i'm looking for. It loosk more solid. I have used javascript to set heights on the container and the tabs themselves, and this stops the tabs from interfering with the rest of the page, however the tabs themselves make these jumps.

    I hope this clarifies it a bit.

  45. Karl

    Ah! I definitely see what you mean now. I don't know what could be causing this, but if you post the question to the jQuery Google Group, maybe someone who is more familiar with the fx.js component of the jQuery source code could provide a solution. Otherwise, this could be a bug that should be logged n Trac on the jquery.com. But posting the question to the Google Group is definitely the first step. Make sure you provide the URL, too. That was really helpful for seeing what the problem is.

  46. Bobby Digital

    I know someone else asked this but I can't find the solution anywhere.

    How can I have the class of an h3 change when you click on it, and then revert to normal when you either

    1. click on it again, or
    2. click on a different h3?

    I tried the following:

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

    inside the conditional statement of your "//queued showing and hiding" example, but I quickly discovered that I have no clue what I am doing.The class changes but stays that way when I click on other h3's

    Any ideas?

  47. Bobby Digital

    Woops, I posted the wrong code. This is as far as I can get here:

    $(document).ready(function() {
    $('div.demo-show2:eq(0) > div').hide();
    $('div.demo-show2:eq(0) > h3').click(function() {
    $(this).next('div').slideToggle('fast')
    .siblings('div:visible').slideUp('fast');
    $(this).toggleClass('active')
    .siblings('h3').toggleClass('normal');
    });
    });

  48. Bobby Digital

    Wow, I actually figured it out! Jquery is easy!!

    $(document).ready(function() {
    $('div.demo-show2:eq(0) > div').hide();
    $('div.demo-show2:eq(0) > h3').click(function() {
    $(this).next('div').slideToggle('fast')
    .siblings('div:visible').slideUp('fast');
    $(this).addClass('arrow-down')
    .siblings('h3').removeClass('arrow-down');
    });
    });

  49. Karl

    Hey Bobby, Congratulations! I'm glad I didn't see your posts until now. It's so much more satisfying to figure these things out on your own, isn't it? Don't hesitate to ask for help, though, if you run into any further snags.

  50. matthew smith

    I'm trying to accomplish something similar, but haven't figured out how to add Bobby's idead to my set up.

    I'm curently using this html:


    Services

    For the web

    Web Design
    Squared Eye is known for our attention to detail, our love of all things easy to use, and the way we can take your needs and find a web solution for them.

    Web Development
    If you need your website to live and breath — to do more than just be an online brochure — Squared Eye can take your site to the next level, integrating anything from e-commerce to video and a myriad of helpful technologies in-between.

    and this JS:


    $(document).ready(function() {
    $('ul.accordion> li> p').hide();
    $('ul.accordion> li> h4').click(function() {
    var $nextDiv = $(this).next();
    var $visibleSiblings = $nextDiv.siblings('p:visible');
    if ($visibleSiblings.length ) {
    $visibleSiblings.slideUp('fast', function() {
    $nextDiv.slideToggle('fast');
    });
    } else {
    $nextDiv.slideToggle('fast');
    }
    });
    });

    I've tried adding bobby's code in there in various places, but can't figure out the right solution.
    the page I'm working on is here

  51. Karl

    Hi Matthew,
    Would you mind posting that link to your page again? For some reason it has no href.

  52. matthew smith

    Karl,
    Man, what a numskull. Sorry, too many things at once :) Here is the link. Thanks :)

  53. Karl

    Hi Matthew, no worries.

    It looks like you're sliding down the <p>s just fine; but getting others to slide back up seems to be the problem. Is that right?

    The cause of the problem is that you're selecting for visible siblings, but since those other <p>s are contained within separate <li>s, they aren't siblings.

    Try replacing this line:
    var $visibleSiblings = $nextDiv.siblings('p:visible');
    with this:
    var $visibleSiblings = $(this).parent().siblings().find('p:visible');

    Let me know how that goes.

  54. matthew smith

    Karl,
    Thanks, that did the trick. To understand it correctly the $(this).parent().siblings() is because of the nested unordered list?

    On another note, in accordance with the comments above about adding or removing a class based upon whether the paragraph is open or closed.

    I had thought I might have it by adding $(this).parent().addClass('arrow-down') thinking that was targetting the nested list element, but it appears I was wrong.

  55. Karl

    Hi Matt,
    My pleasure. Doesn't matter if the unordered list is nested, just that the h4 within each li has only one sibling -- a p. So, you need to go up from the clicked h4 to its li, then select all of that li's sibling lis, and within those find all ps and slide them up.

    About the addClass(), what you have should work. I peeked at your code and didn't see you doing that. If you wanna shoot the whole script to me so I can take a look at it, feel free to send it through the contact form.

  56. bs

    i want to add dynamic div. how can i give dynamic div name inside $('div.demo-show2> div').

  57. Caleb

    Hi Karl,

    I'm trying to build upon the examples you have set. How can i create a 'close' option within each div?

    Here's whats i'm working on so far.

    thanks! your help would be greatly appreciated.

    caleb

  58. Justin

    Caleb,

    Place a class "close" on the div containing the close text. Then place this in your javascript after your other click function.

    $('.close').click(function() {

    $(this).parent().slideUp('slow');

    });

  59. Caleb

    thanks justin! :)

  60. Mitchell Waite

    Is there anyway to prevent the menu height from jumping around. In other words can the height be fixed and the menus open and close to fill it?

    Thanks

    Mitch

  61. Karl

    Hi Mitch,
    Sure. I think all you need to do is set the height of the menu's containing element in your stylesheet. If that doesn't make sense, let me know and I'll explain further.

  62. Jing Jok

    does anyone know how this side scrolling effect is achieved?
    http://www.hotel-oxford.ro/

    It uses moo.tools.js and a clever http:// call in a file called core.js and another named core.ajax.js . The scrolling effect seems to be buried in the last third of the page:
    ... "&contact=1&ajax=1" load_content('contact_div', SITE_ROOT, poststr)...

    I can get everything to work except for the sliding action of each "page" even though all the code is on the index page itself. Just looking for a tip on how the core.js interacts with the info on the index page.

    I just thought this would be a good question for the Jscript / JAVAscript gurus.

  63. Big Brad

    I'm having no issues with the working of the accordion ... it's brilliant infact.

    What I was wondering was the following:

    i managed to set image backgrounds for the h3's in the css for a:link as well as a:hover - and they work fine.

    what i cannot wrap my head around is how I would be able to create a "active" state with yet another img background.

    any takers?

  64. Karl

    Hi Brad,
    I'd use a single background image and shift either its x or y position. For example, if your h3s are 24px tall, you could do something like this:

    h3 a {
      background: url(my-image.jpg) no-repeat 0 0;
     display: block;
    }
    h3 a:hover {
      background-position: 0 -24px;
    }
    h3 a:active {
      background-position:0 -48px;
    }

    You'll probably need to use return false; in your script so it doesn't fire the default click event.

  65. caleb

    is it possible to click and open all ? if so, how can i do that?

    thanks :)

  66. Karl

    Hi Caleb, inside the .click(), just do $(this).siblings('div').slideDown();

  67. caleb

    hi karl,

    sorry but i'm not very good at javascript.

    what's the div variable?

    heres an example of what i got.

    http://oonagi.org/test/

    my js file is here.

    thanks so much. :)

  68. Karl

    Hi Caleb, I'm guessing now that you want a separate element that, when clicked, will open all of the hidden items, but I'm not sure because I can't see anything on that page that you might want to bind to that behavior.

    The first thing I'd do is change all those span elements to divs, because they contain paragraphs. spans should only contain inline elements.

    Then, try something like this (inside your document.ready):

    $('someElement').click(function() {
      $('div.show-hide > div').slideToggle();
    });

    You'll need to change 'someElement' to something that relates to an element on your page. This will slide (up or down) all divs that are direct children of <div class="show-hide">

    btw, in my previous example, div isn't a variable; it's an element.

    Hope that helps

  69. eric maguire

    Hey all
    Great tutorial...new to jquery but am loving it switch from mootools and not looking back. i am having one problem though. i have multiple instances of a div with the content i want to hide at first and multiple instances of a click handle. the problem is with only showing one div at a time... the way it works now is that the user can click multiple show/hide links and the previous one will still show itself until you toggle it. here is the html:

    
    <div class="moduleDescription">
      <ul>
        <li>
          <!-- start description -->
          <a href="http://www.tmz.com/2007/09/04/glaad-accepts-jerrys-mea-culpa/">
            GLAAD Accepts Jerry's Mea Culpa </a><br />
          - <span class="date">4 Sep 2007 | </span>
          <!-- end description -->
        </li>
      </ul>
      <h6>Show/Hide</h6>
      <div>
        <p>
        <p>Filed under: <a href="http://www.tmz.com/category/tv/" rel="tag">TV</a></p>
        <a href="http://www.tmz.com">TMZ.com</a>:  After Jerry Lewis apologized
          ... <a href="http://www.tmz.com/2007/09/04/glaad-accepts-jerrys-mea-culpa/">Read more</a><br/>
        <br/>
        </p>
      </div>
    </div>
    <!-- end item -->
    <div class="moduleDescription">
    <ul>
      <li>
        <!-- start description -->
        <a href="http://www.tmz.com/2007/09/04/lewis-takes-foot-out-of-mouth-issues-statement/">
         Lewis Takes Foot Out of Mouth, Issues Statement </a><br />
        - <span class="date">4 Sep 2007 | </span>
        <!-- end description -->
      </li>
    </ul>
    <h6>Show/Hide</h6>
    <div>
      <p>
      <p>Filed under: <a href="http://www.tmz.com/category/tv/" rel="tag">TV</a>,
       <a href="http://www.tmz.com/category/wacky-and-weird/">Wacky and Weird</a></p>
      <a href="http://www.tmz.com">TMZ.com</a>:  Alleged comedian Jerry Lewis has issued...
       ... <a href="http://www.tmz.com/2007/09/04/...">Read more</a><br/>
      <br/>
      </p>
    </div>
    

    and here is the js

    
    <script>
    $(document).ready(function() {
      $('div.moduleDescription> div').hide();
      $('div.moduleDescription> h6').click(function() {
    	var $nextDiv = $(this).next();
    	var $visibleSiblings = $nextDiv.siblings('div:visible');
    	if ($visibleSiblings.length ) {
    	  $visibleSiblings.slideUp('fast', function() {
    		$nextDiv.slideToggle('fast');
    	  });
    	} else {
    	   $nextDiv.slideToggle('fast');
    	}
      });
    });
    </script>
    

    the test url is here:
    http://celebrityfed.com/v-1-3c.php

    any help would be awesome...thank you!

  70. Karl

    It looks like your problem is with the $visibleSiblings variable. You have each h6/div pair wrapped in its own <div.moduleDescription>.

    You should be able to get this working by just changing the one line. Insead of this . . .

    var $visibleSiblings = $nextDiv.siblings('div:visible');

    try this . . .

    var $visibleSiblings = $(this).parent().siblings().children('div:visible');

  71. eric maguire

    karl

    thank you very much it seemed to work.....but it kinda caused an adverse effect. for some reason it is controlling the "rate this feed" div now too. trying to figure it out....thanks a lot for the help. here is what ive got so far http://celebrityfed.com/v-1-3c.php

    thanks again for your help!!!!!

  72. caleb

    Hi Karl,

    Thank for your help..

    I've tried the suggestion you provided and it works, but theres this bug issue when say i click expand all, and then i click collapse 1 item, everything collapses and it starts going up and down.

    I've also doing this.

    $('.ExpandAll').click(function() {
    $('div.show-hide > div').slideDown();
    });

    $('.CollapseAll').click(function() {
    $('div.show-hide > div').slideUp();
    });

    But it still has the same bug. Isit possible to be fixed?

    test here

  73. Karl

    Eric, I guess I had missed that in the markup. Oops. You'll need to specify the class in your siblings method then:

    var $visibleSiblings = $(this).parent().siblings('div.moduleDescription').children('div:visible');

    That should do it.

  74. Karl

    Caleb, I've been shooting blind with my suggestions for you so far. It really helps me to be able to see a live demo page of some sort. Could you post a link so that I can help you work it out?

  75. eric maguire

    karl

    worked like a charm...thanks so much! keep up the good work.

    -eric

  76. Simon

    Hi Karl,

    What version is the jquery.js file are you using in this examples?

    Im having a problem with getting the effects to run smooth in IE 6.

    When using the latest version available at jQuery.com I get a bump at the end of the animation, but it works fine in your examples. So I tried using your jquery.js file which solved my problem, but instead something else stopped working as intended: when you click an already expanded item I dont want anything to happen. For some reason when using your version of the jquery.js the menu closes and expands if you click an expanded link.

    Here are two links to demonstrate what I mean:

    The latest version available from jQuery.com. Expanded menu does not re-expand when clicked but theres a bump at the end of the animation in IE 6:
    my jquery.js file

    Your file. Works fine in IE 6, but an already expanded menu closes and exapands when clicked:
    your jquery.js-file

    The relevant code is the first line in the function: $("dd").click(function()

    the line:

    $("dt:visible").not($(this).prev()).slideUp("normal")
      .css("background","url('./images/content_b.png') no-repeat scroll left top");

    My intention with the code is to say slideup all the the visible dt-elements except the clicked element.

    Am I correct assuming that .not($(this).prev()) is not handled as it should be when Im using your version of the jquery.js?

    Hope you understand my question, any help appreciated.

    Thanks for taking your time!
    Simon

  77. Rodrigo

    How do I do to make a sublink appear selected (CSS) when I click it? It should apen another page in another frame... but the menu shoud be selected after it. I already tryed the `p` parameter in the URL but didn´ work. Please I need help.. Thanks in advance.

  78. Karl

    Rodrigo, inside your click handler, add a line like this:
    $(this).addClass('selected');

    Then style that class in your stylesheet.

    Hope that helps.

  79. Victor

    Hi Karl,

    Please, how can I make visible my hidden element (with an id="xyz") when it matches current page pathname - (.../page.htm#xyz)? (I want to open and scroll to it from a link on the same or another page).

    Thank you in advance for any hint.

  80. caleb

    would it be possible to change the heading on click?
    say for example, on the corner of the header i have 'expand', once i click on it, the contents display while at the same time, the word 'expand' changes to contract. im guessing the 'expand' could be just an image instead if that would make things easier?

  81. Karl

    Hi Caleb,

    Yes, this is possible. Right after the line that reads var $nextDiv = $(this).next();, you can do something like this:

    if ($nextDiv.is(':visible') ) {
     $(this).text('expand');
    } else {
     $(this).text('contract');
    }
  82. caleb

    hi Karl,

    thanks for that. i've included an example of what i'm working on to give you a better understanding what i'm trying to achieve.

    please see example here and screenshot here.

    how can i have the words on the right corner to change accordingly?

    thanks for taking your time! :P

  83. Karl

    Hi Caleb,
    I don't see the text in your example page (though I do see it in the screenshot). The principle will be the same as I described in comment 83, but the selector expression will just be a little different. For example, you could put a <span> inside the <h4> with the "expand" text in it, right before the other text and float it right. Then you can just change the text on clicking the <h4> the same way I showed in comment 83, except that, instead of this:

    if ($nextDiv.is(':visible') ) {
     $(this).text('expand');
    } else {
     $(this).text('contract');
    }

    you would do this:

    if ($nextDiv.is(':visible') ) {
     $('span', this).text('expand');
    } else {
     $('span', this).text('contract');
    }
  84. Scott Lenger

    For a horizontal accordion you'll want to use the animate effect. Replace the code between the function brackets with something like this:

    
    $(this).next('div').animate({
       width:"100%"}, 250)
    .siblings('div').animate({
       width:"0"}, 250)
    
  85. Karl

    Thanks for that, Scott! Keep in mind that this will only work with jQuery 1.2 and up.

  86. Sean

    Hi Karl,

    I'm at a total loss here. My keyboard is getting covered with the hair I've been ripping from my skull trying to get this to work. Tried to modify each of your show/hide related examples but to no avail.

    My setup is here: http://www.appelmanncreative.com/testarea/test2.html
    the css and jquery files are there on the server with it

    Basically I want the subnav to show/hide the content layers accordian style like Option 3a on this page, with the first (about us section) showing on page load.

    Can it be done?

  87. Karl

    Hi Sean,
    I don't have time to write the whole script out for you, but I'm guessing that the problem you're having involves identifying the correct div to show and hide when you click on one of those links. Try pasting this into your script file. Then you can go through and replace the logic of what gets shown and hidden when by looking at the example script in this entry:

      $(document).ready(function() {
        $('#subNav > li').each(function(index) {
          $(this).click(function() {
            $('#loadContent > div:eq(' + index + ')').slideToggle();
            return false;
          });
        });
      });
  88. Sean

    Hi Karl,
    Thanks for that, but I still didn't get it to work.
    I'm not really clear on where exactly to put the logic of what gets shown and hidden when.

    thanks for taking your time!

  89. Karl

    okay, Sean, take a look here:

    http://test.learningjquery.com/test2.html

    The script is in the <head>.

  90. Sean

    that's beautiful!!
    thanks again for your help!

  91. Karl

    Not a problem. Glad I could help.

  92. reza

    Hi,

    How to add a fading effect during the slide motion?

    Thanx a lot for help!

  93. Karl

    Hi reza,
    For that, you'll need to use the .animate() method. For example, option 3a above would look like this:

    $(document).ready(function() {
      $('div.demo-show2> div').hide();
      $('div.demo-show2> h3').click(function() {
    	$(this).next('div').animate({height: 'toggle', opacity: 'toggle'})
    	.siblings('div:visible').animate({height: 'hide', opacity: 'hide'});
      });
    });
  94. Beau

    Great Tutorial!
    I am new to Java, what would be the path in the HTML for an external .js scriprt?

  95. Rick R

    Just wanted to say thanks for this tutorial. Nicely done and extremely helpful.

  96. Dustin W. Gold

    Thank you very much for your hard work. I am primarily a graphic designer and have been getting into web in the last year, but have been using a programmer. I know HTML and CSS, but have been trying to learn some javascript and this is the best source that I have found.

    Thank you very much.

  97. Dustin W. Gold

    I am new at this so please be patient, but is there a way to keep the menu open when I click on links. For example, if I open "Video Solutions" and I click on a link the accordion closes. I can separate the menu using php, but it still will continue to close because it is reloading the menu. Any advise?

    http://www.e6lu2eiubr.web.aplus.net/index.php?page=about_us

        $(document).ready(function() {
            $('div.demo-show> div:gt(0)').hide();
            $('div.demo-show> h3,h4').click(function() {
              $(this).next('div').slideDown('fast')
              .siblings('div:visible').slideUp('fast');
            });
          });
  98. Karl

    Hi Dustin,

    Maybe something like this:

    $(document).ready(function() {
      $('div.demo-show > div').hide();
      var hrefParts = location.href.split('=');
      var thisPage = hrefParts[hrefParts.length-1];
      $('div.demo-show div:has(a[href*=' + thisPage + '])').show();
      $('div.demo-show > h3,h4').click(function() {
        $(this).next('div').slideDown('fast')
        .siblings('div:visible').slideUp('fast');
      });
    });
  99. Dustin W. Gold

    You are a GOD! Thank you very much for your assistance. It works like a charm. I can't thank you enough. I played with it for hours and couldn't find a solution that worked.

  100. Karl

    Dustin,
    LOL. I wouldn't go that far! Still, I'm very happy that it's working for you. Enjoy!

  101. Dustin W. Gold

    Do you have any tutorials on rollover/click text swaps with jquery?

  102. Karl

    Hi Dustin,
    I'm not sure what you're referring to when you write "rollover/click text swaps." It could mean any of a number of things. Can you point me to any examples of this sort of thing on another site that I can look at? Maybe then I can write up a tutorial on how to do it.

  103. Dustin W. Gold

    I'm sorry, I just mean a rollover swap. I rollover a thumbnail image and text would change in a div box. When I click on the thumbnail the text would show in the box.

  104. Mark

    Great stuff! I'm desperate for a slight amend! I would like to have a different CSS style for the title you are currently looking at, ie if I'm looking at "Title 2" contents I want the Title 2 heading to have a different text colour.

    I've managed to add a class quite easily but I can't find the place to remove it! I've tried adding a toggle function but it's not happening! Can anyone help?

    This is as far as I've got:

    $(document).ready(function() {
    	$('body#faq #content p').hide();
    	$('body#faq #content h4').click(function() {
    		$(this).addClass("on");
    		var $nextDiv = $(this).next();
    		var $visibleSiblings = $nextDiv.siblings('p:visible');
    		if ($visibleSiblings.length ) {
    			$visibleSiblings.slideUp('fast', function() {
    			$nextDiv.slideToggle('fast');
    		});
    	  } else {
    		 $nextDiv.slideToggle('fast');
    	  }
    	});
    });
    

  105. Karl

    Hi Mark, Right before the line with $(this).addClass("on");, try this:

    $('#faq #content h4').removeClass('on');

    There are a couple ways to optimize your code, but this is a good start and should do the trick.

  106. Mark

    Hello Karl

    Many thanks for you response.

    Nothing is happening. I think that the "addClass" immediately after the "removeClass" is turning it straight back on again. Does some kind of IF statement need to be applied?

    Regards.

  107. Karl

    Hi Mark, I'll have to look at your page to see what is going on. The addClass should not be changing any of the h4 elements except the one that you click on. That's why you're using $(this) instead of $('h4') for the addClass.

  108. Mark

    Sorry, my mistake, I should have been much clearer. When I click on the title I'm currently reading, to close it down (almost as if I've refreshed the page and reset everything) the current title doesn't loose it's "on" class. It's a little pedantic but thought there might be a solution. To be honest, I was kind of getting us to the class staying on - it gives me a nice "visited" link sort of vibe!

    On an aside, if your looking for tutorial subject matter I'd love to see a jquery version of this: Ajax Sortables! I haven't seen any jquery tuts that allow you to dynamically update databases.

    Many thanks again.

  109. Hannes

    Hi,

    I am using the accordion as part of a vertical navigation with h2 as header and nested ul as the submenue that I want to hide. The toggle works fine, but somehow the hiding of the siblings doesn't work.
    Does anyone has an idea why?!?

    THANKS A LOT, Hannes

    here the jQuery:

    
    $(document).ready(function() {
           $('h2').next('ul').hide();
            $('div#sidebar> ul h2').click(function() {
              $(this).next('ul').slideToggle('fast');
              .siblings('ul:visible').slideUp('fast');
            });
          });
    

    here the html:

    
    
    • Portfolio
      • Flyer
      • web
    • Blog
      • projekte
      • news
  110. Hannes

    Sorry,

    here the html:

    
    <div id="sidebar">
    <ul id="nav">
    <li class="categories"><h2 class="portfolio">Portfolio</h2>
    <ul>
    	<li class="cat-item cat-item-8">Flyer</li>
    	<li class="cat-item cat-item-11">web</li>
    </ul>
    </li>
    <li class="categories"><h2 class="blog">Blog</h2><ul>
    	<li class="cat-item cat-item-12">projekte</li>
    	<li class="cat-item cat-item-13">news</li>
    </ul></li>
    
  111. devartstudio

    great!
    good tutorial.

    best regards!

  112. sutra

    Hi, great tutorial.

    I want to use Definition List and have the behaviour sets to 'hide' in first menu (just like your example) but don't know how to modify your code.

    This is what I have from other tutorial:

    $(document).ready(function(){
    $('dt a').click(function(){
    $(this).parent().next().siblings('dd:visible').slideUp('slow');
    $(this).parent().next().slideToggle('slow');
    return false;
    });
    });

    and my markup is like so:


    Title 1

    • content for title 1
    • content for title 1

    Title 2

    • content for title2
    • content for title 2

    Please helps!

    Many thanks!

    t

  113. sutra

    Sorry, it couldn't show my markup. What I want is to use DL instead of DIV class, and I want the DTs as 'title 1', 'title 2' and 'title 3'. When the page first loaded, the DD in the title 1 is hidden.

    $(document).ready(function(){
    $('dt a').click(function(){
    $(this).parent().next().siblings('dd:visible').slideUp('slow');
    $(this).parent().next().slideToggle('slow');
    return false;
    });
    });

  114. Karl

    Hi Sutra, it looks like you might need to use John Resig's nextUntil utility plugin:

    $.fn.nextUntil = function(expr) {
       var match = [];
       // We need to figure out which elements to push onto the array
       this.each(function(){
           // Traverse through the sibling nodes
           for( var i = this.nextSibling; i; i = i.nextSibling ) {
               // Make sure that we're only dealing with elements
               if ( i.nodeType != 1 ) continue;
               // If we find a match then we need to stop
               if ( jQuery.filter( expr, [i] ).r.length ) break;
               // Otherwise, add it on to the stack
               match.push( i );
           }
       });
       return this.pushStack( match, arguments );
    };
    

    Here is an example of it in use.

  115. sutra

    Hi Karl,

    Thank you so much for the reply, but the example is just a plain html page !)

    Last night I played with your code a bit further and was finally able to come out something like this:

    $('dl#cateringmenu_index> dd').hide();
    $('dl#cateringmenu_index> dt a').click(function() {
    $(this).parent().next().siblings('dd:visible').slideUp('fast');
    $(this).parent().next().slideToggle('fast');
    return false;
    });
    });

    it was Accordion menu and works great until client said no, I want the pop up window, now it's a lightbox effect lack of 'close' button' in the pop up :)

    tiny url page (not spam): http://tinyurl.com/2ckq3s

    Thanks again for the great tutorial, you explain it so well that I am finally able to wrap my head around jquery.

  116. Karl

    I'm glad you found the tutorial helpful, and it's nice to see that you got something working for your client. Yeah, I probably should have pointed you to a more obvious example of the plugin. Next time. ;)

  117. susan

    I'm playing with this to make some changes to my personal portfolio site and am wondering what I need to do to make the first set of content show when a user lands on the page. For this example, I would want the content under Title 1 to be showing when the user lands on the url.

    Thanks so much for the great tutorial!

  118. bali web designer

    ha finally step by step explanation :) thanks

  119. Jay

    Hi,

    What a great thread! A wonderful community this is! Someone else created this accordion menu and I can't seem to work out adding the functionality I need. Maybe someone could give me some help.

    I have this accordion menu that functions properly, though it reloads when a link is clicked (page referesh) so the accordion is closed instead of re-opening the menu panel with the active link. Similar to Dustin's problem above. Here it is if anyone has a few minutes to share:

    var Sisters = Sisters || {};

    Sisters.showloginform = function() {
    $('#footer #block-user').fadeIn("slow");
    }

    Sisters.buildAccordion = function() {
    var str = window.location.toString();
    var panel = 0;
    if (str.indexOf('/companions/') > -1) { panel = '1'; }
    else if (str.indexOf('/vocations/') > -1) { panel = '2'; }
    else if (str.indexOf('/support/') > -1) { panel = '3'; }
    else if (str.indexOf('/justice_peace/') > -1) { panel = '4'; }
    else if (str.indexOf('/ministries/') > -1) { panel = '5'; }
    else if (str.indexOf('/red/') > -1) { panel = '6'; }
    else if (str.indexOf('/spiritual_centers') > -1) { panel = '7'; }
    else if (str.indexOf('/meet') > -1) { panel = '8'; }

    $('ul.menu:first').hoverAccordion({
    active: 'active',
    activateitem: 'panel',
    speed: 'slow',
    keepheight: 'true'
    });

    }

    Sisters.linkActivator = function() {
    doc = document.location.href ? document.location.href : document.location;
    split = doc.split('/');
    link = split[split.length-2].toLowerCase() + '/' + split[split.length-1].toLowerCase();
    linkTwo = split[3].toLowerCase();
    if (link=='/' || linkTwo=='') {
    return;
    }
    finder = "#sidebar-left li.leaf a[@href *= '" + link + "']";
    finderTwo = "#primary a[@href *= '" + linkTwo + "']";
    $(finder).css({color: '#000000', fontWeight:'bold'});
    $(finderTwo).css({color:'#084060', fontWeight:'bold'});

    }

    Thanks in advance for your help!

  120. Karl

    Hi Jay,

    Unfortunately, there is some missing information that I need to see in order to help you. You use the .hoverAccordion() method, but I'm not sure what that is supposed to do. Also, I don't see you binding a click handler to any of the links. At the very least, you should have the clicks return false on any links that you don't want to refresh the page or take you to another page. One more thing: it probably makes sense to declare your variables (doc, split, finder, etc.) using "var" to be sure you won't run into any naming collisions.

    Is there a URL where I can look at what you have so far?

  121. Jay

    Karl,

    Wow! Thanks for the quick reply.

    It's a drupal site. I didn't build it, I'm just helping out with it. Here it is: osfphila.org.ldh0242.uslec.net

    The CSS is a bit unorganized as well... .

  122. Karl

    Hi Jay, No problem. You caught me at the right time. ;)

    After taking a second glance at your code and your description of what you want to have happen, I think the problem lies here:

    activateitem: 'panel',

    With this "activateitem" option, you're now saying that it should match the string "panel." But since you have a bunch of lines of code before it which try to set the value of the panel variable, I'm guessing you want to remove the quotation marks:

    activateitem: panel,

    Try that, and let me know how it works.

  123. Jay

    Hi Karl,

    Thanks for your suggestion. I just gave it a try, but no go. :(

    Any other ideas?

    Thanks,
    Jay

  124. Jay

    Wow! Karl, your website is gorgeous! Elegant, stately, and modern--all in one--brilliant.

  125. Karl

    Thanks, Jay! <blushing>

    About the problem with the active section's menu items not showing, your best bet is probably to contact the developer of the hoverAccordion plugin. That activateitem option should be working with panel, as far as I can see. You should, however, remove the last line in the code now -- $(panel).show('slow');

    Here is an alternative way that you can get the active section's items to show, if it just won't work through the plugin's option:

    $(document).ready(function() {
      function findSection(path) {
        path = path.replace(/^\//,'');
        return path.slice(0,path.indexOf('/'));
      }
      var winPath = findSection(location.pathname);
      $('li.expanded > a').each(function() {
        if (findSection($(this).attr('href')) == winPath) {
          $(this).next().show();
        }
      });
    });
  126. Jay

    Karl,

    I can't thank you enough. You really saved the day!

  127. Odo

    Karl, great script! But I’m having visual glitches with IE7. It appears that the height of the content makes difference. Your demo works fine until I remove some “lorem…” content, in fact everything is smooth if there’s some text that fills up the div for more than 3 lines, less than that it jerks when closing. Just before final closing (last frame?) in animating I see the full open position and then it closes. I wonder why is that. Perhaps some magical css extra will solve the issue?

  128. Karl

    Hi Odo,

    I can't recall offhand what causes this sort of thing, but I think it might have to do with top/bottom padding or margin. You might want to try zeroing out those properties and trying again to see if that fixes the problem.

  129. Odo

    I played around with every height affecting property that popped into my mind (height, line-height, margin, padding) but nothing seemed to fix the problem. But then I did some research on Animate effect in Jquery library itself. It has 2 methods of “easing” i.e. how the smoothness of the anim is handled – linear and swing, latter being the default one as far as I understand. And this is where things go wrong I think. So I tried to force slideToggle and slideUp to use linear instead. I achieved this with the following code:

    
       $(this).next('div').slideToggle(200, 'linear')
       .siblings('div:visible').slideUp(200, 'linear');
    

    I’m not sure why it works though :) as the second parameter, like manual and demos describe is for callback (function to be executed whenever the animation completes). Ok still, this didn’t solve problems yet – had to test with different speeds to get the right smoothness and in my case 200 seemed ok speed. So in conclusion – managed to make it work for me but I’m not exactly sure how and why it works :)

  130. Sathish

    Hi Guys,

    Do any one know how to link JQuery with a Database?
    Please provide a sample if possible.

    Thanks for your reply in advance.

    Cheers
    Sathish

  131. Karl

    Hi Sathish,

    Your question is a little off topic. Anyway, you really need server-side code to communicate with the database. You can then use jQuery's ajax methods to request that code. Check out the ajax methods on the official documentation site for more information.

  132. Chad

    Hi, great tut! Just a question, let's say I have 3 links first and then 3 containers that I need to show and hide, obviously using sibling won't help since thecontainers are not sitting next to the links, what should a do in this case? Thanks!

  133. Chad

    Hi, great tut! Just a question, let's say I have 3 links first and then 3 containers that I need to show and hide, obviously using sibling won't help since the containers are not sitting next to the links, what should a do in this case? Should I use tabs instead of this approach? Thanks!

  134. Karl

    Hi Chad,

    You could certainly use tabs. It's a great plugin. If you want to do this on your own, it's pretty simple. I've put together a demo page for you.

  135. Ryan

    First off, thanks for the very informative website. I implemented some code base on your suggestions and I am plagued with a minor bug:

    http://ryanlsmith.com/tmp/jquerytest/index4.html

    If you check the aforementioned URL, the accordian works but after being clicked the layers don't hold their positoin and overlap some. I am assuming this is a problem with the div style attributes, can you offer some advice? Thanks in advance-
    -Ryan

  136. Hi Ryan,

    The problem is that all the divs inside each container div are floated, so they are outside the flow of the document. Adding clear: all; to .menu {} should do the trick. Let me know if that doesn't solve the issue for you.

  137. Karl

    Oops. Rather than .menu { }, that should, of course, be .menubar { }

  138. Ryan

    Hi Karl-
    Thanks for the response. I tried your suggestion and had no luck. Any other ideas? When I set the float:left attribute it fixes the current problem but the collapse no longer works right. Any ideas? Thanks in advance-
    -Ryan

  139. Karl

    Hi Ryan,

    Hmm. I didn't suggest using float:left. I just looked at your page again, but I didn't see clear:all; applied to the "menubar" class in the styles. Please do that, and if it still isn't working, I'll examine it more carefully.

  140. Bob

    Hi, I tested the code and works fine in Firefox. It does work in IE but there were some annoying "Flickerings".

  141. Nik

    Thanks! Works great

  142. milkshake

    Thanks, I was trying to figure that out for ages ;)

  143. blackproof

    when i enter links in the div tag that is the content of the accordian everything seems to work fine in firefox but in internet explorer the links just flash once and dissappear after that

    another problem with firefox is that my first title of accordian like in this pages its title 1 seems to dissappear in internet explorer

  144. Binusha Perera

    hi

    I am quite new to the jQuery and I am using it for my main menu navigation, the question i have is when i go to a new page from a link on the menu how do i keep the state (selected menu displayed in the accordion). Is there a simple way to do this ?

    Thanks
    Binu

  145. Rockstyle

    Ok: I've got something

    <div class="demo-show2">
      <h3>Title 1</h3>
      <div>Lorem...</div>
      <div>Lorem...</div>
      <h3>Title 2</h3>
      <div>Ipsum...</div>
      <div>Ipsum...</div>
      <h3>Title 3</h3>
      <div>Dolor...</div>
      <div>Dolor...</div>
    </div>

    I want i to toggle but I can't do it with the second div. Anyone got an idea how to toggle all divs and not only one?

  146. Karl Swedberg

    Binesh, please take a look at the cookie plugin. That should help you achieve what you're attempting. I have a demo page using it that might be helpful

    Rockstyle, you probably need to use John Resig's nextUntil utility plugin:

    $.fn.nextUntil = function(expr) {
       var match = [];
       // We need to figure out which elements to push onto the array
       this.each(function(){
           // Traverse through the sibling nodes
           for( var i = this.nextSibling; i; i = i.nextSibling ) {
               // Make sure that we're only dealing with elements
               if ( i.nodeType != 1 ) continue;
               // If we find a match then we need to stop
               if ( jQuery.filter( expr, [i] ).r.length ) break;
               // Otherwise, add it on to the stack
               match.push( i );
           }
       });
       return this.pushStack( match, arguments );
    };
    

    Here is an example of it in use.

  147. Rockstyle

    Any idea, how to do it without additional plugins? Maybe I sould put these two divs inside one and toggling only that one.

  148. Karl Swedberg

    Yeah, I think wrapping the two divs inside a single div would make the most sense.

  149. Bladescope

    Hey, first off, thanks of for the script it's greatly appreciated.

    Second off, is there any way to replace the h3 tags with divs instead?
    E.g.

    Title 1
    Content
    Title 2
    Content
    Title 3
    Content

    Any help would be helpful, thanks in advance,
    Bladescope

  150. Bladescope

    Apologies for the double post, but i'll rephrase. Here's an example of the code I would like to use with the script:

    Style:

    
        <style type="text/css">
    	div.box {
    	border: 1px solid black;
    	width: 300px;
    	float: left;
    	}
    	div.desc {
    	border-bottom: 1px solid black;
    	border-left: 1px solid black;
    	border-right: 1px solid black;
    	width: 300px;
    	clear: left;
    	}
    	div.class {
    	float:left;
    	width:200px;
    	}
    	div.status {
    	float:left;
    	width: 100px;
    	}
        </style>
    

    Code:

    
    	<div class="demo-show">
    	<div class="box">
    		<div class="class">{Class}</div> <div class="status">{Status}</div>
    	</div>
    	<div class="desc">{Description}</div>
    	</div>
    

    Again, it's a great script and thanks for showing it to us :D

    Any help would, again, be appreciated.
    Bladescope

  151. Karl Swedberg

    Hi there,
    Sure it's possible. It's unclear to me which div(s) you want to bind the click event to and which one(s) you want to hide and show. Do you want the "description" div to appear when you click the "class" div? When you click the "status" div? Both? Neither? I'm confused.

    However you have it set up, I think the trick for you will be to use a combination of child/parent selectors and the this keyword.

  152. Nick

    Yo!

    Very nice script..however i've encountered a problem though. It basically 'jumps'. So the content appears, then jumps up about 10 pixels. When you click to close, it jumps down the same amount, the new content appears and same thing happens.

    Turns out it happens when you include p tags inside the divs that get shown/hidden.

    To solve this problem, you have to make sure those p tags are given margin and padding of 0px in your css. Number of ways to do this, but best to give each div your showing/hiding the same class (such as 'showhidecont') and put this in your css

    
    .showhidecont p
    {padding:0px;
    margin:0px;}
    

    Problem solved!

    :)

  153. Philip

    Karl,
    some great tutorials on jquery here, thanks a lot. I'm very interested in your (Tab Example). I was wondering how I would go about hiding all the panels (instead of having one automatically showing) and having them slide up and down on-tab-click like this accordion example? i.e. zero or one.
    -Philip

  154. Philip

    Thanks Karl! That's fantastic. My skills are mostly (X)HTML and CSS but having seen your site, the demos, and your helpfulness I think I'll add your jQuery books to my bookshelf!
    -Philip

  155. Josh

    Anyone ever use this application with an unordered list and sub menus? I have a client that wants to have a vertical navigation able to reveal sub navigation for each section on rollover. I realize i could set it up as individual s but would like to maintain my

      i have already created. Any help is appreciated.

      Thanks.
      Josh

  156. Brad

    I'm migrating a site onto a new CMS and they used an old version of accordion that I just couldn't get working with the newest version of accordion and jquery.

    Your code took about 10 minutes to get working once I figured out I needed to use # instead of . since I use an ID on my main div!

    Very awesome tutorial.

  157. Marko

    Hi,
    every time I use slidetoogle, the content wich is hidden just before slideing shows up in a milisecond completly, hides back, then he slides down, and when I click to slideup, he slide just fine, and when he rich end, he do this reset - streching thig again in milisecond, and then it hides again.

    I dont get it, because I am using examples code above, but when I trying it here on your page everything is just fine, so I suppouse this hasnt nothing to do with IE6 wich I am useing.

    Thanks.

  158. Karl Swedberg

    Hi Marko,

    If it works here but not on your page, I guess the first thing to do would be to see what the differences are between the two pages. You might want to start by looking at the CSS. If you'd like some help, post a link to the page in question.

  159. Marko

    Hi Karl,
    I figure out that toggle function doesnt work good for me, but when I use hide and show alone it works great, so I am using

    $(document).ready(function() {
    $('div.demo-show2> div').hide();
    $('div.demo-show2> h3').click(function() {
    $(this).next('div').show(500)
    .siblings('div:visible').hide(300);
    });
    });

    and now I need only to close existing (with hide, not with toggle) without oppening new , so can I tell something like "If click on existing one wich is oppened, hide it"?

  160. Patrick

    Thank you very much for this awesome tutorial !!

    I am really happy with this,superb !

  161. Dodgson

    Hey guys, I'm new to this... I have put together the Accordian panel, but am having problems with one thing. I really want to have an additional heading within each panel. For some reason the as soon as I add a subhead and add a or or

      etc. the panel will not hide or work for that manor. Is there any way to style an additional heading (other than the standard H3). Thanks for any light you can shed on this.
  162. Dodgson

    sorry about last post.. It left out the tags... h5, div, ul, li etc.

  163. Tyler B.

    Hello Karl,

    This code/post has been incredibly helpful. There's a good variation on this here (scroll to example 4) that expands on this code to include a class toggler and more.

    I do have a question. Would it be possible to do an "upside-down" version of this accordion? For instance, if I clicked on "Title 2", Title 1 & 2 would shift up, Title 2's div would reveal and also shift up, and Title 3 would remain stationery during this whole fiasco. I've tried experimenting and Googling, but no such luck (plus I'm not even sure what to use as search terms. Upside-down accordion script? Bottom align accordion script?). Part of my brain refuses doesn't believe the internet will even allow this to work.

    If you know of any solutions, scripts, or even any initial hints of an idea, that would be most helpful.

  164. samy

    hi karl,

    I have a non accordian question.
    i’m trying to use the following code and i want to hide a div “.nextblock” when i click any where on the page, except on that div. But this is not working. It hides the block even if i click on the div “.nextblock”.

    $(”body,div”).not(”.nextBlock”).click(function () {

    $(”.nextBlock”).hide();

    });

    I tried using filter() instead of not. That does not work either.

    I would appreciate if you could sujjest some thing.

  165. webanalyst

    I have failed to implement the above for the following... on clicking the word "change" it should toggle the 'secondchild'... I can do this one 'firstdiv' but then it goes on the next 'seconddiv'. How can I implement the above method with different parents...


    #secondchild{ display: none; }

    NameChange
    Full NameSantosh S Kumar

    ...

    NameChange
    Full NameSantosh S Kumar

    ...

  166. webanalyst

    Sorry the was not enclosed in pre...
    I have failed to implement the above for the following... on clicking the word "change" it should toggle the 'secondchild'... I can do this one 'firstdiv' but then it goes on the next 'seconddiv'. How can I implement the above method with different parents...

    #secondchild{ display: none; }
    
               NameChange
               Full NameSantosh S Kumar
             ...
               NameChange
               Full NameSantosh S Kumar
             ...
    
    
  167. webanalyst

    I am extremely sorry for the above two comments.. they were not properly wraped inside the tags... I kind of figured out by changing the HTML layout. Thank you so much for the post.

  168. Jomy

    Any way to implement Accordion--when clicks on title it need to open a new page along with expanding

  169. Deon

    Hi karl, i have followed all the example from above but my code just doesnt work... and one question, wher do i get the "more-show-hide.js" ?