"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

Anthony's picture
Nov 5, 2009
6:34 pm
Anthony

This demo works great however when I add this code to my JSP and I use the collapsible.js from above then I am getting a strange behavior. When the fieldset is open and I clik on the legend, it closes, reopens and then closes again. When I click on the closed fieldset it opens, closes and then reopens. Have you ever encountered this behavior? any ideas? Is the link to the collapsible.js file above pointing to the same file used in the demo?
Thank you,
Tony

PeterSmith's picture
Jun 28, 2011
4:07 am
PeterSmith

You published a really important information! It really helped me in my work! custom writing

jp2symposium.org's picture
Dec 14, 2013
4:55 pm
jp2symposium.org

“Reply to comment | Michael Irwin - Web Developer” was a fantastic blog
post. If merely there were even more web blogs just like this excellent one
in the actual cyberspace. Well, many thanks for ur precious time, Melina

kim's picture
Mar 13, 2013
11:48 am
kim

It was great to land on this blog post and to read such amazing stuff. Your blog is full of authentic and highly-researched information that is worth reading. I will surely recommend your blog to my fellows!
download youtube videos

best ways to make money's picture
Nov 4, 2013
6:32 am
best ways to make money

When I initially commented I clicked the "Notify me when new comments are added"
checkbox and now each time a comment is addedd I gett four e-mails with the same comment.

Is there anny waay you can rmove people from that service?
Cheers!

optimum 9200's picture
Jul 10, 2014
5:32 pm
optimum 9200

What's up Dear, are you genuinely visiting this web site daily, if
so then you will definitely take nice knowledge.

mikesir87's picture
Nov 5, 2009
6:41 pm
mikesir87

@Tony I have never seen this happen before, and I've used it on several of my sites. The collapsible.js file has the same source code as the one in the demo. Are you sure you're only including the js file once? If you have it more than once, it could be triggering the click event a few times. What browser are you experiencing this in?

Anthony's picture
Nov 6, 2009
5:13 pm
Anthony

Hi Michael,
I love your collapsible fieldsets. I have some that I wish to be initially closed upon pageload. Is this possible? Could you show how to implement this?
Thank you so much!
--Mike

empower network's picture
Nov 20, 2013
7:09 am
empower network

As the adxmin of this site is working, no uncertainty very soon it will be well-known,
due to its quality contents.

Appreciating the persistence you put into your blog and detailed information you provide.
It's nice to come across a blog every once in a while that isn't the saje out of date rehashed information.
Fantastic read! I've bookmarked your site and I'm adding your RSS feeds to
my Google account.

Anthony's picture
Nov 6, 2009
5:15 pm
Anthony

hi Michael,
Yes, I corrected that issue. I had somehow added the function three times to each fieldset. Doh! I'm not sure how but I have corrected it now and it works beautifully!
Is it possible to have the fieldset display closed initially?
Thank you,
Mike Anthony

mikesir87's picture
Nov 6, 2009
8:07 pm
mikesir87

Anthony,
I've made a revised version, and posted it as another attachment. It's the file labeled v2. At the end of the tutorial, I posted a little update on how to use it. The demo has also been updated to show this. If you want, I can extend this tutorial (probably make another one) that explains how I added the ability for options. Just let me know!
Thanks!

Alex B's picture
Apr 20, 2011
9:59 am
Alex B

Thanks for awesome tutorials about jQuery plugin - very useful for me! Nice stuff for my essay papers as practice in college.

makyaj yapma's picture
Nov 21, 2009
4:29 am
makyaj yapma

Thanks for this plug-in

sextreffen in hamburg's picture
Jun 4, 2014
1:28 pm
sextreffen in hamburg

Amazing! Thiss blog looks exactly like my old one! It's on a totally different topic but
it has prettyy muuch the same layout and design. Excellent
choice of colors!

Ella Harrow's picture
Nov 23, 2009
1:40 pm
Ella Harrow

Thanks i was looking for this for my site.

emichan's picture
Nov 23, 2009
3:29 pm
emichan

Hi, thanks for posting this. Just a quick suggestion. Instead of

$(this).parent().children().filter("p,img,table,ul,div, /
span,h1,h2,h3,h4,h5").toggle("slow");

why not use

$(this).parent().children().not("label").toggle("slow");

?

It will save having to anticipate all of the possible tags one could put inside a fieldset.

HTH, Emi

mikesir87's picture
Nov 23, 2009
3:33 pm
mikesir87

Great suggestion! I'll update the scripts. However, I'll change it to $(this).parent().children().not('legend') Thanks for the tip though! :-)

