More Showing, More Hiding

read 231 comments

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:

  1. each detail shows and hides independently of others
  2. one and only one detail visible at a time
  3. 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:

HTML:
  1. <script src="/js/jquery.js" type="text/javascript"></script>
  2.   <script src="/js/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:

HTML:
  1. <div class="demo-show">
  2.   <h3>Title 1</h3>
  3.   <div>Lorem...</div>
  4.   <h3>Title 2</h3>
  5.   <div>Ipsum...</div>
  6.   <h3>Title 3</h3>
  7.   <div>Dolor...</div>
  8. </div>

Now let's add to that a little CSS to shape things up a bit:

CSS:
  1. .demo-show {
  2.   width: 350px;
  3.   margin: 1em .5em;
  4. }
  5. .demo-show h3 {
  6.   margin: 0;
  7.   padding: .25em;
  8.   background: #bfcd93;
  9.   border-top: 1px solid #386785;
  10.   border-bottom: 1px solid #386785;
  11. }
  12. .demo-show div {
  13.   padding: .5em .25em;
  14. }

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:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show:eq(0)> div').hide();  
  3. });

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:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show:eq(0)> div').hide();  
  3.   $('div.demo-show:eq(0)> h3').click(function() { });
  4. });

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):

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show:eq(0)> div').hide();  
  3.   $('div.demo-show:eq(0)> h3').click(function() {
  4.     $(this).next().slideToggle('fast');
  5.   });
  6. });

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

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 2

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 3

Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

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>:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show:eq(1)> div:gt(0)').hide();  
  3. });

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:

JavaScript:
  1. $(document).ready(function() {
  2.   $('div.demo-show:eq(1)> div:gt(0)').hide();  
  3.   $('div.demo-show:eq(1)> h3').click(function() {
  4.     $(this).next('div:hidden').slideDown('fast')
  5.     .siblings('div:visible').slideUp('fast');
  6.   });
  7. });

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

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 2

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Title 3

Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

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.

HTTP/2 will change the web as we know it. Find out why.
Provided by
comment feed

