Animating a div using a changing scope variable in AngularJS

As a newcomer to Angular, I am looking to add animation to a div element using ng-click within an ng-repeat loop. Here is what I have attempted:

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>

I am trying to implement a fade-in transition effect on the "item-body" div as the item changes. Despite searching online, I have been unable to find a suitable solution. Any assistance would be greatly appreciated.

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

Answer №1

Animating the elements

To achieve animation in your items, you can utilize angular by adding a class to the selected element and manage the transition through css transitions.

This eliminates the need for using $scope.selectedStyle, as all styling and transitions are handled within css.

Here is how the process works:

  1. When a user clicks on an item, angular will assign a selected class to that element.
  2. The css transition for the class item will control the color changes during selection and deselection.

Below is the code implementation:

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 upon change, you can use a simple timeout function to add and remove classes dynamically.

There are also modules available that can assist in achieving this effect (such as this).

Consider the following steps:

  1. Add a flag to signal when the item-body needs to hide or show.
  2. Associate that flag with a class.
  3. Use the flag to toggle the visibility of the element, similar to the previous transition setup.

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>

Answer №2

By utilizing ng-class, you have the ability to implement the animation class depending on the specific scope value, like so:

$scope.selectedStyle = false;

<tr ng-class="({'myClass':selectedStyle})" >

Answer №3

To enhance your application's functionality, consider developing a custom directive that tracks changes in a designated model within your item-body section and utilizes Angular's animate service when the value is updated.

Make modifications to your HTML code by integrating the custom directive as shown below:

<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" my-dir ng-model="myValue">
    {{selectedItem.name}}
  </div>
</div>

Don't forget to obtain angular-animate.js and include it in your project. It is vital to inject 'ngAnimate' dependency into your module and implement the custom directive in the following manner.

Prior to this step, define a class style:

.myClass {
  background-color: red;
  transition: all 1s;
  -webkit-transition: all 1s ease-in-out;
}

Note the utilization of the $watch method for variable monitoring:

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

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;
    $scope.myValue = item.name;
  }

}).directive("myDir", function ($animate, $timeout) {
  return function (scope, element, attrs) {
    scope.$watch('myValue', function (newValue, oldValue) {

      if (newValue != oldValue) {

        $animate.addClass(element, "myClass").then(function () {
          $timeout(function () { $animate.removeClass(element, "myClass"); });
        });
      }

    }, true);
  }
}); 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular: StaticInjectorError(ExplorationEditorPageModule)[Number]

Currently in the process of transitioning oppia's codebase from AngularJS(1.x) to Angular(2+). I recently migrated a service called UtilsService.ts to the following code snippet: import { Injectable } from '@angular/core'; import { downgrad ...

Utilizing jQuery boilerplate to execute functions

I am currently utilizing jQuery Boilerplate from However, I have encountered an issue where I am unable to call the "openOverlay" function within the "clickEvents" function. Oddly enough, I am able to successfully call "openOverlay" within the "init" fun ...

Does the CSS :not() selector function properly when used with distant descendants?

Check out the official documentation for the CSS3 :not() pseudo-class at this link: http://www.w3.org/TR/css3-selectors/#negation Additionally, you may be interested in the proposed enhancement for CSS Selectors Level 4 found here: http://dev.w3.org ...

What is the best way to enable the user to scroll smoothly while new data is continually being added to the screen?

I'm attempting to develop a chat feature where the scroll automatically moves down when new messages are received by the user. However, I've come across an issue while trying to allow users to manually scroll up. Every time I scroll up and a new ...

The AJAX call fails to refresh the secondary table in CodeIgniter

I have a situation where I need to display data from two tables - car producer and car model, pulled from a database. My goal is to filter the second table to only show cars from a specific producer when that producer is clicked in the first table. I attem ...

Why is AngularJS $http response undefined?

My $http call in AngularJS is returning undefined when I try to access the data in my controller. What could be causing this issue? Despite using .then to handle promises, the data passed to the controller seems to become undefined. Can you help me figure ...

Acquire the content of an interactive website with Python without using the onclick event

I am looking to extract the content of a dynamically generated website after clicking on a specific link. The link is structured as follows: <a onclick="function(); return false" href="#">Link</a> This setup prevents me from directly accessin ...

Avoid losing any entered form information when leaving the page

As I work on creating a datagrid with hundreds of rows, each row features a checkbox that allows users to select items from the grid. I've noticed that users might spend considerable time filtering and searching through the grid, ticking checkboxes a ...

No content returned by Angular Server

I have implemented a factory in angular 1.6 to make GET requests to a Rails 5 server. The factory contains an $http call like this: $http({method: 'GET', url: urlString, params: dataToSend}) .then(function successCallback(response) { ...

What is the best way to maintain scrollbars on mobile devices?

I'm currently building a cross-platform application using Angular 4 that needs to work seamlessly on both mobile and desktop devices. Is there a special trick to prevent the scrollbars from disappearing when viewing this page on a mobile browser? I&ap ...

Troubleshooting inactive CSS hover animation

Greetings! I'm facing an issue with a CSS hover animation. Here are two demos I've created: In the first DEMO, the animation works perfectly. However, in the second DEMO, it doesn't seem to be functioning. On the second demo, there are two ...

The animation isn't loading

I discovered a handy script that displays a waiting message when my form is submitted. I implemented jquery-ui to showcase this message in a dialog box, and it was successful. However, upon customizing the text and adding an animated gif background using C ...

What is the best way to retrieve the file and directory tree structure from git using php?

I am looking to streamline the process of downloading zip files from my public git repository on Bitbucket. Rather than manually creating a download button for each zip file, I want to dynamically generate a PHP page that displays all available zip files a ...

Tool for obfuscating client-side files using node.js

I'm in search of a tool similar to the one found at but in the form of a node.js module, allowing for obfuscation of client-side js files prior to transmission. The tool mentioned above performs various tasks, with its most crucial function being th ...

Modifying the color scheme of Google Maps API V2

I am trying to customize the color of the direction line in Google Maps API. I have checked the documentation, but couldn't find any information on changing the color. Below is my code: function direction() { var txtAddress = document.getElement ...

The JSX in React won't display the modified state on the user interface

In my diary object, I have records of 2 meals function Magicdiary() { const [diary, setDiary] = React.useState<MagicDiaryDay[]>([ { mealName: "Breakfast", ingredient: null }, { mealName: "Lunch", ingredient: null }, ]) ...

What obstacles must be overcome when developing a CSS framework?

Currently, I am delving into the realm of popular CSS frameworks such as Bootstrap and Foundation. While studying them, I have identified aspects that I believe could be enhanced and customized to suit my own projects or potentially for free distribution i ...

What is the best way to create a JQuery click event that applies to every button on my webpage?

I am working on a website settings page where logged-in users can edit the content displayed on the public page. I have a form that uses AJAX to update the content when submitted. My main question is how to modify the code so it can determine which text b ...

The content's div is not extending completely in the horizontal direction

Just starting out with tailwind CSS and struggling a bit with the design aspect due to my lack of CSS skills. Need some assistance troubleshooting my layout, particularly in making sure the div container stretches to fit the screen size properly. The spec ...

When using React / Next.js, the .map() function may not rerender the output based on changes in the state array if the keys remain the same

In my react component, Matches.js, I handle the display of tournament matches sorted by rounds. The data is fetched from a parent component through nextjs SSR and passed as props to the child component. To avoid unnecessary requests upon data changes like ...