Nathan Rabe
Nathan Rabe

Reputation: 665

Visually show Angular scope changes when made programmatically

Is there a way to visually show when a scoped input value is changed programmatically?

I have several input fields that are bound to various ng-model values, and these values change outside the user's control. (The change is tied to a button in the example below for simplicity.)

When the values change, I want the input to change color or show some kind of visual cue to make it obvious that the value isn't the same as a second ago. If there was only one field, this could probably be done with a watch and adding some CSS to the relevant input. However, in production there are hundreds of values, we don't have a mapping of which values are shown in which inputs, and even if we did, many inputs are generated by repeaters, so hand coding countless watches is out.

I was hoping for something like the jQuery highlight effect (http://api.jqueryui.com/highlight-effect/) but at this point, I'd be interested in any visual change at all to see if I can make it work for what I need.

Sample fiddle here: http://jsfiddle.net/cdnaa8ew/1/

angular.module('changeSample', [])
  .controller('SampleController', ['$scope',
    function($scope) {
      $scope.a = 1;
      $scope.b = 2;
      $scope.c = 3;
      $scope.d = 4;
      $scope.e = 5;

      $scope.change = function() {
        var rand = Math.floor(Math.random() * 5);
        if (rand == 0) {
          $scope.a = $scope.a + 1;
        }
        if (rand == 1) {
          $scope.b = $scope.b + 1;
        }
        if (rand == 2) {
          $scope.c = $scope.c + 1;
        }
        if (rand == 3) {
          $scope.d = $scope.d + 1;
        }
        if (rand == 4) {
          $scope.e = $scope.e + 1;
        }
      };
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>

<body ng-app="changeSample">
  <form ng-controller="SampleController">
    <input type="text" ng-model="a" />
    <br/>
    <input type="text" ng-model="b" />
    <br/>
    <input type="text" ng-model="c" />
    <br/>
    <input type="text" ng-model="d" />
    <br/>
    <input type="text" ng-model="e" />
    <br/><span>{{a}}{{b}}{{c}}{{d}}{{e}}</span>

    <br/>
    <button ng-click="change()">Change</button>
  </form>
</body>

Upvotes: 1

Views: 263

Answers (2)

dfsq
dfsq

Reputation: 193271

You can create a simple directive for that which would add a class to changed element. For example:

.directive('highlight', function($timeout) {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs) {
            var className = attrs.highlight || 'highlight';
            scope.$watch(attrs.ngModel, function(newVal, oldVal) {
                if (newVal !== oldVal) {
                    element.addClass(className);
                    $timeout(function() {
                        element.removeClass(className);
                    }, 400);
                }
            });
        }
    };
});

And use it like this:

<input type="text" ng-model="c" highlight />
<input type="text" ng-model="d" highlight="highlight-red" />

Then you can define whatever highlight style want using CSS:

.highlight-red {
    -webkit-transition: background .4s ease;
    transition: background .4s ease;
    background: #FE94B3;
}

Demo: http://jsfiddle.net/cdnaa8ew/3/

Upvotes: 2

Duncan
Duncan

Reputation: 2560

Angular animate can be bound to a number of events such as ng-show and ng-repeat. https://docs.angularjs.org/api/ngAnimate/service/$animate

This would allow you to replicate the jquery highlight effect. Also, check out this related question: ng-animate : Animation when model changes

Upvotes: 0

Related Questions