How do I highlight ng-repeat items - angularjs

How do I highlight the newest item added to a list that is displayed with ng-repeat? I've tried using jquery effect() in my addItem() function but that didn't work. I've also tried using the highlight filter from angular-ui without success.
//controller
$scope.addItem = function() {
$scope.items.unshift($scope.item);
};
//html
<ul class="media-list">
<li class="media" ng-repeat="item in items | highlight:item">

Angular has been supporting animations since version 1.1.4.
Just add ng-animate to you lis, with an animation name:
<li ng-animate="'highlight'" ng-repeat="item in items">{{ item }}</li>
and supply the proper animation CSS for that animation name:
li {
-webkit-transition: all 2s 1.5s ease-out;
-moz-transition: all 1.5s ease-out;
transition: all 1.5s ease-out;
}
.highlight-enter-setup {
background: yellow;
}
.highlight-enter-start {
background: white;
}
Here's the fiddle: http://jsfiddle.net/u4Tnw/
You are not limited to just highlighting. You can do all sorts of crazy animations.
Here's a crazier example: http://jsfiddle.net/u4Tnw/3/

Related

ng-repeat elements are removed from the DOM after a moment rather than immediately

I have this instagram feed page which shows liked media from a specific user, the results are limited to 6:
<li ng-repeat="p in pics | limitTo: 6">
<a href="{{p.link}}" target="_blank">
<img ng-src="{{p.images.standard_resolution.url}}" />
</a>
</li>
<button ng-click="shuffle()">Shuffle</button>
I also added a shuffle button which when you click picks 6 pictures at random from the total amount of pictures in the JSON. However when you click it shows them all for a second. Is there a way to stop this from happening?
JS
app.controller('ShowImages', function($scope, InstagramAPI){
$scope.layout = 'grid';
$scope.data = {};
$scope.pics = [];
$scope.shuffle = function() {
$scope.pics.sort(function() { return 0.5 - Math.random() });
};
InstagramAPI.fetchPhotos(function(data){
$scope.pics = data;
console.log("length is "+data.length)
});
});
You can see it here:
http://alexanderlloyd.info/Angular-Instafeed-master/
This behavior is as expected because your elements are styled with .ng-leave so that they fade out when leaving the DOM. You just need to remove that style from those elements altogether, or if needed, conditionally apply/remove the transition so that it is not affecting the elements in the state you're currently dealing with.
This style is the problem:
.page .ng-leave {
-webkit-animation: fadeOut 0.6s both ease-in;
-moz-animation: fadeOut 0.6s both ease-in;
animation: fadeOut 0.6s both ease-in;
}
Any element inside of .page that gets the class .ng-leave is going to be animated out. Perhaps you meant that to be .page.ng-leave so that it would only apply to .page? I removed that style and tried the shuffle and the leaving elements were immediately removed as you desire.

Animate removal of list items with css

I have made the animation of a showing/hiding a list of messages. See this plunk. But how can I adapt it to also make an animation when a message is removed from the list?
My css:
.messages-active.messages {
max-height: 50px;
}
.messages {
-webkit-transition: max-height 1s;
-moz-transition: max-height 1s;
-ms-transition: max-height 1s;
-o-transition: max-height 1s;
transition: max-height 1s;
background-color: AntiqueWhite;
overflow: hidden;
max-height: 0;
}
My index file (using Angular):
<body ng-app="app" ng-controller="TestCtrl as test">
<button ng-click="test.toggle = !test.toggle">Show messages</button>
(current: {{test.toggle}})
<div class="messages" ng-class="{ 'messages-active': test.toggle }" ng-repeat="message in test.messages">
{{message}} <a href ng-click="test.remove($index)">remove</a>
</div>
</body>
The idea is to set the height of container and add transition to the height.
$scope.styles.height = $scope.messages.length * 20 + 'px';
http://plnkr.co/edit/3dnGeVoQ1DbX55WQtJjk?p=preview
You can try following if it may help you.
On clicking remove instead removing element just add class messages-remove on it's parent div messages.
For e.g: It should become <div class="messages" to <div class="messages messages-remove".
Also add the following CSS in your style sheet.
.messages-active.messages-remove.messages,
.messages-remove.messages { max-height: 0px; }
Let me know if you have any question.

adding angular animation to bootstrap dropdown

I want to add animations to the opening and closing of a dropdown in my angular app. So far I can get open animations working on the dropdown, but nothing for close animations.
I took the navbar code straight from the bootstrap example and added it to my page with some minor modifications. The relevant part of the navbar is this:
<ul class="nav navbar-nav navbar-right">
<li ng-if="isAuthenticated()" class="dropdown">
{{ authenticatedUser.displayName }} <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li ng-if="menuItem.show()" ng-repeat="menuItem in menuItems" ng-class="{active: menuItem.active, disabled: menuItem.disabled}">
<a ui-sref="{{ menuItem.state }}({{ menuItem.stateParams }})">{{ menuItem.heading }}</a>
</li>
</ul>
</li>
</ul>
I'm also using angular bootstrap so the line:
<li ng-if="isAuthenticated()" class="dropdown">
triggers angular's own Dropdown directive.
I noticed by simply adding a class to the inner <ul class="dropdown-menu" ...> element I could get a nice open animation.
<ul class="dropdown-menu my-cool-opening-animation" role="menu">
2 questions:
Is this the correct 'angular' way to add the animation?
The animation works when the dropdown opens, but I can't get any animation when the dropdown closes, how do you do this?
This issue looks very similar to what I'm seeing and the fix for the issue seem to be very closely related to what I want. But I don't really understand how to apply it to get animations on the dropdown close.
As a side note, but possibly relevant is I'd like to use/am using the animate.css package as a base for my css animations.
Just faced out with the same issue and spent weeks trying to make two-way fade animation I came up with tricky CSS-solution. Almost done, I've took a look at Fade animation in Angular-UI Modal and what I have found:
<div class="modal fade in" ng-class="{in: animate}">modal content</div>
After checked out the issue #1465 and made a deeper look at Angular Docs (addClass/removeClass methods) I transferred this to Angular-UI Dropdown and what I've got so far:
http://plnkr.co/edit/KO41KkAFnCog3Vfl08Uf?p=preview
Here is the last version of my CSS:
.dropdown.ng-animate-start {
border-spacing: 0;
}
.open-add > .dropdown-menu,
.open-remove > .dropdown-menu {
display: block !important;
}
.open-add > .dropdown-menu {
opacity: 0;
-webkit-transition: opacity .3s ease-in;
-moz-transition: opacity .3s ease-in;
-ms-transition: opacity .3s ease-in;
-o-transition: opacity .3s ease-in;
transition: opacity .3s ease-in;
}
.open-add.open-add-active > .dropdown-menu {
opacity: 1;
}
.open-remove > .dropdown-menu {
opacity: 1;
-webkit-transition: opacity .3s ease-out;
-moz-transition: opacity .3s ease-out;
-ms-transition: opacity .3s ease-out;
-o-transition: opacity .3s ease-out;
transition: opacity .3s ease-out;
}
.open-remove.open-remove-active > .dropdown-menu {
opacity: 0;
}
Hope it helps to save your time.

angularjs: ngAnimate not working

