user1881482
user1881482

Reputation: 746

Accordion style behaviour on items outside of containing div

I have a list of images - 3 in each row.

I then have 3 divs directly below that with corresponding info to each of the images

I have 3 rows of images with the same setup. Essentially I want to have all items show up in a grid. If item 1,2 or 3 are clicked i want to show their related info directly below the first row of images, but before the second row of images, as well to only allow one one information div to be open at a time.

<ul class="thumbnails">
                    <li class="span4">
                        <div class="thumbnail">
                            <img src="assets/img/rpic.jpg" alt="" class="accord-header">
                        </div>
                    </li>
                    <li class="span4">
                        <div class="thumbnail">
                            <img src="assets/img/mpic.jpg" alt="" class="accord-header">
                        </div>
                    </li>
                    <li class="span4">
                        <div class="thumbnail">
                            <img src="assets/img/cpic.jpg" alt="" class="accord-header">
                        </div>
                    </li>
                    </ul>
                    <div class="accord-content span12">
                        This is the content for the first image.
                    </div>
                    <div class="accord-content span12">
                        This is the content for the second image.
                    </div>
                    <div class="accord-content span12">
                        This is the content for the third image.
                    </div>

I had been using an accordion script for this however it only allows the div to be placed directly below the referencing link. Is there a way to allow external divs

$(".thumbnails .accord-header").click(function() {
                if ($(this).next("div").is(":visible")) {
                    $(this).next("div").slideUp("slow");
                } else {
                    $(".thumbnails .accord-content").slideUp("slow");
                    $(this).next("div").slideToggle("slow");
                }
            });

Upvotes: 1

Views: 153

Answers (1)

Sushanth --
Sushanth --

Reputation: 55750

To find the next div you need to find find the ancestor and get the next one..

Replace

$(this).next("div")

with

$(this)..closest('li').next("li").find('div')

And you have invalid HTML .. Only li should be a direct child of an ul .Move the div's to outside the ul

Why don't you have the accordcontent div's inside the div in the first place. That should be the better approach.

Approach 1

HTML

<ul class="thumbnails">
    <li class="span4">
        <div class="thumbnail">
            <img src="assets/img/rpic.jpg" alt="" class="accord-header">
        </div>
    </li>
    <li class="span4">
        <div class="thumbnail">
            <img src="assets/img/mpic.jpg" alt="" class="accord-header">
        </div>
    </li>
    <li class="span4">
        <div class="thumbnail">
            <img src="assets/img/cpic.jpg" alt="" class="accord-header">
        </div>
    </li>
</ul>
<div class="content">
    <div class="accord-content span12">
        This is the content for the first image.
    </div>
    <div class="accord-content span12">
        This is the content for the second image.
    </div>
    <div class="accord-content span12">
        This is the content for the third image.
    </div>
</div>

JS

$(".thumbnails .accord-header").click(function () {
    var $closestli = $(this).closest('li'),
        liIndex = $('li').index($closestli);

    // Hide all content
    var $contentDiv = $('.accord-content.span12', '.content').eq(liIndex);
    if ($contentDiv.is(":visible")) {
        $contentDiv.slideUp("slow");
    } else {
        $('.accord-content.span12', '.content').not($contentDiv).slideUp("slow");
        $contentDiv.slideDown("slow");
    }
});

Check Fiddle

Approach 2

Otherwise you can use HTML data-5* attributes that hold the corresponding content div to be managed.

HTML

<ul class="thumbnails">
    <li class="span4">
        <div class="thumbnail">
            <img src="assets/img/rpic.jpg" data-div="content1" alt="" class="accord-header">
        </div>
    </li>
    <li class="span4">
        <div class="thumbnail">
            <img src="assets/img/mpic.jpg" data-div="content2" alt="" class="accord-header">
        </div>
    </li>
    <li class="span4">
        <div class="thumbnail">
            <img src="assets/img/cpic.jpg" data-div="content3" alt="" class="accord-header">
        </div>
    </li>
</ul>
<div class="content">
    <div id="content1" class="accord-content span12">
        This is the content for the first image.
    </div>
    <div id="content2" class="accord-content span12">
        This is the content for the second image.
    </div>
    <div id="content3" class="accord-content span12">
        This is the content for the third image.
    </div>
</div>

JS

$(".thumbnails .accord-header").click(function () {
    var contentId = $(this).data('div'),
        $contentDiv = $('#' + contentId);

    if ($contentDiv.is(":visible")) {
        $contentDiv.slideUp("slow");
    } else {
        $('.accord-content.span12', '.content').not($contentDiv).slideUp("slow");
        $contentDiv.slideDown("slow");
    }
});

Check Fiddle

JS slideToggle

$(".thumbnails .accord-header").click(function () {
    var contentId = $(this).data('div'),
        $contentDiv = $('#' + contentId);

        $contentDiv.slideToggle("slow");
        $('.accord-content.span12', '.content').not($contentDiv).slideUp("slow");
});

Slide Toggle

Upvotes: 1

Related Questions