Reputation: 807
The code below will show / hide a div on click. It works perfectly for the first div listed, but doesn't work for any of the others. Is there a way to have the function apply to all the elements with the same class names? It should, of course, only open / close the div to which it's being applied (i.e., clicking on the Second Div toggle button should only open / close the Second Div, and not the others...)
// this is the markup
<div class="collapsible-item">
<div class="collapsible-item-title">
<div class="item-title-header"> First Div</div>
<img src="/images/expand.png" alt="Expand this section" class="toggle-button">
</div>
</div>
<div style="display: none;" class="togglethis">
Cras cursus sodales odio, quis consectetur felis ultricies in.
</div>
</div>
<div class="separator"></div>
<div class="collapsible-item">
<div class="collapsible-item-title">
<div class="item-title-header"> Second Div</div>
<img src="/images/expand.png" alt="Expand this section" class="toggle-button">
</div>
</div>
<div style="display: none;" class="togglethis">
Cras cursus sodales odio, quis consectetur felis ultricies in.
</div>
</div>
<div class="separator"></div>
<div class="collapsible-item">
<div class="collapsible-item-title">
<div class="item-title-header"> Third Div</div>
<img src="/images/expand.png" alt="Expand this section" class="toggle-button">
</div>
</div>
<div style="display: none;" class="togglethis">
Cras cursus sodales odio, quis consectetur felis ultricies in.
</div>
</div>
And, this is the jQuery:
$(document).ready(function () {
$('.toggle-button').toggle(
function() {
$(this).attr('src', '/images/collapse.png');
$(this).parent().siblings('.togglethis').slideToggle('slow');
},
function() {
$(this).attr('src', '/images/expand.png');
$(this).parent().siblings('.togglethis').slideToggle('slow');
}
);
$('.item-title-header').toggle(
function() {
$('.toggle-button').attr('src', '/images/collapse.png');
$(this).parent().siblings('.togglethis').slideToggle('slow');
},
function() {
$('.toggle-button').attr('src', '/images/expand.png');
$(this).parent().siblings('.togglethis').slideToggle('slow');
}
);
});
Upvotes: 0
Views: 1638
Reputation: 10795
The main problem is that you have mismatched </div>
s inside your collapsible-item-title
div
s. Just remove that and it will fix the toggling. You might also want to add end-slashes to your img
tags.
Also I'm guessing that, instead of,
$('.toggle-button').attr('src', '/images/collapse.png');
you meant to have
$(this).siblings('.toggle-button').attr('src', '/images/collapse.png');
Here is the corrected code posted on JS Bin:
http://jsbin.com/iruvo (editable via http://jsbin.com/iruvo/edit)
Lastly, you can make your jQuery code much simpler by refactoring your event handlers into a single function:
function toggleIt() {
var collapsibleItem = $(this).parents('.collapsible-item');
var toggleButton = collapsibleItem.find('.toggle-button')
var currentImage = toggleButton.attr('src');
toggleButton.attr('src', currentImage === minusIcon ? plusIcon : minusIcon);
collapsibleItem.find('.togglethis').slideToggle('slow');
}
$('.toggle-button, .item-title-header').toggle(toggleIt, toggleIt);
Upvotes: 1
Reputation: 655239
You have a mismatch of opening and closing DIV tags. It’s probably either the closing DIV tag in the line of the opening DIV tag of the class item-title-header or two lines below that.
You can also make it more compact by using this:
$(document).ready(function() {
$('.collapsible-item-title').toggle(
function() {
$(this).attr('src', '/images/collapse.png')
.next('.togglethis').slideToggle('slow');
},
function() {
$(this).attr('src', '/images/expand.png')
.next('.togglethis').slideToggle('slow');
}
);
});
Upvotes: 1
Reputation: 186562
Something like this?
<script>
$(document).ready(function () {
$.fn.toggleTo = function( options ) {
options = $.extend( options, {
containerClass:'collapsible-item',
speed:'slow',
collapse:'/images/collapse.png',
expand:'/images/expand.png',
toggleClass:'togglethis'
});
return this.each(function() {
var p = $(this).closest('.' + options.containerClass);
$(this).toggle(function() {
$(p).find('.toggle-button').attr('src', options.collapse);
$(p).next('.' + options.toggleClass).slideToggle('slow');
}, function() {
$(p).find('.toggle-button').attr('src', options.expand);
$(p).next('.' + options.toggleClass).slideToggle('slow');
});
});
}
$('.item-title-header, .toggle-button').toggleTo();
});
</script>
And I think some of your traversing was off, it didn't descend high enough or something of that nature to get to the sibling, I just re-coded it entirely.
Upvotes: 1
Reputation: 91193
You guys are making this sound too hard. Pretty sure this is all you need:
$(document).ready(function() {
$('.toggle-button').click(function(){
$(this).parent().next().slideToggle('slow');
});
});
Upvotes: 0