emichan's picture
Dec 6, 2009
3:37 pm
emichan

Yes, haha, I meant legend - not label. :)

top compact digital cameras's picture
Jul 2, 2014
11:48 pm
top compact digital cameras

Hi, all the time i սsed to check web site posts here in the
early hours in the morning, ƅecause i love to learn more and more.

Luis Monroy's picture
Dec 2, 2009
12:12 pm
Luis Monroy

This is great information. Thanks so much for sharing. Its really gonna help me out!

spoetnik's picture
Jan 31, 2010
3:36 pm
spoetnik

Great plugin. Got it working, but found one glitch.
When i would like to have an easyslider (http://cssglobe.com/post/5780/easy-slider-17-numeric-navigation-jquery-s...) in a default collapsed fieldset, the slider stays 'display:none' This doesn't get update by the Collapsible Fieldset plugin.
Any suggestions?

mikesir87's picture
Jan 31, 2010
4:02 pm
mikesir87

Do you have a demo URL in which I can check out?

Lord Matt's picture
Feb 1, 2010
12:15 pm
Lord Matt

I was able to get the initiated as closed to work by changing line 35 to

obj.children().not('legend').css('display', 'none');

As it stood it refused to start hidden.

However mixed text (not in anything else) images and form elements all seemed to become block elements or something including the a element which appeared to take up 100% of width and as you can imagine this looked messy.

The same thing happened while the fieldset was hiding the layout would deform.

I don't have a demo (actually I do but it is tucked behind a whole heap of security and is under development).

In the end I tired of ugly forms and removed everything so I could focus on getting everything else working. I'd love to have the time to get to the bottom of what was going on though.

mikesir87's picture
Feb 1, 2010
12:42 pm
mikesir87

Ahhh... I see. You are correct. I recently made the change on line 26, but didn't do it where you noticed. I've updated the script here, as well as the jQuery plugin repository.

For it to work correctly though, you will need to have some sort of wrapping element around it all (whether a div, span, p, etc.). Plain text will still appear (if not wrapped in anything), and I'm not too sure of a way around that (unless it creates an entirely new fieldset and legend, but that seems unnecessary). Let me know if you think of anything.

cho thue ban ghe's picture
Jun 28, 2014
9:38 am
cho thue ban ghe

While some feel as though they are preserving their purity if they only
commit to fellatio or cunnilingus, many teenagers and even adults mistakenly believe that they will be
protected against sexual disease or infections. Remember,
he doesn't need as much time as you would to prepare to receive oral
sex. Find out the essentials about a wide range of careers in this amazingly succinct yet comprehensive review.

Vamshi's picture
Mar 2, 2010
2:03 pm
Vamshi

First of all Great Plugin! and thanks for sharing it!

I found a problem with this plugin,let me explain it as follows:

What if you have multiple field sets in one fieldset .

Parent1
Child1
Child2
Child3

When I collapse/un-collapse the child the parent collapses.

How can I avoid that ? Any thoughts

mikesir87's picture
Mar 2, 2010
2:38 pm
mikesir87

@Vamshi - nice catch! I've posted an updated version of the plugin, which should resolve the issue. Let me know if it works. It's version *.2

Tod Gabehart's picture
Jun 30, 2014
2:24 pm
Tod Gabehart

Hi people if you can't earn any money online try - bluehand roulette system - it
earns me extra money everyday, just google it

Vamshi's picture
Mar 3, 2010
2:20 pm
Vamshi

Awesome ! It works Gr8!

But when i collapse and un-collapse a fieldset the fields in it become distorted, and when i refresh it they will become normal.

Do you know what is causing it ?

mikesir87's picture
Mar 3, 2010
2:26 pm
mikesir87

What browser are you using? Do you have a demo or any screenshots?

Vamshi's picture
Mar 3, 2010
3:15 pm
Vamshi

When you collapse it the table inside the fieldset becomes:

When you un-collapse it the table inside the fieldset becomes:

I think that "block" thing is causing the problem

Vamshi's picture
Mar 3, 2010
3:17 pm
Vamshi

I am using Firefox , it works in IE 8 though

mikesir87's picture
Mar 3, 2010
4:09 pm
mikesir87

Well, the style="block" comes from jQuery itself because it is being shown again. I'm not too sure how to resolve this issue, as this is built-in into jQuery. There appear to be other people that are wondering this, looking at the API page for slideDown (http://api.jquery.com/slideDown/).

australia health insurance's picture
Jul 22, 2014
1:17 am
australia health insurance

This paragraph offers clear idea in favor of the
new people of blogging, that really how to do running a blog.

crimsonchilla's picture
Jul 23, 2014
5:02 am
crimsonchilla

Lots of companies that are well establish may not
provide as good of service as you may expect.

They are very intelligent and like to be clean, so they
should pick it up quickly. Most ferrets are easily trained to use a litter box and
it helps if it is kept in the same place in their cage or in the corners of your "ferret room".

Peterborough Housing's picture
Mar 20, 2010
1:27 pm
Peterborough Housing

Very Great Plugin i want to say thank you for sharing it!

Varun Vohra's picture
Mar 22, 2010
12:58 pm
Varun Vohra

Michael

Thank you a million mate. This saved me some much needed trouble coding my own jQuery to do something similar to multiple accordions on the same page. I owe you one :)

