0

I'm trying to mock a refresh for a list that I have. So when a user clicks refresh, the list fades in to let users know a new GET request was made.

html

<div ng-controller="ModalDemoCtrl">

    <ul ng-repeat="friend in friends" class="animated" ng-class="{fadeIn: refresh === true}">
       <li>{{friend}}</li>
    </ul>

<button ng-click="refresh=!refresh"> Fade me in every time </button>

</div>

css

.animated { 
    -webkit-animation-duration: 1s; 
    animation-duration: 1s; 
    -webkit-animation-fill-mode: both; 
    animation-fill-mode: both; 
} 

@-webkit-keyframes fadeIn { 
    0% {opacity: 0;} 
    100% {opacity: 1;} 
} 
@keyframes fadeIn { 
    0% {opacity: 0;} 
    100% {opacity: 1;} 
} 
.fadeIn { 
    -webkit-animation-name: fadeIn; 
    animation-name: fadeIn; 
}

and of course the js

angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {

  $scope.friends = ['andy', 'randy', 'bambi'] ;

};

Here's a working plnkr: http://plnkr.co/edit/R0Gv2T?p=info

My issue is the way I have it, the user has to click twice to fade in the list in after clicking it once because the variable refresh has to be set back to false before being set back to true. Is there anywhere through pure css to accomplish this? I've tried setting scope variables in the controller and calling on click function but I'm just confused at this point. I'm open to any solution

Garuuk
  • 2,153
  • 6
  • 30
  • 59
  • 1
    You just need to show it as an indicator for data refresh right. You do not need all these flags just convert it to array of objects. http://plnkr.co/edit/RYBVUp?p=preview With array of objects what happens is (you do not have a track by) everytime items will be new items (because of difference in hashKey) the animation will occur. For more advanced animations on addition of items you can take a look at ng-repeat animation classes/ – PSL Oct 20 '14 at 22:46
  • Thanks @PSL This worked fine but I had a more nested and complicated object and I couldn't simply cast them all into an array. I ended up using your timeout idea but added a variable that checks if fade is true or not and then setting to false on the timeout and have this in ng-class. I have a plnkr for my answer. – Garuuk Oct 21 '14 at 16:22
  • Possible duplicate of [How to fade out element using ng-hide with AngularJS?](http://stackoverflow.com/questions/42928222/how-to-fade-out-element-using-ng-hide-with-angularjs) – Mistalis Mar 21 '17 at 13:35

2 Answers2

1

For one, I'd check out angular-motion as it has all of these kinds of css animations. If not though you should hook into the ngAnimate module as it provides a great way to handle this sort of stuff using ng-hide/ng-show. So your css becomes

.fadeIn { 
    opacity: 0;
}
.fadeIn.ng-hide-remove {
    -webkit-animation-name: fadeIn; 
    animation-name: fadeIn;
}

and your html becomes

<ul ng-repeat="friend in friends" class="animated" ng-show="refresh">
   <li>{{friend}}</li>
</ul>

You may also want to provide a fadeOut animation as well and apply it using css rule .fadeIn.ng-hide

Vadim
  • 17,897
  • 4
  • 38
  • 62
0

I used @PLS timeout idea but kept the ng-class and added a variable that checks if it's on or off. Then always set it to false when you click before waiting for the timeout.

  $scope.friends = [{name:'andy'}, {name:'randy'}, {name:'bambi'}] ;
    $scope.refresh = function(){
        $scope.fadeCheck = true;
        $timeout(function(){
            $scope.fadeCheck = false;
        }, 300);
    }

and the html

<ul ng-repeat="friend in friends" class="animated" ng-class="{fadeIn: fadeCheck === false}">
  <li>{{friend.name}}</li>
</ul>

http://plnkr.co/edit/Xp7E6s?p=preview

Garuuk
  • 2,153
  • 6
  • 30
  • 59