Search code examples
javascriptangularjsanimationjqlite

Animating a button with AngularJS inside ng-repeat


I have this online shop here that is displaying items, sizes, prices, etc. and I want to add an animation to the .add-to-cart-btn <button> so that each time it is clicked, the button will perform some type of animation. I could do this with jQuery something like:

$(document).ready(function() {
  $('.add-to-cart-btn').on('click', function() {
    $(this).addClass('bounce').delay(1000).removeClass('bounce');
  });
});

but i'm trying to do things the "Angular Way" and I think i'm close. I have a directive here: thanks to This Post

angular.module('ForeverLeather').directive('animateTrigger', ['$animate', function ($animate) {

  return function (scope, elem, attrs) {
    elem.on('click', function (elem) {
      scope.$apply(function() {
        var el = angular.element(document.getElementsByClassName("add-to-cart-btn"));
        var promise = $animate.addClass(el, "bounce");
        promise.then(function () {
          scope.$apply(function() {
            $animate.removeClass(el, "bounce");
          });
        });
      });
    });
  }
}]);

HTML

  <div class="col-md-4 col-sm-6" ng-repeat="item in templateItems">

      <div class="product-img-wrapper">
        <img ng-src="{{item.src}}">
      </div>

      <h3 class="product-header">{{item.name}}</h3>
      <p class="lead product-text">
        {{item.description}}
      </p>

      <div class="product-btn-wrapper">
        <select ng-options="size.size as size.text for size in item.sizes" ng-model="item.selectedItem.size"
                class="form-control" ng-change="getPrice(item, item.selectedItem.size)">
          <option value="" disabled>-- Select to view prices --</option>
        </select>
        <span class="text-left product-price">{{item.selectedItem.price | currency}}</span>
        <button ng-click="addToCart(item.type, item.name, item.selectedItem.size);" 
                class="btn btn-lg btn-success add-to-cart-btn animated" animate-trigger>
          <i class="fa fa-cart-plus"></i>&nbsp; Add To Cart
        </button>
      </div>

    </div>

This works.. well kinda, my problem is that var el = angular.element(document.getElementsByClassName("add-to-cart-btn")); always find the first button on the page with this class name, I need to change this to something like:

var el = angular.element(elem); // invalid
var el = angular.element(this); // invalid

so that I am performing the animation on the currently clicked element instead of the first of the page.


Solution

  • But you already have the element, all you need is

    return function (scope, elem, attrs) {
        elem.on('click', function () {
          scope.$apply(function() {
            var promise = $animate.addClass(elem, "bounce");
            promise.then(function () {
              scope.$apply(function() {
                $animate.removeClass(elem, "bounce");
              });
            });
          });
        });
      }