Expand-collapse toggle panel (div) using jquery

In this post, I’ll show you how easy it is to show expandable and collapsible toggle panel using jQuery. When you click on the heading, the content gets displayed by sliding and when you again click on the heading again, it gets collapsed.


View LIVE DEMO

Now let’s look at the html code,

<div class="msg_list">
<p class="msg_head">Header-1 </p>
<div class="msg_body">
orem ipsum dolor sit amet, consectetuer adipiscing elit orem ipsum dolor sit amet, consectetuer adipiscing elit
</div>
<p class="msg_head">Header-2</p>
<div class="msg_body">
orem ipsum dolor sit amet, consectetuer adipiscing elit orem ipsum dolor sit amet, consectetuer adipiscing elit
</div>
<p class="msg_head">Header-3</p>
<div class="msg_body">
orem ipsum dolor sit amet, consectetuer adipiscing elit orem ipsum dolor sit amet, consectetuer adipiscing elit
</div>
</div>

As you can see above, the whole message panes contained inside the div with class name “msg_list”. And, the header element where you click is defined with the class “msg_head” and after that there is element with class “msg_body” which contains the message or text which is expandable or collapsible.

Now let’s look at the CSS attributes of these three classes,

p {
padding: 0 0 1em;
}
.msg_list {
margin: 0px;
padding: 0px;
width: 383px;
}
.msg_head {
padding: 5px 10px;
cursor: pointer;
position: relative;
background-color:#FFCCCC;
margin:1px;
}
.msg_body {
padding: 5px 10px 15px;
background-color:#F4F4F8;
}

Now, let’s look at the JavaScript code to make the pane toggling i.e collapsible and expandable,

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
  //hide the all of the element with class msg_body
  $(".msg_body").hide();
  //toggle the componenet with class msg_body
  $(".msg_head").click(function()
  {
    $(this).next(".msg_body").slideToggle(600);
  });
});
</script>

As you can see above, first of all jQuery framework is used. After that, all the element with the class name “msg_body” is collapsed when the page is loaded. And you can see, the “slideToggle()” function of jQuery is used to expand and collapse the “div” with class “msg_body”. When user clicks on the element with the class “.msg_head”, then div with class “msg_body” next to it, gets toggled with sliding effect, making toggle panel using jQuery.

Download Full Source Code

If you want to learn more about jQuery then you can check the following books and buy them.I really recommend the book “jQuery in Action” for starting your way for jQuery.

Learning Jquery: Better Interaction Design and Web Development with Simple JavaScript Techniques


Jquery in Action

