JQuery: Animated Collapsible List

The more you use JQuery, the more intuitive it becomes, as well as easier and enjoyable. I extracted this example from a book I’m reading, and I will provide links at the end of this post to aid understanding. Here’s a snapshot of the demo, and when you click on the + or -, it will collapse or expand the children with animation.


Download this demo’s zip file here. (just unzip and open the html in your preferred browser.)

Here’s a snipplet of the JQuery code that makes it all work.

<script type="text/javascript">
            if (this == event.target) {
                    (!$(this).children().is(':hidden')) ? 'url(plusbox.gif)' : 'url(minusbox.gif)');
            return false;
        .css({cursor:'pointer', 'list-style-image':'url(plusbox.gif)'})
    $('li:not(:has(ul))').css({cursor:'default', 'list-style-image':'none'});


I’m not going to go into explaining every line, but here’s a short summary.

  1. Line 2: Using JQuery to bind a Document Ready function when DOM elements are loaded and ready to be manipulated. I’m using the shorthand style, instead of $(document).ready(fn).
  2. Line 3 -5: Setting default CSS style for <li> elements on page.
  3. Line 6 -16: For all <li> elements with <ul> as child, we first bind a click event handler. The handler modifies the list-style-image accordingly by checking if it’s children are hidden or not, and also toggles ‘hide/unhide’ animation on it’s children using toggle(‘slow’).
    (Line 15-16) Next, we set a default CSS style for it’s cursor (when mouse over) to a pointer, and list-style-image to plusbox.gif. Last, we hide it’s children, which should be the default when page loads.
  4. Line 17: for all <li> elements that DO NOT have <ul> elements, we set default CSS style for cursor to default, and no list-style-image.

Hope that helps, below are some useful references to the JQuery API used in this example.

If this is too confusing, might help if you look at my Introduction to JQuery, or have a look at the JQuery site documentation and tutorials.

JQuery is a lot of fun, and for a MS developer, this has become a life saver for client side scripting. Happy coding!

Share this post:

6 Responses to “JQuery: Animated Collapsible List”

  1. Hasanah Says:


    Thank you so much for this. I’m a javascript newbie and I was wondering if you could help me with toggling? Right now when I open Item 4, Item 3 remains open. I’d like it to automatically close when I open Item 4, but I’m not sure how to go about this.

    Help? Thanks in advance.

  2. Andrew Says:


    Thank you for the great script and I was wondering if you can help me with a small thing. I have added some links in my list, but unfortunatly they do not open because of “.click(function(event)” and I was wondering if you can help me fix the anchor problem.

    Thank you in advance. Can`t wait to hear from you.

  3. Omeguis Says:

    I have the problem, can someone please help?

  4. Nabil Says:

    thanks, I had little trouble, click being called 2 times.. so I ad to handle it manually….

    first time for the expanded item, and immediately after click is being called for the first child in the list .

    any thoughts?

    var clickHandeled = 0;
    $(function () {

    $(‘#div_wrap li’).css(‘pointer’, ‘default’)
    .css(‘list-style-image’, ‘none’);

    $(‘#div_wrap li:has(ul)’)
    .click(function (event) {
    // alert(this.innerText + ‘ ‘ + clickHandeled);
    if (clickHandeled == 1) {
    clickHandeled = 0;
    return true;
    if (this == event.target) {
    if ((!$(this).children().is(‘:hidden’))) {
    $(this).css(‘list-style-image’, ‘url(minusbox.gif)’);
    } else {
    $(this).css(‘list-style-image’, ‘url(plusbox.gif)’);
    clickHandeled = 1;
    return true;
    .css({ cursor: ‘pointer’, ‘list-style-image’: ‘url(plusbox.gif)’ })

    $(‘#div_wrap li:not(:has(ul))’).css({ cursor: ‘default’, ‘list-style-image’: ‘none’ });

  5. Alesandro de Lima Says:

    .css(‘pointer’, ‘default’)
    .css(‘list-style-image’, ‘none’);
    .click(function (event) {

    if (this == event.target) {
    (!$(this).children(‘ul’).is(‘:hidden’)) ? ‘url(https://dl.dropboxusercontent.com/u/4472595/plusbox.gif)’ : ‘url(https://dl.dropboxusercontent.com/u/4472595/minusbox.gif)’);
    return true;
    .css({ cursor: ‘pointer’, ‘list-style-image’: ‘url(https://dl.dropboxusercontent.com/u/4472595/plusbox.gif)’ })

    $(‘li:not(:has(ul))’).css({ cursor: ‘default’, ‘list-style-image’: ‘none’ });

    Use this if you want to have divs or elements within your li’s

    .Children() will hide all elements and you may not want that.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: