Alexander Showlsky
Alexander Showlsky

Reputation: 214

Animate div's height with nested divs

Here is the snippet: https://jsfiddle.net/wc48jvgt/69/

I have a horizontally shaped div #cleaning_card_1, which has embedded divs which act like borders and vertical div #cleaning_card_right_1 with a nested div #cleaning_card_right_content_1. Inside the last div I have multiple divs which amount is dynamic. What I want to achieve is #cleaning_card_right_1 acting like a dropdown menu. I have a simple function to achieve that:

function maximizeCleaningCard () {

    var cleaning_card_number = $(this).attr('number')

    $(this).animate({width: '97%'}, 200, function () {
        $('#cleaning_card_right_' + cleaning_card_number).removeClass('cleaning_card_right').addClass('cleaning_card_right_maximized')
        $('#cleaning_card_right_' + cleaning_card_number).animate({height: 400}, 400)
        $('#cleaning_card_right_content_' + cleaning_card_number).animate({height: 400 - 80}, 400)
        $('#cleaning_card_right_left_border_1, #cleaning_card_right_right_border_1').animate({height: 400 - 80}, 400)
    })

}

$('.cleaning_card').click(maximizeCleaningCard) 

Animation is properly run on #cleaning_card_1 and border divs, however the #cleaning_card_right_content_1 is not animated at all. It just pops up there and thats it. If I'll remove nested items out of it, animation will properly work. I think that the problem is that div's height is not equal to 0 due to nested elements, but most likely I am mistaken. How to overcome this issue?

Upvotes: 0

Views: 85

Answers (1)

joshmoto
joshmoto

Reputation: 5088

I noticed you are animated multiple divs to get the simultaneous vertical animate. You could streamline your div layout to get the same effect by just using 2 animates to complete the sequence.

I've removed all the unnecessary divs and used more practical css to get the same effect. Might not be perfect for your final use but may get you on the right track.

I've also added a minimizing sequence using the class .maximized to tell what state the cleaning card is in, and which sequence to run.

Here is a fiddle too https://jsfiddle.net/joshmoto/0ynrm1ts/2/

See comments in my script to see what is happening...

// maximize cleaning card
function maximizeCleaningCard() {

  // store current clicked cleaning card variable for later use in animate
  let cleaningCard = this;
  
  // set cleaning card right element variable
  let cleaningCardRight = $('.cleaning_card_right', cleaningCard);
  
  // check we actually have a cleaning card right
  if($(cleaningCardRight).length) {
    
    // set the cleaning card right content variable
    let cleaningCardRightContent = $('.cleaning_card_right_content', cleaningCardRight);
  
    // if cleaning card has maximized class
    if($(cleaningCard).hasClass('maximized')) {

      // remove the maximized class
      $(cleaningCard).removeClass('maximized');

      // animate cleaning card right first to reverse sequence
      $(cleaningCardRight).animate({
          height: '0px'
        }, 500, function() {

          // when cleaning card right is fully closed
          // animate cleaning card to finish the closing sequence
          $(cleaningCard).animate({
            width: '70%'
          }, 500 );

        });

    // else if cleaning card does not have maximized class
    } else {
      
      // add the maximized class
      $(cleaningCard).addClass('maximized');
      
      // animate cleaning card width to 100%
      $(cleaningCard).animate({
        width: '100%'
      }, 500, function() {
      
        // when cleaning card is fully open
        // animate cleaning card height to the cleaning card right content
        $(cleaningCardRight).animate({
          height: $(cleaningCardRightContent).outerHeight()
        }, 500 );

      });

    }
  
  }
  
}

// when cleaning card is clicked
$(document).on('click','.cleaning_card', maximizeCleaningCard );
BODY {
  padding: 15px;
  margin: 0;
}

.cleaning_card {
  position: relative;
  width: 70%;
  border: 1px solid black;
  height: 80px;
  font-size: 15px;
  overflow: visible;
  margin-bottom: 15px;
}

.cleaning_card:hover {
  cursor: pointer;
}

.cleaning_card_right {
  position: absolute;
  width: 25%;
  height: 0;
  background-color: white;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
  border-right: 1px solid black;
  overflow: hidden;
  top: 100%;
  right: -1px;
}

.cleaning_card_right_content {
  position: relative;
  padding: 5px;
  overflow: hidden;
}

.cleaning_card_right_content_item {
  position: relative;
  background-color: cornsilk;
}
<div id="cleaning_card_1" class="cleaning_card">

  <div class="cleaning_card_right">

    <div class="cleaning_card_right_content">

      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Standard </div>
        <div class="cleaning_card_right_value"> 1 </div>
      </div>

      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Junior Suite </div>
        <div class="cleaning_card_right_value"> 2 </div>
      </div>
      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Lux </div>
        <div class="cleaning_card_right_value"> 3 </div>
      </div>

    </div>

  </div>

</div>

<div id="cleaning_card_2" class="cleaning_card">

  <div class="cleaning_card_right">

    <div class="cleaning_card_right_content">

      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Standard </div>
        <div class="cleaning_card_right_value"> 1 </div>
      </div>

      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Junior Suite </div>
        <div class="cleaning_card_right_value"> 2 </div>
      </div>
      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Lux </div>
        <div class="cleaning_card_right_value"> 3 </div>
      </div>

    </div>

  </div>

</div>

<div id="cleaning_card_3" class="cleaning_card">

  <div class="cleaning_card_right">

    <div class="cleaning_card_right_content">

      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Standard </div>
        <div class="cleaning_card_right_value"> 1 </div>
      </div>

      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Junior Suite </div>
        <div class="cleaning_card_right_value"> 2 </div>
      </div>
      <div class="cleaning_card_right_content_item">
        <div class="cleaning_card_right_category"> Lux </div>
        <div class="cleaning_card_right_value"> 3 </div>
      </div>

    </div>

  </div>

</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Upvotes: 1

Related Questions