views:

204

answers:

2

Okay, I feel like a bit of a 800 pound gorilla trying to thread a needle when it comes to jQuery. I need a script that will preform a simple show/hide (preferably with a nice sliding in and out) on a list.

My markup looks like this:

          <div id="themes">
          <h2>Research Themes</h2>
            <ul>
              <li class="tier_1"><a href="">Learn about our approach to the <strong>environment</strong></a>
                <ul class="tier_2 hide">
                  <li><a href=""><em>How we are tying this all together</em></a></li> 
                  <li><a href=""><strong>Project:</strong> Solor Powered Biofactories</a></li> 
                  <li><a href=""><strong>Project:</strong> Cleaning Water with Nature</a></li>
                  <li><a href=""><strong>Project:</strong> Higher Efficiency Solar Technology</a></li>
                </ul>
              </li>
              <li class="tier_1"><a href="">Learn about our approach to <strong>human health</strong></a>
                <ul class="tier_2 hide">
                  <li><a href="">Project name numero uno goes here</a></li> 
                  <li><a href="">Project name numero dos goes here</a></li>
                  <li><a href="">Project name numero tres goes here</a></li>
                </ul>
              </li>
              <li class="tier_1"><a href="">Learn about our approach to <strong>national defense</strong></a>
                <ul class="tier_2 hide">
                  <li><a href="">Project name numero uno goes here</a></li> 
                  <li><a href="">Project name numero dos goes here</a></li>
                  <li><a href="">Project name numero tres goes here</a></li>
                </ul>
              </li>
            </ul>
          </div><!-- // end themes -->

You can see that each nested ul has a class of "tier_2" and "hide". Ideally when the li they are nested within ("li.tier_1") is clicked it's child ul will have the hide class removed and the li's contained within will slideout, but at the same time should check all the other ul.tier_2's and be sure they get a hide class--so only one theme can be expanded at a time.

I set up a sandbox to try some things: http://jsbin.com/odete/3

My JS looks like this:

$(function(){

$(".tier_1 a").each(function(i,o){
  $(this).click(function(e){
    e.preventDefault();
    $(this).addClass("show").siblings("ul").removeClass("show");
    $("ul.tier_2:eq("+i+")").show().siblings("ul.tier_2").hide();
  });
});

});

Totally a dumb way to do this, I am sure. But I based it off another script and it does work "a little bit" as you can see in the sandbox.

If one of you mean hands at jQuery might be so inclined to take a peek I'd be very grateful. If you could also advise on how to have the transitions slideIn and Out that would also be fantastic!

+2  A: 

Replace your jQuery code with:

$(function(){
  $(".tier_1 > a").click(function() {
    var currentList = jQuery(this).parents('li').find('.tier_2');
    $(currentList).slideToggle();
    jQuery(this).parents('ul').find('.tier_2').not(currentList).slideUp();
    return false;
  });
});​

Haris
Works like a charm brother, understand why too. Simple. Only other question is a way to re-hide the same tier_2 list if it is reclicked. I.E. someone clicks, see's the list and then reclicks the same one. Right now it just bounces again?
Fuego DeBassi
Oh and BTW. THANK YOU.
Fuego DeBassi
Edited. Check the answer.
Haris
@Banderbash: if this is the correct answer, mark the it as such (the tick under the answer votes). Good answer btw, +1
Alastair Pitts
http://jsbin.com/odete/3 The updated code seems to break it all together?
Fuego DeBassi
@Banderdash, I have tested the code and it is working. http://jsbin.com/odete/4/edit
Haris
You should have a look at http://api.jquery.com/toggle/
TehOne
Hmm. Quite right, on the sandbox it is working. Thanks to much guys!
Fuego DeBassi
One more thing--not to be nit picking something as insanely helpful as this snippet has been, but I am noticing that in IE 7 the contents are not visible when clicked. The slide occurs, but no contents shown. Yet when I just remove the "hide" class manually and check they appear. Any thoughts?
Fuego DeBassi
A: 

Alternatively, you can use:

$(".tier_1 a").each(function(i,o){
  $(this).click(function(e){
    e.preventDefault();
    var wasShowing = $(this).siblings('ul:visible').length > 0

    // hide everything... 
    $('.tier_2').hide();
    // give everything the proper classes (hide, since we just hid everything)
    $(".show").addClass('hide').removeClass("show");

    // if the tier was not expanded, then show it... 
    // otherwise leave it hidden
    if (!wasShowing) { 
      $(this).siblings('ul').show();
      $(this).removeClass("hide").addClass("show");
    } 
  });});

This is really potentially slow on a large page, since it grabs all ".tier_2" objects.

JBristow