phpN00b
phpN00b

Reputation: 807

Applying jquery function to more than one div?

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

Answers (4)

brianpeiris
brianpeiris

Reputation: 10795

The main problem is that you have mismatched </div>s inside your collapsible-item-title divs. 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

Gumbo
Gumbo

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

meder omuraliev
meder omuraliev

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>

http://jsbin.com/ayula

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

Jake Wilson
Jake Wilson

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

Related Questions