Lydia Maier
Lydia Maier

Reputation: 439

Resize height of div, from accodion (jQuery)

So just to my problem, I have a separate script for a kind of accordion function, in this element there are other accordions (jQuery UI), which is barely visible through the fixed height of the first accordions.

In short, by toggling the second accordion, the height of the first accordion and the parent would have to change to make it look as if the underlying content is pushed down.

Example: http://jsfiddle.net/v5m4wyoo/10/

//show hidden content function
// global variables
                var nav1           = $('.group'),
                    navHeight1     = nav1.height(),
                    items1         = $('.group .partner_item .trigger'),
                    itemsSub1      = items1.next('.toggle_container'),
                    itemsSubOpen1  = false,
                    speed1         = 400;

                // global functions
                var navOpen1 = function (thisSubmenu1) {
                    itemsSubOpen1 = true;

                    // get height
                    thisSubmenu1.css('height', 'auto');
                    var thisHeight1 = thisSubmenu1.height();


                    thisSubmenu1
                        .css('height', '0')
                        .animate({height: thisHeight1 }, speed1)
                        .addClass('open')
                        .closest('.group')
                        .animate({height: thisHeight1 + navHeight1+130 }, speed1);
                };

                var navClose1 = function () {
                    itemsSubOpen1 = false;
                    items1.next('.open')
                        .animate({height: 0}, speed1)
                        .removeClass('open');
                    nav1.animate({height: navHeight1+125 }, speed1);
                };
                // prepare css
                itemsSub1.css('display', 'block');
                itemsSub1.css('height', '0');
                // click event
                items1.click(function(event) {

                    // set local variables
                    var thisItem1 = $(this),
                        thisSubmenu1 = thisItem1.next('.toggle_container');

                    // conditional click event handling
                    if ( itemsSubOpen1  ) {

                        if ( thisSubmenu1.hasClass('open') ) {
                            // only close
                            navClose1();
                        } else {
                            // close old, than open new
                            navClose1();
                            setTimeout(function() {
                                navOpen1(thisSubmenu1);
                            }, speed1);

                        }
                    } else {
                        // only open
                        navOpen1(thisSubmenu1);
                    }

                    // prevent default
                    event.preventDefault();

                });

Upvotes: 1

Views: 1184

Answers (1)

FrancescoMM
FrancescoMM

Reputation: 2960

http://jsfiddle.net/v5m4wyoo/12/

I have added a height("auto") at the end of the animation. Is that what you needed?

                thisSubmenu1
                    .css('height', '0')
                .animate({height: thisHeight1 }, speed1,function() {
                    $(this).height("auto");
                })

the function gets called at the end of the opening animation and resetting height to auto (has no visual effect and) lets the inner accordion resize and expand as it likes

EDIT

You can rearrange items in the page, adding something like this:

var customId=0;
$(function() {
    $(".wrapper_hidden_content").each(function() {

        var $this=$(this);
        var $partner_item=$(this).parent().parent();
        var $group=$partner_item.parent();
        $this.appendTo($group);

        $this.attr("id","id"+customId);
        $partner_item.data("id","id"+customId);
        customId++;
    })

});

This will put all .wrapper_hidden_content items inside the .group, together, but then you have to rearrange all your code and CSS to handle the new javascript manipulated HTML, and it gets quite messy. You have to remove all position absolute from the css, add a clear:both to the .wrapper_hidden_content so they stay below, remove height from group... it is messy but can be done

To get the submenu from the menu you can use

thisSubmenu1 = $("#"+thisItem1.parent().parent().data('id'));

(get the saved data-id of the clicked element, then add "#" in front and use that to search for the item with JQuery)

UPDATE

I have made a fiddle modifying your code to take the new (JS generated) HTML

http://jsfiddle.net/v5m4wyoo/20/

not tested much but looks like it's working, here is the code:

