Collapsible List with jQuery (Part 2)

Posted by jcargoo | Thursday, December 4, 2008
| 0Delicious Twitter Reddit Digg Loading...


In the previous post (part1) I have talked about how to create a Collapsible List with jQuery.
I want in this current post to talk about how to animate the display of the Collapsible List with toggle.
The show() (), hide(), and toggle() commands are complex functions.
When we call those functions with no parameters, they effect a simple manipulation of the display state of the wrapped elements, causing them to instantaneously be revealed or hidden from the display. But when passed parameters, these effects can be animated.

toggle(speed,callback)
Performs show() on any hidden wrapped elements and

hide() on any non-hidden wrapped
elements.

Parameters
speed (Number|String): Optionally specifies the duration of the effect as a number of
milliseconds or as one of the predefined strings: slow, normal, or fast. If omitted,
no animation takes place.
callback (Function): An optional function invoked when the animation is complete. No
parameters are passed to this function.
In this article I want just to apply the toggle function to the opening and closing behaviors.
If you add the speed property ‘slow’ to the previous script here as following:
$(this).children().toggle('slow');
You will notice that you are getting some weird results.
So how to apply it?
We will change this:
$(function(){
$('li:has(ul)')
.click(function(event){
if (this == event.target) {
$(this).children().toggle();
$(this).css('list-style-image',
($(this).children().is(':hidden')) ?
'url(plus.gif)' : 'url(minus.gif)');
}
return false;
})
.css('cursor','pointer')
.click();
$('li:not(:has(ul))').css({
cursor: 'default',
'list-style-image':'none'
});
});
To this:
$(function(){
$('li:has(ul)')//(1)
.click(function(event){//(2)
if (this == event.target) {//(3)

if ($(this).children().is(':hidden'))
$(this).css('list-style-image', 'url(minus.gif)');//(4)

else
$(this).css('list-style-image', 'url(plus.gif)'); //(4)

$(this).children().toggle('slow');//(5)
}
return false;
})
.css({cursor:'pointer',
'list-style-image':'url(plus.gif)'})
.children().hide();//(6)
$('li:not(:has(ul))').css({//(7)
cursor: 'default',
'list-style-image':'none'
});
});
In this last script we need to explicitly use the hide() command (6), without parameters, to hide the element before the user gets a chance to see them and then to set the markers to the plus image. Why?
In our first script (without animation), in order to initially hide the collapsible elements, we called the click handler of the active items which immediately hides the child elements.
But now we’ve animated the behavior; so when the page loads, we see the child items hiding themselves in the animated fashion. This is the reason why we should use the hide function.
The whole script is too easy to dissect:
First, we select all list items that have list children by applying the jQuery containment selector li:has(ul) (1), and apply a chained series of jQuery commands to the matched elements, beginning with attaching a click handler (2).
This click handler checks to make sure that the target element of the event matches this (3). This is true only when the clicked item is the same as the one on which the listener was established; it allows us to ignore clicks on the child elements.
After if this has children which who are hidden, then we apply minus.gif to the current and vice versa (4).
The rest of the code is simply related to the animation part with toggle (5) as well as checking for list items which have not children (7).



How to encourage this blog if you like it:
  • Promote our sponsors;
  • Add any kind of comment or critic;
  • Ask me directly by email if you prefer.
Just do something like that, and I will have the huge pleasure to continue posting the best of the creativity I have.




Share this post ?

Digg Reddit Stumble Delicious Technorati Twitter Facebook

1 Previous Comments
  1. Anonymous | January 8, 2009 at 5:43 AM  

    this is great. i need to be able to add hyperlinks to the hidden list items though. This logic doesn't allow for click event for those items to happen. Any thoughts on how to do this?