"Innovation comes only from readily and seamlessly sharing information rather than hoarding it."- Tom Peters
Development Blog

Collapsible Fieldsets jQuery plugin - Drupal Style

Drupal does a great job in using collapsible fieldsets.  But, wouldn't it be great to be able to use this jQuery feature on other sites?  Well, here's your plugin.  In this tutorial, we will build a simple page, and then enable the collapsible fieldset on it.


Well, let's get started. First, let's make a simple HTML page to start with.


<h1>Collapsible Fieldset - jQuery plugin</h1>
<fieldset>
<legend>Cannot collapse me</legend>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam in nisi magna.</p>
</fieldset>
<fieldset class="collapsible">
<legend>Can Collapse Me!</legend>
<h2>1914 translation by H. Rackham</h2>
<p>"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment...,"</p>
</fieldset>

You'll notice that the first fieldset has no class, while the second one has a class of collapsible. We will be using this later on. You'll also want to go ahead and include the javascript source file for jQuery.

The jQuery plugin

Now, let's take a look at the actual plugin. What makes it work? How's it do it? Well, let's find out!


$.fn.collapse = function() {
return this.each(function() {
$(this).find("legend").addClass('collapsible').click(function() {
if ($(this).parent().hasClass('collapsed'))
$(this).parent().removeClass('collapsed').addClass('collapsible');

$(this).removeClass('collapsed');

$(this).parent().children().not('legend').toggle("slow", function() {

if ($(this).is(":visible"))
$(this).parent().find("legend").addClass('collapsible');
else
$(this).parent().addClass('collapsed').find("legend").addClass('collapsed');
});
});
});
};

Alright...jQuery makes it super easy to create your own functions, and add them right into the framework. The only thing that is required is the next line. This line of code ensures the ability for jQuery to chain together many functions. It allows you to do something like this:

$("p").css("color", "#0000FF").find("a").slideUp();

Now, I'm not sure why you would want to do a function like that, but you can if you include that line of code.

The third line of code selects the fieldset's legend, adds the class collapsible to it, and then creates the onclick function. Let's take a look at that...


if ($(this).parent().hasClass('collapsed'))
$(this).parent().removeClass('collapsed').addClass('collapsible');

$(this).removeClass('collapsed');

This part of the code checks to see if the parent (the fieldset) is currently in the collapsed state. If so, go ahead and add the 'collapsible' class. Now, why are we doing this? This ensures that the fieldset borders will be shown (if you style it to do so) DURING the animation, and not just have them appear once it's done.


$(this).parent().children().not('legend').toggle("slow", function() {

if ($(this).is(":visible"))
$(this).parent().find("legend").addClass('collapsible');
else
$(this).parent().addClass('collapsed').find("legend").addClass('collapsed');
});

This section of the code selects the fieldset, then its children, selects everything that is not the label, and then toggles it (does the animation of opening or closing). Now, if you notice that you are using an element not contained in this set, feel free to add it! Once the toggle is complete, the callback function is called to ensure the fieldset and legend are in their proper states. Pretty simple, huh?

The CSS

Now that we have our page and plugin, lets add some styling to it. I'm going to keep this VERY basic, but feel free to do whatever you want.


fieldset, fieldset.collapsible {
padding: 10px;
border: 1px solid black;
border-bottom-width: 1px;
border-left-width: 1px;
border-right-width: 1px;
margin-bottom: 1em;
}
fieldset.collapsed {
border-bottom-width: 0;
border-left-width: 0;
border-right-width: 0;
margin-bottom: 0;
margin-left: 3px;
}

legend.collapsible {
color: blue;
}
legend.collapsed {
color:green;
}

Putting it all together

Now that we have the HTML, the plugin, and the CSS, let's put it all together, and make this thing work! All you have to do now is select the elements you want to collapse, and make them work! Here's a sample...


<script type="text/javascript">
$(document).ready(function() {
$("fieldset.collapsible").collapse();
});
</script>

Now that you have your page, put it to work! Test it out! Let me know how it goes! Of course, this plugin currently doesn't have any configurable options. Feel free to let me know what you might want! I'll try to implement them as quickly as I can! Thanks!


UPDATE: Version 1.1 (and 2.1) have been released. The only change is the fieldset is now toggled using .not('label'), rather than .filter( ELEMENTS ). This will allow you to place anything you want in the fieldset, without having to limit to these elements. Thanks emichan for the tip!

UPDATE: I've added another version of the plugin below (v2.1). It allows you to initiate the fieldsets, and have certain ones closed. In order to do so, use something like this... (I've got the first line starting open, and the second line being closed. Just change the class for the fieldset).


$(document).ready(function() {
$("fieldset.collapsible").collapse();
$("fieldset.collapsibleClosed").collapse( { closed : true } );
});

UPDATE: Version 2.1.2 fixes an issue when nested fieldsets are used.

UPDATE: Version 2.1.3 makes the script $.noConflict() compliant. I will no longer update the original script that this tutorial made, but will still make it available below. I will do updates on the current release though.

AttachmentSize
Original Script968 bytes
jquery.collapsible-v.2.1.3.js1.43 KB