//show hidden content function
// global variables
                var nav1           = $('.group'),
                    navHeight1     = nav1.height(),
                    items1         = $('.group .partner_item .trigger'),
                    itemsSub1      = items1.next('.toggle_container'),
                    itemsSubOpen1  = false,
                    speed1         = 400;

                // global functions
                var navOpen1 = function (thisMenu1,thisSubmenu1) {
                    itemsSubOpen1 = thisMenu1;

                    // get height
                    thisSubmenu1.css('height', 'auto');
                    var thisHeight1 = thisSubmenu1.height();


                    thisSubmenu1
                        .css('height', '0')
                    .animate({height: thisHeight1 }, speed1,function() {
                        $(this).height("auto");
                    });
                    thisMenu1.addClass('open');
                };

                var navClose1 = function (thisMenu1,thisSubmenu1) {
                    itemsSubOpen1 = false;
                    thisSubmenu1.animate({height: 0}, speed1);

                    thisMenu1.removeClass('open');
                };
                // prepare css
                itemsSub1.css('display', 'block');
                itemsSub1.css('height', '0');
                // click event
                items1.click(function(event) {

                    // set local variables
                    var thisItem1 = $(this),
                    //    thisSubmenu1 = thisItem1.next('.toggle_container');
                    thisSubmenu1 = $("#"+thisItem1.parent().parent().data('id'));
                    // parent().parent() goes from the clicked item to the containing partner_item item
                    // .data('id') recovers the id of the submenu we saved with $partner_item.data("id","id"+customId);
                    // $("#"+...) gets the submenu on the page


                    // conditional click event handling
                    if ( itemsSubOpen1  ) { // either FALSE or the opend menu JQuery object
                        var oldSubmenu1 = $("#"+itemsSubOpen1.parent().parent().data('id'));
                        if ( thisItem1.hasClass('open') ) {
                            // only close
                            navClose1(itemsSubOpen1,oldSubmenu1); // old partner_item and his submenu
                        } else {
                            // close old, than open new
                            navClose1(itemsSubOpen1,oldSubmenu1); // old partner_item and his submenu
                            setTimeout(function() {
                                navOpen1(thisItem1,thisSubmenu1); // partner_item and his submenu
                            }, speed1);

                        }
                    } else {
                        // only open
                        navOpen1(thisItem1,thisSubmenu1); // partner_item and his submenu
                    }

                    // prevent default
                    event.preventDefault();

                });


var customId=0;
$(function() {
    $(".wrapper_hidden_content").each(function() {

        var $this=$(this); // the wrapper_hidden_content
        var $partner_item=$(this).parent().parent(); // his partner_item (two levels outside)
        var $group=$partner_item.parent(); // his group (one more level outside)
        $this.appendTo($group); // move the wrapper_hidden_content up to his group

        $this.attr("id","id"+customId); // set the id of the wrapper_hidden_content to a growing number
        $partner_item.data("id","id"+customId); // save the id of the wrapper_hidden_content inside the partner_item
        customId++; // increment the id number
    })

});

And here is the HTML how it gets modified by javascript on the go

<div class="partnerwrap">
    <div class="groupwrap">


        <div class="group">

            <div class="partner_item first even">...</div>
            <div class="partner_item odd">...</div>
            <div class="partner_item even">...</div>
            <div class="partner_item odd">...</div>
            <div class="partner_item even">...</div>
            <div id="id0" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id1" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id2" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id3" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id4" class="wrapper_hidden_content toggle_container">...</div>

        </div>

        <div class="group">

            <div class="partner_item odd">...</div>
            <div class="partner_item even">...</div>
            <div class="partner_item odd">...</div>
            <div class="partner_item even">...</div>
            <div class="partner_item odd">...</div>

            <div id="id5" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id6" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id7" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id8" class="wrapper_hidden_content toggle_container">...</div>
            <div id="id9" class="wrapper_hidden_content toggle_container">...</div>

        </div>
    </div>
</div>

Upvotes: 1

Related Questions