77 thoughts on “Expand-collapse toggle panel (div) using jquery

  1. Oscar

    Hi Roshan, nice article. The expand effect looks horrible but it’s just because all “msg_body” height divs are too small for an -in this case- long effect duration time. For those readers who are looking for a way to better this example (repeat it’s a good stuff but for highers divs) you can try this:

    $(document).ready(function(){
    $(“.msg_body”).hide();
    $(“.msg_head”).toggle(function(){
    $(this).next(“.msg_body”).slideDown(100);
    }, function(){
    $(this).next(“.msg_body”).slideUp(300);
    });
    });

    With shorter times for expanding divs, the effect looks better. My script isn’t so concise as Roshan’s, but it could be useful for some cases.
    Greetings from Peru to all.

  2. hi oscar..thanks for posting that comment..you are right shorter interval can be better than the current one..

    well it’s just the example for toggle panel and anyone can modify this script according to their need…

  3. Works amazing, thanks for this!

  4. abubin

    good and simple tutorial but what if I want the header to be at bottom?

    Meaning I click on the msg_head and msg_head will scroll down revealing the msg_body on top of it. Like the 180 degree turn on example above.

  5. chris

    Dear god i love you. i tried 4 different sites’ examples, none of which worked on my css jscript flash riddled mess of a site. thank you so much

  6. wow!!!!…what a nice compliment….thanks dude.

  7. Jamy

    Hi Roshan,
    Nice Example, and very much useful.

    How can we add collapse and expand images in the “msg_head” class?

    I badly need it. Can you please help me out?

  8. @Jamy – for this you can use css() function of jquery framework..look at this where I’ve did that…

    http://roshanbh.com.np/2008/06/accordion-menu-using-jquery.html

  9. Jamy

    Thanks Rosahn. I have a different senorio with me to hide / show selective div’s.

    I want to hide or show using the id of the div. which is not working / not giving any error.

    Fragment of my code is attached.
    thanks in advance.

    $(document).ready(function()
    {
    for (var i = 0; i < collapseArr.length; i++) {
    if (collapseArr[i] == ‘Y’) {
    $(“#category_body[” + i + “]”).hide();
    }
    }
    });

    function toggleCategory(categoryId) {
    $(“#category_body[” + categoryId + “]”).slideToggle(600);
    }

  10. Hi Roshan, every time your code is more and more compact, bravo! Now I want contribute too with these lines:

    $(‘.msg_list’).click(function(e){
    if ($(e.target).is(‘.msg_head’))
    $(e.target).next(‘.msg_body’).slideToggle(250);
    });

    It’s the same with a nice difference: it use event delegation, so if you add new content (example: via ajax) all newies will come with the toggle propertie, yeah, without need to call the declaration again and again. Event delegation is more efficient using PC resources too.

  11. @Oscar – great code dude..cheers for you…
    thanks for sharing it with us…..

  12. Thank you so much for this. Simple, concise and effective. You rock.

  13. Hi Roshan and hi everybody! I just developed a project using horizontal scrolling panels so in the spirit of jQuery, I decided to share it with you. You can find the example here:

    http://oscaralderete.com/hscrolling

    I guess you can find useful it.
    Regards

  14. @oscar- thanks for sharing the link…quite nice workd dude…

  15. Sharon

    All

    Novice here and scared of code. Am able to update pages and replicate to create new only.

    The above is exactly what I need to incorporate in a webpage but don’t understand how to add to my current page code. simply cut and paste or do I need the full source code

    TIA

    Sharon

  16. @sharon – just look at the full source and see how it is working ….you can read the tutorial to see the exaplanation for help hope it will help for you…

  17. Hi Roshan,

    thanks for making this available online. I’m new to jQuery as well. I’m a designer by trade. Have high respect for coders. I’m using your code for a page I’m designing, but I wanted to add a visited and hover state to msg_head. As someone who designs with css, my instinct was to add the following to the styles:

    .msg_head a:visited , a:hover, a:active, {
    padding: 5px 10px;
    cursor: pointer;
    position: relative;
    background-color:#eeeeee;
    color: #8c1919;
    margin:1px;
    }
    Can you give me an idea as to how I can create an visited and hover state?

    Thanks, Mali

  18. @Mali – If you want to visited and hover state to the links inside .msg_head then it should work I think

    msg_head a:visited , msg_head a:hover, msg_head a:active
    {
    padding: 5px 10px;
    ………

  19. Roshan,

    thanks for replying so quickly. Unfortunately, the style above doesn’t work. I think it might have to do with the fact that I’m not linking .msg_head, so there’s no usage of . I’m trying to change the hover state of .msg_head before it expand to include content within . I have to aproach it different. do you have any other suggestions? Thanks,
    Mali

  20. Hi Roshan,

    I received an email from you, but there wasn’t any comments on it. Any chance you replied, but the text didn’t go through?

    Mali

  21. @mali- you can’t have visited state without anchor tag I think…

  22. Max

    Nice nice example!! I am not very experience with JQuery or js in general.

    How would one add a “+” “-” or small arrow to make expand and collapse options more obvious for people who do not find such things obvious?

    Thanks!!

  23. Max

    Solved my issue with having +/. to indicate that the div is collapsible and expandable… to do so I slightly modified the function, .msg_head, and I added a new class called .msg_head2. See below:

    $(document).ready(function(){
    //hide the all of the element with class msg_body
    $(“.msg_body”).hide();
    //toggle the componenet with class msg_body
    $(“.msg_head”).click(function(){
    $(this).toggleClass(“msg_head2″).next(“.msg_body”).slideToggle(150);
    });
    });

    .msg_head {
    padding: 5px 10px;
    cursor: pointer;
    position: relative;
    background-color:#CCCCCC;
    margin:1px;
    background-image:url(images/plus.gif);
    background-position: 280px 5px;
    background-repeat:no-repeat;
    }

    .msg_head2 {
    padding: 5px 10px;
    cursor: pointer;
    position: relative;
    background-color:#CCCCCC;
    margin:1px;
    background-image:url(images/minus.gif);
    background-position: 280px 5px;
    background-repeat:no-repeat;
    }

  24. Max

    building on my previous comment… how can it be done so that if the page is reloaded it will remember the state of the collapsed and expanded DIVs?

    Thanks!!

  25. Matt

    I’ve got the same question as Max. Is it easy to adapt the code so that the state of expanded or collapsed divs is remembered on page load/refresh. I know it can be done with javascript cookies, but all the other examples I’ve found online would require me to completely change my markup – I love the simplicity of Roshan’s version and would like to keep the message_body/message_head structure intact.

  26. Sukru Boztepe

    @oscar

    About
    http://oscaralderete.com/hscrolling, how do you make it work without the tables. When I remove them it dos not show any of the divs except for the first one.

    If I change the width of the .oa_slider to say 9600px; and flaot the .oa_panel to left, it works but than i get a horizontal scroll bar.

    Any suggestion?

  27. @Sukru Boztepe
    Thanks for your comment, too much people ask me for a version without tables, so you can found here the new version and download files:
    http://oscaralderete.com/hscrolling2/
    You can customize it just editing CSS file, because now the JS file don’t need you enter any data.
    Happy holidays everybody!

  28. anonymous

    hi roshan,
    i pass through all the comments but didnt find my answer
    my problem is:
    if i have passed my cursor 10 times quickly on the menu….once my mouse is out of the firstpane or away from the menu i dont want the dancing effect which continues

  29. Dear Roshan, i was trying to implement but when page is loading all 3 news details are collapse when i clicking these are not expanding, what is the reason please tell me.

  30. Thanks oscar. That smoothed it all out :)

  31. sarah

    hi guys
    & thanks roshan
    do you know how to make it vertical?

  32. Sukru Boztepe

    Thank you Oscar.

  33. Hi,

    I love this code, but I have the same problem as Max and Matt. Is there a way to ensure that collapsed items stay collapsed after refresh? Or, as I am using this script to create a menu, can I specify that for a certain directory/page a specific menu_body should be expanded by default? I’ve tought about doing this using PHP if/else statements, but I don’t know what the outcome should be jquery-wise…

    Does anyone know how to do this or an alternative like using cookies?
    Thanks,
    Stef

  34. Hi, this looks great but I have sIFR text that needs to be in the .msg_head, and when I tack on my h2 tag, it makes it so you have to click around the invisible box the sIFR sits in to make the hidden text scroll down. Any ideas on how I can make it so you can click on the sIFR text and have the box scroll down?

    Thanks,
    Ryan

  35. Is there a way to link to a message_head from another page and have the body expand? I also saw the question but no answer to “Is it easy to adapt the code so that the state of expanded or collapsed divs is remembered on page load/refresh. “

  36. Hi Roshan. Could you see my first comment?

    Thanks a lot

  37. I guess my first comment had an error.

    My english is very poor, but I try to explain you my problem.

    I make this script for my blog, but, when somebody visit it with Chrome, the accordion menu works good, instead, if they are using Internet Explorer, doesn’t work

    Do u know why?

    thanks in advance.

  38. Cesar

    Hello Roshan,

    I’m looking for something like this (exactly like this) but to hide a whole table when the user clicks on an image outside that table… is it possible? How?

    Thanks!

  39. Cesar

    Hello again. Well, I’ve got it. I can make my table disappear now but following this example I can make it appear and disappear by clicking at the other table I have on top of the table I’m making disappear.

    The only problem is that in the “header” table, I’ve also got links and I would like the “body” table to disappear or appear when clicking on an image button on the “header” table. I was looking at your accordion example but the problem is that you don’t use a table so I don’t know how to us that in a table cell. You still are making the whole “row” clickeable and just changing the image.

    Thanks!

  40. Eric Nickus

    Nice work. Not too many examples that you can just cut and paste. Sweet. MS accordion control is a total joke compared to this
    Thanks

  41. Thanks! I tweaked it just a little. This code will only let you expand an element if it has more than 0 children. This gets rid of that slight little hiccup.

    $(document).ready(function(){
    $(‘.msg_body’).hide();
    $(‘.msg_head’).toggle(function(){
    if($(this).next().children().size() > 0){
    $(this).next(‘.msg_body’).slideDown(100);
    }
    }, function(){
    $(this).next(‘.msg_body’).slideUp(300);
    });
    });

  42. rizwan

    it did not works with table . can you tell me how i can make it to with tables .
    actullay i need to place forms

    Header-1

  43. Just as a heads up, this method works great on divs, but will not work on tables in IE. I had an instance where I wanted to slideToggle a few tables, but IE would choke. It works great in most browsers, but with IE I had to wrap everything in a div, like this example, to get it to work. Just throwing that out there if you are having issues extrapolating this method into other tags in IE.

  44. Stephen

    Hey can someone tell me how i can have an anchor tag on my page that collapses all the divs when a user clicks on it? I’ve tried coding it myself but after i click the link when i try to reopen any of the divs it opens then immediately re closes. Any help would be appreciated. Thanks.

  45. born2bedead

    hey roshan bro is it possible to enable cookie in this code. so for example, if i am expanding the content and refresh the page it keeps expanding and same when i am collapsing.

    thanks for the code bro.

  46. Excelent example, i have used it on my website. Thanks very much.

    Walter.

  47. vraman

    Hi,
    I am trying to customize this code so that one particular category(Dynamically selected) will be expanded when the page loads.
    But I am not able to get it working properly. Can you please help me with that?

  48. Deepak Rai

    Great post. Helpful for me.
    Thanks a lot.

  49. Justin St. Germain

    hey, i am having the same question as a couple others. i want to remember the expanded and collapsed div states between page loads. so, if for example, i expand my “Posts” div, and click something under that menu and then submit my changes, the “Post” div is longer expanded, so, i have to expand it again. please le tme know if you have a fix for this. thanks.

  50. Cool informations. Thx man.

Comments are closed.