231 comments

  1. CH

    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...;-)

  2. 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.

  3. CH

    Cool. Ill give it a shot tomorrow at work.

    Keep up the great work!

  4. Ty

    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!

  5. 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?

  6. 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

  7. That's a really cool one. Thanks, Sean!

  8. enquest

    their is something wrong... Their is a small but sudden flash before the anim. start.

  9. 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?

  10. rolfsf

    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?

  11. rolfsf

    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!

  12. Hi Rolf,
    You're correct about div:gt(0). It gets all divs that have an index greater than 0, or, in other words, all divs 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.

  13. Philip

    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!

  14. Philip

    Well Karl... I just found the answer to my question by reading your next article...
    :-)
    Thanks all the same.

  15. Hey Philip,

    Glad to see that you found what you were looking for. Cheers!

  16. Rob Callahan

    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?

  17. Hi Rob,

    Your first example won't work because you are trying to attach the referenced DOM nodes to the .hide() method by using this. You need to wrap it in the jQuery constructor, $(). So, your code would look like this:

    $('input[@type=checkbox]').each(function(i) {
      $(this).hide();
    });

    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()

  18. n00bie

    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?

  19. 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.

  20. n00bie

    Thanks karl - i had all but given up ... you have mail :D

  21. 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.

  22. Web

    I used it in my blog. Thanks.

  23. 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!

  24. 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:

    $(document).ready(function() {
      $('div.demo-show:eq(1)> div:gt(0)').hide();
      $('div.demo-show:eq(1)> h3').click(function() {
            $(this).toggleClass('opened').next('div:hidden').slideDown('fast')
    	.siblings('div:visible').slideUp('fast');
      });
    });

    Then, for the CSS, you would have something like this:

    .demo-show h3 {
      padding-left: 20px;
      background: url(/images/closed.gif) no-repeat 2px 50%;
    }
    .demo-show h3.opened {
      background-image: url(/images/opened.gif);
    }

    Hope that helps.

  25. 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!

  26. Jessica

    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!

  27. 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 id of "toggle-all" and keep the same class as in the examples for the items to be expanded or collapsed:

    $('#toggle-all').toggle(function() {
      $('div.demo-show > div:hidden').slideDown('fast');
      $(this).text('Collapse All');  
    }, function() {
      $('div.demo-show > div:visible').slideUp('fast');
      $(this).text('Expand All');
    });

    If you need the clickable element to be a true link (<a>) for some reason, just put return false; in a line right after each $(this).text(...); line.

    Hope that helps.

  28. Jessica

    Thanks Karl! That works beautifully. Yes, I only meant a clickable element, not necessarily an &lt a &gt - 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!

  29. 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!

  30. 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!

  31. Hi Dave,

    Klaus Hartl's Cookie plugin might do the trick. You can find it here.

  32. Oly

    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.

  33. 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 add return false; after the toggle line.

    Let me know if that works for you.

  34. QT

    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

  35. Bart

    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?

  36. 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!

  37. Bart

    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... :)

  38. 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:

    $(document).ready(function(){
      $('#mainnav a').each(function(index) {
        $(this).mouseover(function() {
          $('#subnav ul').eq(index).show().siblings().hide();
        });
      });
      $('#subnav ul').hide().hover(function() {
       $(this).addClass('active');
      }, function() {
        $(this).removeClass('active').hide();
      });
    });
  39. Bart

    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 :)

  40. justin

    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!!!!

  41. justin

    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.

  42. Guilherme

    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 :P

    best regards

  43. Shelley

    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

  44. @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.

  45. Shelley

    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

  46. 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.

  47. Shelley

    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

  48. 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!

  49. Michael

    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...

  50. Hi Michael,
    I see a couple things here:

    1. Your jQuery code is trying to select the elements by their ID (by using "#"), but the HTML uses classes for those elements.
    2. Your click handler for the ul that is a child of "show-hide-one" tries to apply effects to sibling elements, but there are none (because there is only one ul inside that div).

    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.

  51. sean

    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

  52. Ondrej

    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.

  53. Ondrej

    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..

  54. 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?

  55. Fred

    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?

  56. 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.

  57. jonnythebird

    Hey, I need help with a code variation of your great tutorial.
    The html code I need should look like that:

    <div class="demo-show">
    
      <div class="node">
        <h3>Title 1</h3>
        <div>Something I threw together...</div>
        <div class="content">Lorem...</div>
      </div>
    
      <div class="node">
        <h3>Title 2</h3>
        <div>Something I threw together...</div>
        <div class="content">Ipsum...</div>
      </div>
    
      <div class="node">
        <h3>Title 3</h3>
        <div>Something I threw together...</div>
        <div class="content">Dolor...</div>
      </div>
    
    </div>

    The div.content should disappear, the title and the other divs should stay.
    I already made some changes in the jquery file (bold):

    
    $(document).ready(function() {
      $('div.demo-show> > div.content:gt(0)').hide();
      $('div.demo-show> > h3').click(function() {
        $(this).next('.content:hidden').slideDown('fast')
          .siblings('div:visible').slideUp('fast');
      });
    });
    

    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.

  58. 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
    http://www.mitchwaite.com

  59. Quintin

    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.

  60. Quintin

    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 !

  61. Quintin

    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 !

  62. 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.

  63. lrh

    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.

  64. Hi lrh,
    You're doing fine. Take a deep breath. :) Now, replace this line:
    $('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.

  65. lrh

    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 :)

  66. > "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.

  67. 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.

  68. 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.

  69. Is it possible to use slickboxin with tables and tds?

  70. 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.

  71. thanks for quick help, suddenly it works... jihaa!

  72. Hi jhalmu,
    Glad it's working for you now!

  73. Quintin

    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

  74. @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.

  75. @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.

  76. @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.

  77. Jay Cee

    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.

  78. Chango

    Hi, does anybody can help me to make it working in horizontal way?
    I really need this,
    thanks!

  79. Robert

    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

  80. 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.

  81. Robert

    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:

    
    if (condition) {
    $(#selector).replaceWith("something");
    } else {
    $(#selector).replaceWith("otherthing")
    }
     

    RIGHT

    
    if (condition) {
    $(#selector).replaceWith("<div id=\"selector\">something</div>");
    } else {
    $(#selector).replaceWith("<div id=\"selector\">otherthing</div>");
    }
     

    Typical case or RTFM, sorry for the question.
    It was too late yesterday ;-)

    greetz

    robert

  82. 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');

  83. Victor

    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.

  84. Victor

    ...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:

    
    		$(document).ready(function(){
    		$("dd:not('.open')").hide();
    		$("dt a").click(function(){
    			$("dd:visible").slideUp("slow");
    			$(this).parent().next().toggle("slow");
    			return false;
    		});
    	});
    
    
  85. Thanks for the excellent tutorial! I tested it and it really works....keep it up

  86. Do you have any other tutorial(s)?

  87. 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.

  88. jack

    I get a flicker when I close up the second item in the Independent example. I'm using jQuery 1.2.1. any idea?

  89. 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?

  90. Is it possible to make wordpress plugin to automaticly make sidebar menu collapsible and expandible?

  91. Jim Cllins

    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.

    Untitled Document
    
    .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;
    }
    
    
    $(document).ready(function() {
      $('div.demo-show:eq(1)> div:gt(0)').hide();
      $('div.demo-show:eq(1)> h3').click(function() {
    	$(this).next('div:hidden').slideDown('fast')
    	.siblings('div:visible').slideUp('fast');
      });
    });
    
    
    
    
    
      Title 1
      Lorem...
      Title 2
      Ipsum...
      Title 3
      Dolor...
    
    
    
    
  92. 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.

  93. Jim Collins

    Karl,

    Your suggestion"...remove the :eq(1) part." did the trick.

    Many thanks for your expertise and contribution to this site...Jim

  94. Ruby

    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!

  95. How can I "show all" for printing?

  96. 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

  97. 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>

  98. 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

  99. Mike,
    I didn't hide the content using display: none.

  100. 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: none is 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 false at the end of the code inside the onclick.

    Thanks again for the tip. Very instructive.

22 Pings

  1. [...] Read more Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. [...]

  2. [...] Learning jQuery - More showing, more hiding [...]

  3. [...] Learning jQuery - More showing, more hiding [...]

  4. [...] Learning jQuery - More showing, more hiding [...]

  5. [...] Original post by Cisco Switch News » MCTS Self-Paced Training Kit (Exam 70-528): Microsoft .NET Framewor... [...]

  6. [...] two files for this. jQuery itself and the Dimensions plugin. Then using the technique described at Learning jQuery, we need to make a call to show and hide the list [...]

  7. [...] two files for this. jQuery itself and the Dimensions plugin. Then using the technique described at Learning jQuery, we need to make a call to show and hide the list [...]

  8. [...] 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): [...]

  9. [...] Learning jQuery – More showing, more hiding [...]

  10. [...] in Chronological Order by WPGuy 10 Ways to Customize Thesis and Enhance Your Blog by Matt Flies More Showing, More Hiding by Learning [...]

  11. [...] I would like to do is to incorporate this jquery tutorial into this list structure so that only one of the nested <ul>’s is [...]

Sorry, but comments for this entry are now closed.