More Showing, More Hiding
We've received a number of comments recently from people looking for variations on the showing and hiding theme. For the basics, you can take a look at two earlier entries, Basic Show and Hide and Slicker Show and Hide.
For a full-blown plugin solution with lots of options, look no further than Jörn Zaefferer's Accordion Menu. But if you want to try some showing and hiding on your own, read on.
Caveat
In this tutorial, we'll explore a couple ways to show and hide details by clicking on headings. I recognize that there are many ways to mark up the HTML for this sort of thing, and many more ways to write the JavaScript/jQuery. Even the functionality can vary greatly, depending on your needs. Some common variations include:
- each detail shows and hides independently of others
- one and only one detail visible at a time
- either no detail or one detail visible at a time
We'll take a look at the first two variations this time, and the third in a separate entry (so that I can get something posted more quickly).
The Setup
As with any jQuery script, we need to include the jquery.js file and our custom script file in the <head>, like so:
-
<script src="/scripts/jquery.js" type="text/javascript"></script>
-
<script src="/scripts/more-show-hide.js" type="text/javascript"></script>
It's important to include jquery.js before any other files that use it. Also, you may need to change the path to match your site's structure.
For the elements to show and hide, we'll use a simple <h3> / <div> structure:
-
<div class="demo-show">
-
<h3>Title 1</h3>
-
<div>Lorem...</div>
-
<h3>Title 2</h3>
-
<div>Ipsum...</div>
-
<h3>Title 3</h3>
-
<div>Dolor...</div>
-
</div>
Now let's add to that a little CSS to shape things up a bit:
-
.demo-show {
-
width: 350px;
-
margin: 1em .5em;
-
}
-
.demo-show h3 {
-
margin: 0;
-
padding: .25em;
-
background: #bfcd93;
-
border-top: 1px solid #386785;
-
border-bottom: 1px solid #386785;
-
}
-
.demo-show div {
-
padding: .5em .25em;
-
}
Finally, we can get to the scripting.
Option 1: Independent
Remember, this is the option that allows each detail section to be shown or hidden independently of the others. It's also the easiest of the three to accomplish.
The key method we'll be using here is .slidetoggle(), an excellent little effect that slides the matching elements down when they are hidden and slides them up when they are visible. But before we do that, let's make all of the detail sections hide when the DOM is ready:
Line 2 gets every <div> that is a child of the first <div class="demo-show"> and hides them. I'm using :eq(0) here because I'll be showing two show-hide examples that use the same class, but we're taking the examples one at a time.
Now, we can bind a click handler to each <h3> that is a child of <div class="demo-show">. You can see this in line 3 below:
All that's left is to drop the .slidetoggle() method inside the click method. Since we know that each <div> that we want to toggle appears next to each <h3> that might be clicked, we can use the handy .next() method (line 4):
-
});
-
});
I used the "fast" option for the duration of the slide, but we also could haved used "slow" or "normal" or a numeric value for the number of milliseconds.
Try out the demo. See how a click on each <h3> will show or hide the next <div>, independent of the others:
Title 1
Title 2
Title 3
Option 2: One and Only
Let's move on now to the scenario in which we want one detail <div> at all times, but no more than one. The first thing we'll need to change for this one is the line that hides all of the child <div>s of <div class="demo-show">. We'll make it hide all but the first <div>:
Again, we add an :eq() to the containing <div> selector, this time with 1 as the index, because we want our second demo (and because JavaScript numbering starts at zero).
Next, we add the same click handler for the <h3> elements, but this time we need to change the effects that take place within it:
Line 4 above slides down the <div> that follows the clicked <h3> by using $(this).next(), but only if that <div> is hidden (:hidden). Also, now that we've chained .next() onto $(this), we've changed the context to that following <div>. So then in line 5 when we refer to .siblings(), we're actually getting the siblings of the <div>. Since out of all the siblings we only want to slide up the slides up the ones that are visible <div>s, we use .siblings('div:visible').
Give demo #2 a whirl:
Title 1
Title 2
Title 3
There you have it—two fairly straightforward examples of showing and hiding elements on a page. Next time we'll take a look at two ways we can implement the third variation on the showing-and-hiding theme: having either no detail or only one shown at all times.
February 8th, 2007 at 10:41 am
Hi.
Thanks for your tutorials. They are great.
I have a question. I'm trying to use the same technique to create a mouse over (or click) effect where the text appers the same place but differ according to what button you click (over spot you mouseover). My problem is that if I click/mouseover before the first effect (eg. SlideDown) is finish I get the new text AND the old text (that should be hidden .hide()) right after each other and hence breaking the layout...:(
Can I somehow tell the slideDown-function to hide everything else even if another slideDown effect is still taking place...?
Hope it was somewhat clear...;-)
February 8th, 2007 at 2:11 pm
Hi CH,
I'm glad you like the tutorials! I think I understand what you're trying to do, but I'm not certain. You might want to try to put the
.slideDown()in the callback of the.slideUp(). If you can wait a few days, I'll be posting a follow-up entry that describes how to do that.February 8th, 2007 at 5:52 pm
Cool. Ill give it a shot tomorrow at work.
Keep up the great work!
February 8th, 2007 at 11:32 pm
What do you think about image button's, instead of using text link title 1, title 2, it should be possible right? This would essentially create a drop down, or flyout menu, with several links for each of the three buttons. Sounds workable no... It would be great if the flyout slightly overlapped the button to more appear that it was the flyout from the button.
I'm not sure I've seen an accordion menu done with image buttons, I guess that would work too, but left to right fly-in was the requested effect. That I've no idea how to accomplish.
Keep the great stuff coming then jQuery'ers!
February 9th, 2007 at 12:07 pm
Hey Ty,
There's no reason it couldn't be done with image buttons. I think I understand what you're getting at with the fly-out menu idea. You would want the fly-out stuff to overlay everything, right?
February 9th, 2007 at 4:30 pm
Karl, nice tutorial. Good way to demonstrate some more advanced selectors.
Also see the Xpander plugin for another take on this:
http://labs.activespotlight.net/jQuery/Xpander.html
_______
SEAN O
February 9th, 2007 at 11:02 pm
That's a really cool one. Thanks, Sean!
February 13th, 2007 at 10:18 am
their is something wrong... Their is a small but sudden flash before the anim. start.
February 13th, 2007 at 10:35 am
Ah, yes, you're probably using FF2.0 Mac, right? That flicker is due to a bug in an early 1.1.1 build of jquery.js. I just updated to a more recent SVN build and tested it; I don't see the flicker now.
Thank you for bringing this to my attention! Would you mind testing it again and seeing if the flicker still occurs?
February 24th, 2007 at 12:44 pm
thanks Karl
one question about this demo - what does the "gt" in div:gt(0) mean or do? or is that "greater than"?
Also, and this may be outside the scope of this demo, if you had 3 divs stacked, how would you modify this script so that at any one time only 2 divs (at most two) could be open, with the third closing itself?
February 24th, 2007 at 12:58 pm
hmm... the more I think about what I just asked, the more potential problems I see, but the idea was that two adjacent divs would be visible (1 & 2 or 2 & 3). Thanks!
February 24th, 2007 at 2:50 pm
Hi Rolf,
You're correct about
div:gt(0). It gets alldivs that have anindexgreater than 0, or, in other words, alldivs after the first one.About the 2-visible, 1-hidden idea — unfortunately, it is outside the scope of this demo. If you know there will be only three total
div, though, you could easily do it by setting one.click()handler for$('h3:eq(0)')and another one for$('h3:gt(0)'). Hope that helps point you in the right direction.March 10th, 2007 at 11:15 am
Hi Karl,
In your example here, when I hover over the h3 titles I see a little hand icon that indicates I can click on them as if they were links. On my pages I only see a caret.
What do I do to show those hand icons?
Thanks!
March 10th, 2007 at 11:34 am
Well Karl... I just found the answer to my question by reading your next article...