I am new to angularjs. I am trying angularjs with rails (using "angularjs-rails" gem). I am having trouble using ngAnimate. The functionality works fine i.e. angular is properly installed and "addEntry" function adds up the new entry, but animation is not working. I am not sure what I am missing here.
app = angular.module("MyApp", ['ngAnimate'])
#MainCtrl = ($scope) ->
$scope.entries = [{name: "Dummy1"}, {name: "Dummy2"}]
$scope.addEntry = ->
$scope.entries.push({name: "Dummy3"})
Here is the html file:
<div ng-controller="MainCtrl">
<button ng-click="addEntry()"></button>
<div ng-repeat="entry in entries" ng-animate="'demo'">
<a>{{entry.name}}</a>
</div>
</div>
Here is CSS to support ngAnimate:
.demo-enter {
-webkit-transition: all 1s linear;
transition: all 1s linear;
background: #000;
}
.demo-enter.demo-enter-active {
background: #ccc;
}
The ng-animate attribute is deprecated in 1.2 and no longer used. Instead, animations are now class based.
If you want your ng-repeat enter animaiton to be named 'demo' you have to decorate it with some additional classes following a special naming convention:
.demo.ng-enter {
transition: all linear 500ms;
opacity: 0;
}
.demo.ng-enter-active {
opacity: 1;
}
Then just put the 'demo' class on the element containing the ng-repeat:
<div ng-repeat="entry in entries" class="demo">
Demo: http://plnkr.co/edit/kNeXtl6TpGNvtQEpErwh?p=preview
Good source on the subject: http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html
If you want the fade animation, set opacity to 0 at the setup class, and opacity to 1 at the active
.animate-enter {
-webkit-transition: 1s linear all; /* Chrome */
transition: 1s linear all;
opacity: 0;
}
.animate-enter.animate-enter-active {
opacity: 1;
}

angularjs chained fade-in / fade-out transition

I have looked at the official show/hide transition example at the bottom of this page... http://docs.angularjs.org/api/ng.directive:ngShow
I have tried to modify it to get a seemless fade transition (transition: opacity 0.5s ease-in-out) from one div to the other, where both divs occupy the exact same position on the page, so that one div completely fades out before the other div begins to fade in.
In jquery, it would be as simple as:
$("#divA").fadeOut(function() { $("divB").fadeIn(); });
Does anyone have any advice on the best way to achieve this with angular, with respect to the linked example, which uses a single model "checked" to trigger the transition?
I used the example in ngShow to make the following jsfiddle based on angular1.2.0-rc.3.
The html code:
<div ng-app="App">
Click me: <input type="checkbox" ng-model="checked"><br/>
<div class="check-element animate-show" ng-show="checked">
<span class="icon-thumbs-up"></span> I show up when your checkbox is checked.
</div>
<div class="check-element animate-show" ng-hide="checked">
<span class="icon-thumbs-down"></span> I hide when your checkbox is checked.
</div>
</div>
The CSS styles
.animate-show.ng-hide-add,
.animate-show.ng-hide-remove {
-webkit-transition:all linear 0.5s;
-moz-transition:all linear 0.5s;
-o-transition:all linear 0.5s;
transition:all linear 0.5s;
display:block!important;
}
.animate-show.ng-hide-add.ng-hide-add-active,
.animate-show.ng-hide-remove {
line-height:0;
opacity:0;
padding:0 10px;
}
.animate-show.ng-hide-add,
.animate-show.ng-hide-remove.ng-hide-remove-active {
line-height:20px;
opacity:1;
padding:10px;
border:1px solid black;
background:white;
}
.check-element {
padding:10px;
border:1px solid black;
background:white;
}
And finally the JavaScript code, don't forget to include the libraries angular.js and angular-animate.js
angular.module('App', ['ngAnimate']);
I hope it helps you ;)
Using the ngAnimate module, you can do this in pure CSS with the -transition-delay directive:
Plunker
HTML
<body ng-app="ngAnimate">
Click me: <input type="checkbox" ng-model="checked">
<br/>
<img ng-show="checked" src="img1.jpg">
<img ng-hide="checked" src="img2.jpg">
</body>
CSS
img {
position: absolute;
}
.ng-hide-add-active {
display: block!important;
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
}
.ng-hide-remove-active {
display: block!important;
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
-webkit-transition-delay: 0.5s;
transition-delay: 0.5s;
}
.ng-hide {
opacity: 0;
}
You can use ng-animate in conjuction with ng-show (http://docs.angularjs.org/api/ngAnimate), available from Angular 1.1.4. Or alternatively simply apply a show class when the model is ticked and apply your show and animation to the class.
<label><input type="checkbox" ng-model="showElement" />Show div</label>
<div ng-class="{show: showElement}"></div>

Resources