Animation on ngShow skips first time

1k views Asked by At

I am trying to animate a twitter bootstrap panel body opening/closing that is shown with ng-show in angular (version 1.3.2), by using a simple jQuery slideUp/slideDown.

(I tried at first with css transitions, but couldn't do it because of unknown body height, and max-height animation was giving me problems on closing, so I decided to go with JS)

I've succeeded in making the animation, but it does not work the first time the animation is toggled. So the first body showing is not animated, then the hiding is animated, and after that everything is fine (both show and hide animate).

Javascript part:

app.animation('.animate-panel-body-slide', function(){
return {
    addClass : function(element, className, done) {
        $(element).slideUp(400, done);
        return function(isCancelled) {
            if(isCancelled) {
                $(element).stop();
            }
        }
    },
    removeClass : function(element, className, done) {
        $(element).slideDown(400, done);
        return function(isCancelled) {
            if(isCancelled) {
                $(element).stop();
            }
        }
    }
}
});

HTML part:

<div class="panel panel-default">
    <div class="panel-heading">
        HEADING
    </div>
    <div class="panel-body animate-panel-body-slide" ng-show="isPanelOpen">
        SOME HTML IN BODY...
    </div>
</div>

Am I missing something?

1

There are 1 answers

1
tasseKATT On BEST ANSWER

When removeClass is executed it's because ng-hide (which sets display: none) was removed from the element.

The first time this happens the element will have display: block which means the element will appear immediately and the slideDown animation will not be apparent.

When the panel is closed the slideUp animation will add style="display: none;" to the element, which means the next time it's opened it will work as expected.

If you add it manually like this:

<div class="panel-body animate-panel-body-slide" ng-show="isPanelOpen" style="display: none">

It will work as long as the panel always begins as closed.

If you want it to work for both cases you can add this:

removeClass: function(element, className, done) {

  element.css('display', 'none');
  element.slideDown(400, done);

  ...