-Varun

mikesir87's picture
Mar 22, 2010
1:03 pm
mikesir87

Glad you enjoyed it! Let me know what site you're using it on, and I'll add it to my list! (I'm going to have a list up soon)

Anonymous's picture
May 21, 2010
4:40 pm
Anonymous

Simpler:

$(document).ready(function(){
	$("fieldset.collapsible legend").click(function() {
		$(this).parent().children().not("legend:first").slideToggle("fast");
	});
	$("fieldset.collapsible.collapsed legend").parent().children().not("legend:first").hide();
});

Christian Voigt's picture
May 25, 2010
3:02 pm
Christian Voigt

To gain control over both states you could use

$("fieldset.collapsible legend").click(function() {
$(this).parent().children().not("legend:first").slideToggle("fast");
$(this).parent().toggleClass('collapsed');
});
$("fieldset.collapsible.collapsed legend").parent().children().not("legend:first").hide();

Todd's picture
Jun 3, 2010
3:04 am
Todd

Hey Michael,
Great plugin! Thanks for creating it.

Only problem I had was that it didn't play nicely with other JS libraries when using jQuery. Mainly the jQuery.noConflict() support to use a different identifier other than '$' for jQuery.

The fix for this is easy. I just changed the plugin to use 'jQuery' instead of the '$' variable in the plugin itself.

Thanks again!

Todd

mikesir87's picture
Jun 3, 2010
6:11 am
mikesir87

Great catch! I haven't had to use noConflict too much, so thanks for letting me know!

I've posted an updated version both here and in the plugin repository.

Thanks!

Chris's picture
Jun 4, 2010
5:18 am
Chris

Could this be used to display a form? Sorry if this is obvious but im new to jQuery.

mikesir87's picture
Jun 4, 2010
6:05 am
mikesir87

Sure! This could be used in a form to better organize the materials. Feel free to send me some details of what you're thinking in my contact form, and I'll help you through it! :-)

stonefield's picture
Jun 25, 2010
5:44 am
stonefield

Thank you for the plugin.

Is there a way to change the cursor behaviour? I'd like to have a "hand" when hovering over "legend".

mikesir87's picture
Jun 25, 2010
6:04 am
mikesir87

There absolutely is a way to do that. Using CSS, you can use the :hover attribute. So, it would be something like this:


legend:hover {
cursor: pointer
}

You can view more options by going to this page: http://www.w3schools.com/CSS/pr_class_cursor.asp

Hope it helps!

stonefield's picture
Jun 28, 2010
9:56 am
stonefield

Thanks for your help mikesir87. I think I was a bit confused when I was solving the problem and wrote "cursor: hand". ;)

anantha's picture
Jul 2, 2010
3:41 pm
anantha

I have a fieldset with id and inside the fieldset it has legend
and div..I want to collapse the fieldset..when i click it has to open and when i close it has to close...but i am thinking the code has used legend for clickable place..since i don't have legend in my code...can i use this code? i am thinking to just change the legend to h2 or something like that...will it work...reply plz...thx

mikesir87's picture
Jul 11, 2010
12:09 am
mikesir87

@anantha,

Sorry for the slow response... but, I'm not sure I fully understand what it is that you are requesting. You say you have a fieldset with a legend and div, but then you don't have a legend in it. Not quite sure... Do you have a link to an example that I can help you out with?

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".

More information about formatting options