Thanks all the same.
March 10th, 2007 at 7:37 pm
Hey Philip,
Glad to see that you found what you were looking for. Cheers!
March 15th, 2007 at 11:59 am
[...] Read more Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. [...]
March 15th, 2007 at 2:18 pm
Hi,
I can't seem to get the following to work:
$('input[@type=checkbox]').each(function(i) {
this.hide();
});
or
$('input[@type=checkbox]').each().hide();
Are there limitations to what can be shown and hidden?
March 15th, 2007 at 7:51 pm
Hi Rob,
Your first example won't work because you are trying to attach the referenced DOM nodes to the
.hide()method by usingthis. You need to wrap it in the jQuery constructor,$(). So, your code would look like this:However, you can do it much more simply than that. Because jQuery has implicit iteration, you can write this to hide all of the checkboxes:
$('input[@type=checkbox]').hide()One more thing: jQuery provides a special pseudo-class for checkboxes, making the code even tighter:
$('input:checkbox').hide()March 30th, 2007 at 9:43 am
I have a question, and i think i am missing something in my page, but i cant get this to work at all. the H1 stays in place and so does the div?
Why is this, i am linking to the jquery 1.1.2 js file?
March 30th, 2007 at 10:00 am
Hi nOObie,
I'd love to help you, but I'm not sure where to begin. Would you mind posting an example page somewhere and sending me a link to it? You can send email to my first name at this domain name.
March 31st, 2007 at 6:50 am
Thanks karl - i had all but given up ... you have mail
March 31st, 2007 at 1:04 pm
No prob, n00bie. You have a reply.
For anyone else who might be following this thread, the problem was that n00bie wasn't using the correct path to include his jquery.js file. It should work fine once he changes that.
April 7th, 2007 at 11:50 am
I used it in my blog. Thanks.
April 9th, 2007 at 3:36 pm
What do you need to do to update the class of the h3 once it's opened (such as class="opened")...
I'm thinking I could use this with CSS to apply an "up" arrow image when opened and a "down" arrow when closed... thanks!
April 9th, 2007 at 4:16 pm
Hi Andy,
That's a great idea, and very easy to implement. Taking the second example above, we would just have to add a
.toggleClass()method like so:Then, for the CSS, you would have something like this:
Hope that helps.
April 9th, 2007 at 4:21 pm
Sweet... I'm a total JavaScript noob (but want to learn)... I poked around and found "addClass" and I thought "if they had a toggleClass, I'd be in business"
And whaddaya know?! I found toggleClass and it was exactly what I was after!
Here's what I ended up with (I'm using a 'span' with a class of 'pull' instead of an 'h3'):
$(document).ready(function() {
$('div.demo-show:eq(0)> div').hide();
$('div.demo-show:eq(0)> span').click(function() {
$(this).next().slideToggle('fast');
$("span.pull").toggleClass("opened");
});
});
I'm definitely a jQuery fan now!
April 11th, 2007 at 12:36 pm
This is perfect. Let's say you wanted a link at the top of the page, though, that would show all the divs at once; i.e. an "Expand All" link. Unfortunately, I have no idea what I'm doing - could someone point me in the right direction? Thank you!
April 11th, 2007 at 1:01 pm
Hi Jessica,
When you say "link," do you just mean a clickable element—something like the
<h3>in my examples? Also, do you want it to be ale to "Collapse All" after all of the<div>s have been expanded?Well, I'll assume that the answer to both questions is "yes." Just to simplify things here, I'll give the clickable element an
idof "toggle-all" and keep the same class as in the examples for the items to be expanded or collapsed:If you need the clickable element to be a true link (
<a>) for some reason, just putreturn false;in a line right after each$(this).text(...);line.Hope that helps.
April 11th, 2007 at 2:12 pm
Thanks Karl! That works beautifully. Yes, I only meant a clickable element, not necessarily an < a > - you can see how set in my HTML ways I am. Now, since I'm using the method you and Andy described above where the opened and closed divs have separate classes, this is what I ended up with:
$(document).ready(function() {
$('div.subContents:eq(0)> div').hide();
$('div.subContents:eq(0)> h3').click(function() {
$(this).toggleClass('opened').next().slideToggle('normal');
});
$('#toggle-all').toggle(function() {
$('div.subContents > div:hidden').slideDown('normal');
$('div.subContents:eq(0)> h3').toggleClass('opened');
$(this).text('Collapse All');
}, function() {
$('div.subContents > div:visible').slideUp('normal');
$('div.subContents:eq(0)> h3').toggleClass('opened');
$(this).text('Expand All');
});
});
I'm so glad I found your site - thanks, and keep up the good work!
April 19th, 2007 at 7:00 am
Great tutorial thanks. Been using Rico Accordians before, but this is much more elegant and simple. Much prefer the way it handles CSS and DIVs too.
jQuery rocks!
April 23rd, 2007 at 10:58 pm
Karl,
Great examples - thanks for paving the way.
I was wondering if anyone out there has figured out how to "maintain state" with this script? What I mean is, while a div is visible (expanded), refresh the page and have that div still visible.
I am asking because I have a popup window that adds a record to the database, then closes. When I refresh the parent page, it closes all of the divs.
Thanks for any ideas!
April 25th, 2007 at 11:48 pm
Hi Dave,
Klaus Hartl's Cookie plugin might do the trick. You can find it here.
May 17th, 2007 at 5:09 am
Hi Karl,
Great tutorial thanks. Have tried so many things that have unclear tutorials but this worked straight off the bat.
One question how are you stopping the page from jumping to the top when you click a toggle link that expands? On your toggle links the page stays at the same scroll position but pushes the contents downwards, when i have used the toggle the page view automatically scrolls back to the top.
May 17th, 2007 at 7:34 am
Hi Oly,
Glad you like the tutorial! I'm guessing the "scrolls back to the top" behavior you described happens because you're using something like
<a href="#">for the click event (I used<h3>). To prevent the default behavior from occurring, just addreturn false;after the toggle line.Let me know if that works for you.
May 28th, 2007 at 3:35 pm
Hi there
Thanks for the good ideas!
I just wonder, how I can pass a variable with a Link that toggles a div-container that contains a form.
Let's say I have a list of items and I want to offer a form to edit the records, how can I pass e.f. the id of a record to the form in the toggable div?
It does not work with just
<a href="#?id=2" id="togglediv">My entry</a>Any hints on this?
Thanks a lot for any info!
Cheers, QT
June 13th, 2007 at 2:19 pm
Hi Karl, awesome stuff you got on your website here. Couldn't thank you enough for all the info
I have to say that you write lovely and easy to follow tuts. Everything step by step with a live example, works wonders for me
What I wanted to ask you; in all the examples/tuts you write everything is getting approached in a - *click* on this or that - way. I have built a css menu which works without javascript which I want to replicate with JQuery just to get a feel what it can do for me. But it doesn't work with a click, it works with hover/mouseover. I seem to get stuck at hiding the context menu when hover off of the "main link".
Problem illustrated here http://www.devliegendepijl.nl/test2.htm
As soon as I want to get context menu of - say link6 - just just dissapears when I want to get to it... Any ideas? I think a lot of people would be helped by it, and correct me if I'm wrong but no tutorial -yet- covers a menu like that implementing JQuery?
June 13th, 2007 at 2:37 pm
Hi Bart,
So glad that you're benefiting from the tutorials. I think you're right about my examples favoring the
.click()method. I will try to write one that demonstrates other types of events soon. In fact, your example would be a good one to use. Stay tuned!June 13th, 2007 at 2:41 pm
Karl,
Thanks! That would be cool.
The css menu I referred to in my previous post is the one on the main website btw; http://www.devliegendepijl.nl that way you can see what I'm trying to get at. Staying tuned...
June 13th, 2007 at 3:01 pm
Not a problem. I see that you would like the main nav to be horizontal and the secondary nav to be vertical. That can certainly be done, but I recommend that you start by nesting each secondary
<ul>inside its parent<li>In the meantime, here is some code that should work with your test page:June 13th, 2007 at 3:56 pm
Impressive Karl, you're a big help! In the mean time I've updated the css on the file a little bit. As you can see the code you've provided is working almost as good as I intended now

