Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - animate div using changing scope variable

I'm new to angular. I want to animate a div body using ng-click on a ng-repeat element. This is what I have tried so far.

app.js

var app = angular.module( 'app', [] );

app.controller('appController', function($scope) {

    $scope.items = [
  {"id": "id1", "name": "Name 1"},
  {"id": "id2", "name": "Name 2"},
  {"id": "id3", "name": "Name 3"}
  ];

  $scope.selectedStyle = {"background-color": "blue", "color": "white"};
  $scope.selectedItem = $scope.items[0];

  $scope.selectItem = function(item) {
    $scope.selectedItem = item;
  }

});

app.html

<div ng-app="app" ng-controller="appController">
  <table class=table>
    <tbody>
      <tr ng-repeat="item in items" ng-click="selectItem(item)" ng-style="item.id === selectedItem.id && selectedStyle">
        <td>
          {{item.id}}
        </td>
      </tr>
    </tbody>
  </table>

  <div class="item-body">
    {{selectedItem.name}}
  </div>
</div>

What I wanted to do is add a fade-in transition effect to item-body div as the changing item. I searched the web, but I can't seem to find a solution. Please help.

JSFiddle - https://jsfiddle.net/lpsandaruwan/ot45qdno/14/

like image 930
lpsandaruwan Avatar asked Dec 05 '16 08:12

lpsandaruwan


1 Answers

Animating the items themselves

You can do this by adding a class to the selected element using angular, and managing the transition using css transitions.

This way, there's no need for $scope.selectedStyle. We'll manage that in css.

So, the flow would be like so:

  1. When a user clicks, angular will add a selected class to the clicked element.
  2. css transition for the class item will handle the color changes for you (both for select and deselect).

Here's the code:

var app = angular.module('app', []);

app.controller('appController', function($scope) {

  $scope.items = [{
    "id": "id1",
    "name": "Name 1"
  }, {
    "id": "id2",
    "name": "Name 2"
  }, {
    "id": "id3",
    "name": "Name 3"
  }];

  $scope.selectedItem = $scope.items[0];

  $scope.selectItem = function(item) {
    $scope.selectedItem = item;
  }

});
.item-body {
  color: red;
}
.item {
  cursor: pointer;
  transition: all 250ms linear;
}
.item.selected {
  cursor: default;
  background-color: blue;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="appController">
  <table class=table>
    <tbody>
      <tr ng-repeat="item in items" ng-click="selectItem(item)" class="item" ng-class="{ 'selected': selectedItem === item }">
        <td>
          {{item.id}}
        </td>
      </tr>
    </tbody>
  </table>

  <div class="item-body">
    {{selectedItem.name}}
  </div>
</div>

Animating the item-body

if you want to animate the item-body on change, you can use a simple timeout to add and remove a class.

Also, you should know that there are some modules that you can use to achieve this (like this).

Here is what I suggest:

  1. add a flag to let the item-body element know it needs to hide and show
  2. hook that flag to a class
  3. make that flag hide and show the element, similar to the transition we did before

var app = angular.module('app', []);

app.controller('appController', function($scope, $timeout) {

  $scope.items = [{
    "id": "id1",
    "name": "Name 1"
  }, {
    "id": "id2",
    "name": "Name 2"
  }, {
    "id": "id3",
    "name": "Name 3"
  }];

  $scope.selectedItem = $scope.items[0];

  $scope.selectItem = function(item) {
    $scope.changeIsOn = true;
    $timeout(function() {
      $scope.selectedItem = item;
      $scope.changeIsOn = false;
    }, 250);

  }

});
.item-body {
  color: red;
  transition: opacity 250ms linear;
}
.item-body.changing {
  opacity: 0;
}
.item {
  cursor: pointer;
  transition: all 250ms linear;
}
.item.selected {
  cursor: default;
  background-color: blue;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="appController">
  <table class=table>
    <tbody>
      <tr ng-repeat="item in items" ng-click="selectItem(item)" class="item" ng-class="{ 'selected': selectedItem === item }">
        <td>
          {{item.id}}
        </td>
      </tr>
    </tbody>
  </table>

  <div class="item-body" ng-class="{ 'changing': changeIsOn }">
    {{selectedItem.name}}
  </div>
</div>
like image 106
Thatkookooguy Avatar answered Sep 27 '22 21:09

Thatkookooguy