views:

1495

answers:

3
+1  Q: 

Open/Close Icons

I'm doing some shennanigans with jQuery to put little plus/minus icons next to my expanders. Its similar to the windows file trees, or firebugs code expanders.

It works, but its not specific enough.

Hopefully this makes sense...

$('div.toggle').hide();//hide all divs that are part of the expand/collapse
$('ul.product-info li a').toggle(function(event){
  event.preventDefault();
  $(this).next('div').slideToggle(200);//find the next div and sliiiide it
  $('img.expander').attr('src','img/content/info-close.gif');//this is the part thats not specific enough!!!
},function(event) { // opposite here
  event.preventDefault();
  $(this).next('div').slideToggle(200);
  $('img.expander').attr('src','img/content/info-open.gif');
});


<ul class="product-info">
  <li>
    <a class="img-link" href="#"><img class="expander" src="img/content/info-open.gif" alt="Click to exand this section" /> <span>How it compares to the other options</span>
  </a>
  <div class="toggle"><p>Content viewable when expanded!</p></div>
  </li>
</ul>

There are loads of $('img.expander') tags on the page, but I need to be specific. I've tried the next() functionality ( like I've used to find the next div), but it says that its undefined. How can I locate my specific img.expander tag? Thanks.

EDIT, updated code as per Douglas' solution:

$('div.toggle').hide();
      $('ul.product-info li a').toggle(function(event){
       //$('#faq-copy .answer').hide();
          event.preventDefault();
       $(this).next('div').slideToggle(200);
                $(this).contents('img.expander').attr('src','img/content/info-close.gif');
       //alert('on');
      },function(event) { // same here
       event.preventDefault();
       $(this).next('div').slideToggle(200);
                $(this).contents('img.expander').attr('src','img/content/info-open.gif');
            });
+1  A: 

Have you tried the .siblings() method?

$(this).siblings('img.expander').attr('src','img/content/info-close.gif');
Nathan Long
thanks,no doubt my fault, but I failed to get that to work myself...
Pickledegg
Probably because the img.expander is a child of the clicked $(this), not a sibling.
Pistos
+2  A: 

How about making your click event toggle a CSS class on a parent item (in your case, perhaps the ul.product-info). Then you can use CSS background properties to change the background image for a <span> instead of using a literal <img> and trying to fiddle with the src. You would also be able to accomplish a showing and hiding on your div.toggle's.

ul.product-info.open span.toggler {
   background-image: url( "open-toggler.png" );
}
ul.product-info.closed span.toggler {
   background-image: url( "closed-toggler.png" );
}

ul.product-info.open div.toggle {
   display: block;
}
ul.product-info.closed div.toggle {
   display: hidden;
}

Using jQuery navigation/spidering functions can be slow when the DOM has many items and deep nesting. With CSS, your browser will render and change things more quickly.

Pistos
ahah... seems like a tidy solution. Will have a look.
Pickledegg
+5  A: 
$(this).contents('img.expander')

This is what you want. It will select all of the nodes that are children of your list. In your case, all of your images are nested inside of the list element, so this will filter out only what you want.

Douglas Mayle
Works a treat! You're a star.
Pickledegg