How should I modify it so that if I hover off on the link1 through 6 anchors the context menu dissapears as well? That's basically the only thing missing right now... Thanks
June 13th, 2007 at 6:20 pm
Hi all. This has been a great intro. I'm trying to adapt this into a comment system. I would like to beable to control "all on/all off" and "individual on/individual off". Think of it as tooltips on crack. However, I'm having a problem getting it to work. Ideally.. I have a picture, i click/mouse over that picture and it toggles on a . This div then contains a picture and another div containing text. These are overlaid with each other so i can have a alpha channel shadow. I cannot get them to react correctly. they can all be turned off/on globally. But only one will function directly and not influence the other. Everything is driven by class attributes; one for the buttons, one for the rollovers. I have tried nesting them in all sorts of ways, but can't seem to get it to react correctly. thoughts? you can find an example at: http://www.punkhaus.com/grab/code/hovertest-help.html help would be greatly appreciated!!!!
June 13th, 2007 at 6:51 pm
Well, per above, it looks like the Divs are very sensitive to "positioning". changing them to relative fixes the issue, but this may impact the extensibility of the solution.
June 15th, 2007 at 11:33 am
Hi all. I've implemented the first variant of accordion menu presented above and it worked properly, but i've noticed that tha h3 tags that contain the "Titles 1/2/3" aren't a link (href). They are h3 tags that work like links (when we pass the mouse on it, it appears tha little "hand").
Can you tell how can i do that ?
I'm noob in this
best regards
June 15th, 2007 at 12:46 pm
http://pogueengineering.dsbworldwide.com/template_navigation43.asp
Can anyone please tell me why my menu looks great in ie but seperates in firefox?
I'm stumped.
BTW..how fun it is to work in jquery. I love it.
Thanks guys I appreciate any help.
Shelley
June 15th, 2007 at 8:46 pm
@Guilherme, check out this quick tip for information on how to set a hover class on anything.
@Shelley, it looks like your HTML isn't valid. You're putting
<div>elements directly inside<dl>elements instead of using<dt>and<dd>elements. The "dl" stands for definition list, so it really should consist of a set of definition terms (dt) and definition data (dd). In your example, though, I would use a nested, unordered list. Also, you're missing a closing</a>tag somewhere, and the style attributes that you've placed into every element should really be pulled out into a separate style sheet. I hope these suggestions don't discourage you. It looks like you have quite a bit of work ahead of you, but there are plenty of HTML and CSS resources and tutorials on the web that can help.June 15th, 2007 at 10:40 pm
Thank you Karl. Although I think I was messing with it when you looked at it, it's not as bad as it seems.:)
But thank you for answering anyways.
Shelley
June 15th, 2007 at 11:20 pm
Hi Shelley, no problem. I took another look and saw that you have two flying pigs in your style sheet. When I deleted them (or commented them), your menu items pulled together. You still shouldn't be using the
<dl>the way they are, but I think that cleaning up the style sheet will fix your problem.June 18th, 2007 at 12:44 pm
Wow..when pigs fly..imagine that.
Thank you so much for your help. Who knew my poor little pigs would cause such a problem.
You're a gem Karl and a darn good teacher. I really enjoy this site and all the tips I get here.
Thanks again!!
Shelley
June 18th, 2007 at 11:02 pm
Ha ha! Well, I'm so glad that you were able to make it work. And I'm glad you like the site. Keep up the good work!
June 21st, 2007 at 2:13 am
Karl,
Great tutorial, and I got the vertical one working just fine, but like Bart I'm having issues with the horizontal version... I look at the example he sent you, as well as the code you sent back to him. I am putting in what I'm using now to see if you might be able to help me fix it.
$(document).ready(function() {
$('#show-hide-one ul').hover(function() {
$(this).addClass('show-hide-hover');
}, function() {
$(this).removeClass('show-hide-hover');
});
$('#show-hide-two> ul').hide();
$('#show-hide-one> ul').click(function() {
$(this).next('ul').slideToggle('fast')
.siblings('ul:visible').slideUp('fast');
});
});
<div class="show-hide-one">
<ul>
<li>In the Press</li>
<li>Testimonials</li>
</ul>
</div>
<div class="show-hide-two">
<ul class="press">
<li>
blah blah blah ...
</li>
</ul>
<ul class="testimonial">
<li>
blah blah blah ...
</li>
</ul>
</div>
I figured with what you already did for Bart this would be easy, but at the moment I cannot get the "blah blah blah ..." to hide, nor does the "In the Press" or "Testimonials" end up clickable. So, once you manage to pick yourself up off the floor because of how easy the solution is, do you think you might be able to help me out?
Thanks again for the tutorial...
June 22nd, 2007 at 1:49 pm
Hi Michael,
I see a couple things here:
ulthat is a child of "show-hide-one" tries to apply effects to sibling elements, but there are none (because there is only oneulinside thatdiv).If you take care of those two things, you should be pretty close to getting things working properly. I hope this helps point you in the right direction.
If you want to clean things up a bit and then send me an email with further questions, I can try to answer them when I get a chance.
June 22nd, 2007 at 3:33 pm
What about remembering the state of the menu after reloading the page?
I have jquery tabs going, and would like to have the last tab be be the active one when user returns to the page (even from with my site)
cookie? jquery.history?
can someone please point me in the right direction?
thanks
June 27th, 2007 at 6:58 pm
Hi, These effects are really cool. But I have problem with second one (Option 2: One and Only). It doesn´t work. And I don´t know why, because the first one works perfectly
Does anybody know, why ?
Thanks o lot.
June 27th, 2007 at 6:58 pm
Hi, These effects are really cool. But I have problem with second one (Option 2: One and Only). It doesn´t work. And I don´t know why, because the first one works perfectly
Does anybody know, why ?
Thanks o lot..
June 27th, 2007 at 7:57 pm
Hi Ondrej, Is the demo not working, or is your implementation of it not working? It works fine for me on Firefox 2 Mac and Internet Explorer 6 Windows. Which browser are you using?
July 11th, 2007 at 12:55 am
This code is really fantastic and very helpful. However I found that some effects using jQuery just don't work in Opera 9...is it just me or isn't jQuery compatible with Opera at all?
July 11th, 2007 at 8:29 am
Hi Fred, jQuery's effects are certainly supposed to work in Opera 9. Sorry to hear that you're having problems with them. I'd be happy to help you troubleshoot, but I think chances are better that you'll get a quick and thorough response if you post a specific question to the jQuery discussion list, with relevant code and possibly a link to a demo page.
July 14th, 2007 at 8:37 am
Hey, I need help with a code variation of your great tutorial.
The html code I need should look like that:
The
div.contentshould disappear, the title and the other divs should stay.I already made some changes in the jquery file (bold):
The code works until
$(this).next, I guess there is a problem because of the new structure and classification.Any proposal to solve this problem??
Thanks in advance, Jonas.
July 15th, 2007 at 3:12 pm
I modified the ideas presented here so I could "simulate" in a GUI what happens when you are using AJAX and there is a delay updating the field. I wanted a focus group to see what the experience will really be like.
http://www.whatbird.com/wwwroot/showhide_slide2.html
I think the code is clear if you view source. Thanks to all the help here.
Mitch
www.mitchwaite.com
August 14th, 2007 at 8:54 am
Very nice thank you - just what I was looking for.
One problem i´m experiencing....this does not work on Safari at all. Is it just me or is that a known drawback of this script. Please excuse me....I´m completely new to this.
However - very nice for my purposes.
August 14th, 2007 at 10:07 am
My appologies...it does work in Safari, but, it is in the open state by default and allows for closing. Is there something to be modified in your example to have it in a closed state as on Firefox and IE ?
Thank you so much for shqaring your knowledge - much appreciated !
August 14th, 2007 at 10:16 am
My appologies...it does work in Safari, but, it is in the open state by default and allows for closing. Is there something to be modified in your example to have it in a closed state as on Firefox and IE ?
One more thing... (sounding like Steve Jobs here). How does one implement more than one of these effects to page elements without creating new DIV´s with different classes. I would like to have more-than-one instance of the same effect on different parts of the same page.
Thank you so much for sharing your knowledge - much appreciated !
August 15th, 2007 at 1:12 am
Hi Quintin,
I just looked at this on Safari 2.0.4, and their initial state was the same as it is in Firefox and IE. Are you running Safari 3? If so, I haven't tested anything yet on that browser, since it's still in beta and it's still buggy, from what I've heard.
Anyway, it's easy to have multiple DIVs with the same kind of showing/hiding. Just remove the ":eq(n)" part of the selector. For example, instead of "div.demo-show:eq(0)", it would be "div.demo-show". Hope that helps.
August 15th, 2007 at 12:22 pm
Alright, I give up. All this code works perfectly but I can't figure out how to make the *last* div the one that's open on page load. In my case I have four items, so the last in line will of course be three because JS starts counting at 0. I still can't figure out how to target that particular div to be open.
I know this is easy. I know I'm missing something really elementary. I'll take my lumps and ask anyhow.
Thanks for an excellent resource.
August 15th, 2007 at 12:55 pm
Hi lrh,
Now, replace this line:
You're doing fine. Take a deep breath.
$('div.demo-show:eq(1)> div:gt(0)').hide();with this one:
$('div.demo-show:eq(1) > div:not(:last)').hide()You'll probably want to modify the "div.demo-show:eq(1)" part, too, to suit your page's HTML.
August 15th, 2007 at 1:25 pm
Ah, excellent. For my application this worked a treat:

$(document).ready(function() {
$('div.folds:eq(0) > div:not(:last)').hide();
$('div.folds:eq(0)> h1').click(function() {
$(this).next('div:hidden').slideDown('fast')
.siblings('div:visible').slideUp('fast')
});
});
The ":not" construct is a bit arcane to say the least, but it worked. Really should be picking up your book any day now
August 15th, 2007 at 1:37 pm
> "The ":not" construct is a bit arcane to say the least, but it worked. "
Yeah, I know what you mean. There are other ways of doing it, too. Since you have four items, you could do this:
$('div.folds:eq(0) > div:lt(3)').hide();The ":lt" part stands for "less than," just as the ":gt" that I used in the original example stands for "greater than." This one isn't as flexible, though. You would have to change it if you added another
<li>to your HTML.You could also use jQuery methods if you'd rather not pack all of the selector syntax into a single set of parens:
$('div.folds:first').children('li').not(':last').hide();"Really should be picking up your book any day now"
Fantastic! I hope you find it helpful.
August 16th, 2007 at 8:30 pm
hello,
i have a tricky IE7 compatibility issue. I've put together an accordion menu that has images in one of it's sections, it works great in FF2 and Safari but the problem is when IE7 tries to collapse the section of the accordion that has images in it, the images don't get masked, they stay on top until the section is collapsed and then they just abruptly disappear:
heres an example:
http://2874086.com/temp/index.html
Here's the code:
$('dl#aCor1:eq(0)>dd').hide();
$('dl#aCor1:eq(0)>dt').mouseover(function(){
$(this).toggleClass('imgVisable').next('dd:hidden').slideDown('slow');
.siblings('dd:visible').slideUp('slow')
});
});
I'm wondering if I'm doing something wrong or if you might know a workaround.
August 19th, 2007 at 7:12 pm
Hi David,
Would you mind posting this question to the jQuery Discussion List over at Google Groups? I think you might have more success in finding someone who can help you with a solution.
August 21st, 2007 at 11:05 am
Is it possible to use slickboxin with tables and tds?
August 21st, 2007 at 5:46 pm
Ok, forget above message. My paths are right to js and jquery works (corner etc). My code is like lrh worote it, but I can't get h3 to be clickable? what am I missing... code is in my webpage to see. Thanks.
August 21st, 2007 at 5:50 pm
thanks for quick help, suddenly it works... jihaa!
August 21st, 2007 at 6:15 pm
Hi jhalmu,
Glad it's working for you now!
August 27th, 2007 at 4:53 am
Karl said: "Hi Quintin,
I just looked at this on Safari 2.0.4, and their initial state was the same as it is in Firefox and IE. Are you running Safari 3? If so, I haven't tested anything yet on that browser, since it's still in beta and it's still buggy, from what I've heard."
Thank you for the reply Karl.
Everything you say helps. Fanatastic job you are doing here. Yes, I am testing on Safari 3 for Windows and it has the initial state reversed (meaning open). Not a major issue for me but just tring to be thourough with the testing. Safari 3 for Mac works fine. I´ll keep an eye on these threads to see if a workaround is developed in future.
Kind regards, Quintin
August 27th, 2007 at 10:15 pm
@Karl
Thanks,
I'll post over there and see if it helps.
I read your book last week by the way, great stuff! I got a way better handle on it thanks to you. Thanks for that, and thanks for this site.
August 27th, 2007 at 10:38 pm
@Quintin,
Glad I could help.One other thing you could try is to add a
display: none;declaration for those elements in your stylesheet. The problem with that approach, though, is that if someone has JavaScript turned off, they'll never get to see those elements on the page.@David,
I really appreciate the kind words about the book (and the site). I hope you don't feel like I'm pushing you aside by sending you to the discussion list. It's just that I'm pretty sure that others have experienced the same issue and therefore may have already discovered a solution.
August 28th, 2007 at 12:17 pm
@Karl
No, it's good that you say that, I'm new to this type of stuff and I recently discovered how valuable it is to be involved in the community discussion (even though I'm still mostly reading others posts). Really a lot of these comments should be posted over there instead so that they may be archived in a central location and that we can all learn from each others mistakes.
September 7th, 2007 at 5:01 am
Great tutorial. I have two questions.
Q.1) I have this function and would like to add the toggleClass('opened') so that i can add an up image. Here is the function.
if (typeof $ == 'function') { $(document).ready(function() { // Assessment Help var scope = $("#assessment div.toggle"); $("div.shDiv", scope).hide(); $("a.toggleLink", scope).wrap('').parent().click(function() { $(this).parent().find('div.shDiv').slideToggle('fast'); return false; }); }); }Q.2) When I print-preview a page that has some content hidden (using the jQuery), in the preview screen that content still remains hidden. In other words javascript is not supposed to run in print-preview mode. I was wondering if there's anything I have to do to with jQuery disable it.
Thanks a lot.
September 14th, 2007 at 3:08 am
Hi, does anybody can help me to make it working in horizontal way?
I really need this,
thanks!
September 18th, 2007 at 7:27 pm
Hi there,
I have a function attatched on the onclick event of a checkbox, that is supposed to replace the text of a div.
function isAlbumHandler() {
var isChecked = document.getElementById('isalbum').checked;
if (isChecked) {
alert("checked");
$("#labelTitleAlbum").replaceWith(" album title <span class=\"requiredField\">*</span >")
} else {
alert("not checked");
$("#labelTitleAlbum").replaceWith(" song title <span class=\"requiredField\">*</span>")
}
}
The alerts work, but the replaceWith not.
If I comment the replaceWith in the else part, the replaceWith in the if part works.
What could be the reason?
tnx
Robert
September 18th, 2007 at 9:50 pm
Hi Robert,
No idea. This is a great question to ask in the jQuery Google Group. It also might help if you point to a demo page or show the HTML that you're using.
September 19th, 2007 at 6:51 am
Hi there,
I figured it out. The "problem" is that replaceWith does not only replace the content of the selector, but it replaces the whole selector. The way I did it the selector disappears and therefore cannot be longer replaced.
WRONG:
RIGHT
Typical case or RTFM, sorry for the question.
It was too late yesterday
greetz
robert
September 19th, 2007 at 1:50 pm
Hey Robert,
Glad to hear that you got it working. Sorry for my unhelpful reply -- feeling a little overwhelmed.
I think I understand what you were trying to do a little better now. You were trying to replace the contents of the selector, right?
You can do the same thing like this:
$('#selector').empty().append('something');or even shorter:
$('#selector').html('something');September 21st, 2007 at 5:12 pm
Hi Karl,
Here's another 'newbie' question: How can I open a particular DIV from a link on another page?
Let's say, I have a number of hidden divs when a page loads, and I want to target them (open the one I need) from a link on another page. I am thinking about adding a class to the div I want to open, but I am not sure how to do this.
Here's a page where I am trying to do this (in my case it's a DL with DT and DD)
Thank you.
September 21st, 2007 at 5:54 pm
...the same question put differently:
My page address ends with page.htm#abc
How can I make the div (or in my case dd that follows dt) with id="abc" visible?
The jquery code for showing/hiding:
September 25th, 2007 at 1:56 pm
Thanks for the excellent tutorial! I tested it and it really works....keep it up
September 25th, 2007 at 1:59 pm
Do you have any other tutorial(s)?
September 26th, 2007 at 11:43 pm
Pretty cool tutorial. I might be needing an accordion (and since I like jQuery) for my next site and was thinking about going with this one.
October 3rd, 2007 at 4:28 pm
I get a flicker when I close up the second item in the Independent example. I'm using jQuery 1.2.1. any idea?
October 15th, 2007 at 11:40 am
[...] Learning jQuery - More showing, more hiding [...]
October 15th, 2007 at 1:54 pm
[...] Learning jQuery - More showing, more hiding [...]
October 16th, 2007 at 1:19 am
[...] Learning jQuery - More showing, more hiding [...]
October 17th, 2007 at 6:35 am
Does anyone know of an accordion that can shuffle? I need to make one that places the clicked element at the bottom of the list, so that you always see all the options at the top?
I made a quick one which used this code
$(document).ready(function(){
$("img.content").hide();
$("a.header").click(function() {
$(".list1").animate({'style': 'position: absolute; top: 30px;'},350);
$(".list2").animate({'style': 'position: absolute; top: 0px;'},350);
$("img.content").slideToggle(250);
$("img.content1").hide();
});
$("img.content1").hide();
$("a.header1").click(function() {
$("img.content1").slideToggle(250);
$(".list2").animate({'style': 'position: absolute; top: 30px;'},350);
$(".list1").animate({'style': 'position: absolute; top: 0px;'},350);
$("img.content").hide();
});
});
But this obviously is very limited, I just wanted to know if anyone can help, or if there are any examples about I can learn from?
October 17th, 2007 at 10:25 am
Is it possible to make wordpress plugin to automaticly make sidebar menu collapsible and expandible?
October 20th, 2007 at 1:35 pm
Karl, Thanks for the excellent work you do on this site. I tried one of your examples shown below and its not working. I know the src for the jquery script is correct since I used it successfully in another test. Many thanks for your help.
October 20th, 2007 at 2:08 pm
Hi Jim,
I'd love to be able to help you with this, but I'll need some more information first. What exactly is not working? Are you seeing a JavaScript error or does it fail silently? Is the CSS styling the elements correctly? Do you have a demo page somewhere that I can see?
Often when something that is working here doesn't work on another site, it has to do with slight changes in the HTML. I wonder if your problem is caused by
:eq(1)in the selector. I used that here to target the second div with a class of "demo-show," but if your page has only one div with that class, you should remove the:eq(1)part.Let me know how that goes.
October 20th, 2007 at 5:57 pm
Karl,
Your suggestion"...remove the :eq(1) part." did the trick.
Many thanks for your expertise and contribution to this site...Jim
October 21st, 2007 at 9:57 am
Karl,
Thank you so much for making this available to everyone.
One quick question--accessibility is a big issue and using the first example above with the added benefit of having the "Expand All/Contract All" add-in you explained in Comment #28, is there something I can do to make this accessible to keyboard users? Any and all suggestions appreciated. Again, thank you for these tutorials. I'd be lost without them!
October 21st, 2007 at 11:22 am
[...] Learning jQuery - More showing, more hiding [...]
October 21st, 2007 at 1:35 pm
[...] Comment on More Showing, More Hiding by 10 Javascript Accordion <b>…</b> [...]
October 21st, 2007 at 3:54 pm
[...] Original post by Cisco Switch News » MCTS Self-Paced Training Kit (Exam 70-528): Microsoft .NET Framewor... [...]
October 30th, 2007 at 12:01 pm
How can I "show all" for printing?
November 3rd, 2007 at 12:53 pm
Hi,
Im sort of a newbie to this sort of thing but i have done a few of these tutorials already and they have helped loads but i seem to be having problems with this one getting it to work and I can't really see what im doing wrong as I'm using the script you have supplied above in order to learn it before appliying it.
http://www.adexusltd.co.uk/dev/capricorn/clients.html
Please could you help been trying to see what is wrong for days and just can't seem to get it to work.
Cheers
Simon
November 3rd, 2007 at 1:45 pm
Hi Simon,
It looks like the references to your scripts are wrong. If you remove the initial slash, they should point to the correct place. For example, change this:
<script src="/scripts/jquery.js" type="text/javascript"></script>to this:
<script src="scripts/jquery.js" type="text/javascript"></script>November 3rd, 2007 at 5:09 pm
Cheers Karl,
Just give that a try but it still doesn't want to work what should the code be for jquery.js?? Might have that wrong i think
Thanks again for the quick response
Simon
November 4th, 2007 at 8:29 pm
Mike,
I didn't hide the content using
display: none.November 5th, 2007 at 9:46 am
Hi again Mike,
Ah, I see. Yes, that makes sense. Thanks for the clarification. At first I thought you were referring to the issue of "graceful degradation." Since the
display: noneis set in the JavaScript, not the stylesheet, all those divs will be visible when JavaScript is turned off. But I hadn't considered the accessibility angle.I must confess to a lack of knowledge of all the ins and outs of accessibility. Do screen readers such as JAWS support JavaScript? In any case, wrapping a link around the h3 is easy enough. We'd also need to add a
return falseat the end of the code inside the onclick.Thanks again for the tip. Very instructive.
November 6th, 2007 at 2:33 pm
Karl,
This page - http://www.quartershoa.org/test_categories1# - is working ok but I'd have to write 7x more jquery code for the full requirement. The content will be filled from a database by a loop routine, including the ids. What jquery technique would I use to return the id that's clicked on to the jquery object so I can eliminate having to write jquery code for each id. Many thanks for your help...Jim
November 6th, 2007 at 6:38 pm
Hi Jim,
Instead of giving each of those divs a unique class, give them a common class (for example, "cat"). They already have a unique id. Then, I'd remove the <div id="cats">, because it seems superfluous and it doesn't even wrap around the first table.
Give a class of "expand" to all the links for which you want to expand content underneath and a class of "collapse" to the ones for collapsing the content. Then you just need to use jQuery's DOM traversal methods to access the div that immediately follows the table in which a link was clicked.
So then your script might look something like this:
November 6th, 2007 at 10:42 pm
Hi Karl,
Your advice on use of Collapse and Expand classes in response to my 11/6 message did the trick! It was a good lesson for me in the power of chaining. Jquery is a powerful tool and, for me, learning it requires an adjustment to the traditional thinking process in solving a problem.
If you were next to me, I'd give you a big hug! You are an invaluable resource, and I greatly appreciate your responsiveness and how generous you are with your time...Jim
November 14th, 2007 at 5:04 am
Hmm, a little tricky to understand for an norwegian newbie like me, but I think mainly understood it.
But I still have a few questions, just to clear out some of my missunderstandings.
To begin with, what is thesecond script for? do I need it?
<code>script src="/scripts/jquery.js" type="text/javascript">
<code>script src="/scripts/more-show-hide.js" type="text/javascript">
and this, where do I put this? somewhere in the <header> right?
<div class="demo-show">
<h3>Title 1</h3>
<div>Lorem...</div>
<h3>Title 2</h3>
<div>Ipsum...</div>
<h3>Title 3</h3>
<div>Dolor...</div>
</div>
And i dont need the css right?
last question, this javascrip thas to be caught inside which tag? And where do i put it?
<code>$(document).ready(function() {
$('div.demo-show:eq(0)> div').hide();
$('div.demo-show:eq(0)> h3').click(function() {
$(this).next().slideToggle('fast');
});
});
November 29th, 2007 at 2:48 pm
Hi Karl,
Thanks for the great work. But is it possible in the second example to hide the already opened div once it's h3 is clicked again?
Thanks
November 29th, 2007 at 5:28 pm
Hi bor,
Yes, take a look at "Option 3: Zero or One" in Accordion Madness.
December 6th, 2007 at 1:06 am
Hi, thanks for the great tutorial.
Im desperate to create a horizontal accordion, does anyone have any examples?
It needs to open and close on click. Many thanks!!!
January 4th, 2008 at 11:22 am
am using jquery
to edit profile page its update the database.but in the view page the old record is displaying this problem is only in IE browser .its woring fine in mozila .am using codigniter....plz help me
January 4th, 2008 at 11:33 am
Hi chenthilf,
I think you'd have more success presenting this problem to the jQuery discussion list. Perhaps you could also provide more detailed information when you post it there.
January 6th, 2008 at 3:00 pm
hello,I have such kind of question...
for example,I have images and divs with ids:
I want to have one button show/hide, which will show or hide only first four divs and images as well...
how can I make this?
January 6th, 2008 at 3:11 pm
Hi dr,
Unfortunately, your comment's code didn't come through. Please read the "important" instructions above the comment field for more information.
February 1st, 2008 at 9:12 pm
I'm having a couple problems which are likely due to my staring at the code too long. Instead of the used in the example code, I'm using a definition list. I'm using the first script example, and trying to do what Jessica did in comment #24, adding an Expand All/Contract All toggle link. However, I'm having several issues with the code (see below) not behaving as I would expect.
The issues are:
1. Hovering over the text doesn't show the text as clickable; in other words, the pointer doesn't change to a hand when hovering over the text. If I click the text, the content does display, but there is no visible way to know the text is clickable.
2. I'm using prepend to create the Expand All/Contract All toggle-all element, and then trying to populate the toggle-all element with the appropriate text.
Here's the script - any ideas what I'm missing?
Here's the markup:
February 2nd, 2008 at 12:25 am
Looks like some of the code didn't make it through. On the line that begins with $("#content, the code should be:
February 24th, 2008 at 11:08 pm
Quick question...
I have the slide working great on my site. The menu is on a Joomla based site. The only problem that I am having is that when viewing certain pages, one of the divs opens on the slide.
None of the links within the slide are linked to these pages.
This is the JS:
$(document).ready(function() {
$('div.demo-show > div').hide();
var hrefParts = location.href.split('=');
var thisPage = hrefParts[hrefParts.length-1];
$('div.demo-show div:has(a[href*=' + thisPage + '])').show();
$('div.demo-show > h2,h3').click(function() {
$(this).next('div').slideDown('fast')
.siblings('div:visible').slideUp('fast');
});
});
This is the CSS:
.demo-show {
width: 219px;
margin: 0px;
}
.demo-show h2 {
margin: 0;
height: 43px;
}
.demo-show h3 {
margin: 0;
height: 30px;
}
a img {border: 0px; }
a:hover img {border: 0px ; }
a:visited img {border: 0px ; }
.demo-show div {
padding: 6px 15px 6px 15px;
background:url("http://www.watchdogproject.us/templates/SCtIR_Template_01/images/Nav/slide_nav.gif") repeat-y;
color: #3e3e3e;
font-size: 10px;
width: 189px;
}
ul.list {list-style-type:none; margin: 0px; padding: 0px; line-height:14px;}
li.bullet {background: transparent url("http://www.watchdogproject.us/templates/SCtIR_Template_01/images/Nav/circle.gif") no-repeat scroll 0px 3px; color:#212121; padding-left:13px; padding-bottom: 4px;}
.demo-show a {font-family: Arial, Helvetica, sans-serif; font-weight: bold; font-size: 10px; color: #3e3e3e; text-decoration: none;}
.demo-show a:link {font-weight: bold; color: #3e3e3e; text-decoration: none; }
.demo-show a:hover {font-weight: bold; color:#791e00; text-decoration: none;}
.demo-show p {margin-top: 10px; color:#04224f; line-height:14px; font-size: 10px;}
element.style {
poisiton: static;
}
Last thing, it works perfectly on a non-Joomla site.
February 26th, 2008 at 8:58 pm
Has anyone figured out how to disable jquery (show all hidden elements) when printing the page? I believe this question was raised a couple times earlier in this post.
February 26th, 2008 at 9:01 pm
Sorry for the double post... this goes with my post above. Here is the code I'm using and would like to "disable" for print:
March 12th, 2008 at 10:35 am
To create on function in javascript. When we write tag in body,then one rouend corner square is automatically display in body.
March 19th, 2008 at 7:14 am
slideToggle("slow") in jquery-1.2.3.min flickers on IE7 (7.0.6000.16609, Vista), whereas it works perfectly on FF2 (2.0.0.12, Vista):
Just before sliding down, the DIV fully displays for a split second. The same when on sliding up, but here the DIV is fully displayed for a split second just after it has finished sliding. Additionally, the contents of the DIV shifts down after the DIV has been fully opened. Here's a test page:
March 20th, 2008 at 3:39 am
This is a great tutorial and it safe me from getting some to code this for me
March 27th, 2008 at 7:00 am
Hi there,
Does anyone know of a way to have an image that when you rollover it, it fades into another image?
Additionally, I would like the fade to be fast onmouseover and slow onmouseout.
I have tried this lots of times and the issue that I keep getting is that I have to let the fades complete before you can initiate the fade again. In other words if I set onmouseout fade to 'slow' if I rollover the image again before this 'slow' fade has completed, nothing happens.
I would like to know if there is a way to interrupt the fade so that if it half complete, the fadeOut is stopped and immediately starts the fadeIn
My pathetic attempts are:
Here!
And the .js file is:
Here!
It is cluncky, to say the least.
ANY help would be great.
Thanks.
March 27th, 2008 at 9:37 am
Hi Nat,
Have you tried checking to see if the element is already animated? Given your HTML, it would look something like this:
Also, note that I used class names instead of repeating the code for each id.
March 27th, 2008 at 10:40 am
Thanks for that.
I replied to your jQuery Google Groups message too.
I posted there because I thought that more help was better than less!
Can I ask, what does:
$('> .fade',this);
this part do?
Nat.
March 27th, 2008 at 9:35 pm
Hi Nat,
That selects the element with a class of "fade" that is a direct child of the hovered element. It could be written this way as well:
$(this).children('.fade')March 28th, 2008 at 6:50 am
Hi there Karl,
Thanks for all the help with this.
That was great how you used the classes to cut out lots of code, thanks.
I've got to sort this 'cos my mates all think that jQuery CANNOT do this. They think that I will end up having to resort to doing this the long way round with JavaScript and using 'setInterval' and 'clearInterval'.
I want to prove them wrong!
The big sticking point though, is that I can't get the .hover to interupt the fade out.
I have currently set the fade out to 6000 so that it is clear whether or not the fade out can be interupted by placing the mouse over the images.
Here is what it looks like.
Here is .js with lots of commented out attempts.
The
if (!$fade.is(':animated')does not seem to holt the animation.I am at a complete loss.
I would like it so that onmouseover the alternative image (.out) fades in, and onmouseout this same image fades out. The catch here though is making it so that if you interupt the fade part of the way through, it stops it (.stop()?) and fades in the other direction.
Hopefully..... Much appreciated.
March 30th, 2008 at 2:07 pm
Hi Nat,
I think I have something for you. I changed all of the fade times to 3000 so you can see it working both ways:
This worked on the test page that I put together, so I hope it works for you, too.
March 30th, 2008 at 5:55 pm
That is SO cool.
Thanks. In a strange twist of fate I bought your 'jQuery Reference Guide' today. I have not got it yet, but at least you and Jonathan can know that in this corner of the world there is a man who is truly grateful.
I have, needless to say, stuck it to my mates who said that this was beyond jQuery. They think that you are too clever!
Again, many thanks for sorting this out.
April 10th, 2008 at 7:07 am
I'm using this code:
$(document).ready(function() {
$('div.demo-show > div').hide();
var hrefParts = location.href.split('=');
var thisPage = hrefParts[hrefParts.length-1];
$('div.demo-show div:has(a[href*=' + thisPage + '])').show();
$('div.demo-show > h4,h5').click(function() {
$(this).next('div').slideDown('fast')
.siblings('div:visible').slideUp('fast');
});
});
The link to the test site is:
http://www.ctbiobus.org/TestSite/BioBus/index.php?page=staff
The problem:
It happens in several cases, but for instance, click on "About", then click on "sponsors", the menu opens in two places. I was debugging it, and it happens in places where the sub menu links do not point to the same place.
Any suggestions?
April 10th, 2008 at 11:38 pm
Hi Dustin,
I think you're seeing that problem because both of those hrefs have "sponsors" in them. One has
?page=sponsorswhile the other has?page=sponsorships. To avoid the problem, try usinghref$=rather thanhref*=.Hope that helps.
April 24th, 2008 at 12:00 pm
Hi,
Great script and works well, but I have a question
I have used your script to create a menu for one of our new sites. You can see it on http://lic.iuvo.tv/ . The problem is that only Undergraduate and Postgraduate menu items have sub-menus.
I am using the following structu