<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <script data-require="angular.js@*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
    <script src="script.js"></script>
    
    <link rel="stylesheet" href="angular-cookie-law.css">

    <script src="angular-cookie-law.js"></script>

  </head>

  <body ng-controller="myCtrl">
    <h2>AngularJS directives in action</h2>
    <p>Click on the image to go to the original image, and click "say hi" to be greeted by each actor.</p>
    
    <div ng-repeat="m in mutants">
      <div actor-tile actor="m"></div>
    </div>
    <cookie-law-banner position="top" message="Your custom message" policy-url="http://link-to-your-policy"></cookie-law-banner>
  </body>

</html>








// Code goes here

angular
  .module('myApp', ['angular-cookie-law']);

angular
  .module('myApp')
  .directive('actorTile', actorTile);

angular
  .module('myApp')
  .controller('myCtrl', myCtrl);
  

function actorTile() {
    return {
      restrict: 'A',
      scope: {
        actor: '='
      },
      replace: true,
      templateUrl: 'actor-tile-template.html',
      link: function (scope, elem, attrs) {
        scope.hi = function () {
          alert('Why hello there, I\'m ' + scope.actor.name + '.');
        };
        elem.find('img').on('click', function () {
          window.open(scope.actor.image);
        });
      }
    };
}

function myCtrl($scope) {
  
  $scope.$on('cookieLaw.accept', function() {
    //callback function
  });

  $scope.mutants = [
    {
      name: 'Wolverine',
      actor: 'Hugh Jackman',
      image: 'https://latimesherocomplex.files.wordpress.com/2030/04/hughjackman4.jpg'
    },
    {
      name: 'Cyclops',
      actor: 'James Marsden',
      image: 'http://s3.amazonaws.com/cmi-niche/assets/pictures/39932/content_James-Marsden-Los-Angeles-Confidential-1.jpg?1411489304'
    },
    {
      name: 'Professor X',
      actor: 'Patrick Stewart',
      image: 'https://pmcdeadline2.files.wordpress.com/2013/01/patrickheadshot.rt__130116211928.jpg'
    }
  ];
}
/* Styles go here */

h3, p {
  padding: 0;
  margin: 0;
}

body {
  font-family: 'Roboto', sans-serif;
}

.actor-tile {
  border: 1px solid lightgray;
  padding: 5px;
  border-radius: 3px;
  box-shadow: 0 0 4px lightgray;
  margin: 10px;
  max-width: 150px;
  float: left;
}

.actor-tile img {
  margin-top: 5px;
  width: 100%;
}

.actor-tile button {
  width: 100%;
}
# Friendly intro to Angular JS directives
This is the code complement for
[Make custom, reusable components with AngularJS directives](https://www.youtube.com/watch?v=7LXN0MzmDsc&index=7&list=PLBFam6bWfknnE_EaG_UTMGSLKPmDw7fgs).

Watch it for a live presentation of how this code was written :)
<div class="actor-tile">
<h3>{{ actor.name }}</h3>
<p>{{ actor.actor }}</p>
<img width="100" ng-src="{{ actor.image }}">
<button ng-click="hi()">say hi</button>
</div>
/**
 * @palmabit/angular-cookie-law - @version v0.5.0 - @author Palmabit Srl<hello@palmabit.com>
 */
.cl-banner {
  background: #000000;
  height: auto;
  min-height: 24px;
  line-height: 24px;
  color: #eeeeee;
  text-align: center;
  padding: 15px 25px;
  z-index: 10000;

  position: fixed;
  left: 0;
  width: 100%;
}

.cl-banner.top {
  top: 0;
}

.cl-banner.bottom {
  bottom: 0;
}

/*
.cl-banner.fixed {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}

.cl-banner.fixed.bottom {
  bottom: 0;
  top: auto;
}
*/

.cl-banner p {
  color: white;
  margin: 0;
  padding: 0;
}

.cl-banner a {
  color: white;
  display: inline-block;
  border-radius: 3px;
  text-decoration: none;
  padding: 0 6px;
  margin: 11px 20px 0 20px;
}

.cl-banner .cl-accept {
  background: #007700;
}

.cl-banner .cl-accept:hover {
  background: #009900;
}

.cl-banner .cl-disable {
  background: #990000;
}

.cl-banner .cl-disable:hover {
  background: #bb0000;
}

.cl-banner .cl-policy {
  background: #0033bb;
}

.cl-banner .cl-policy:hover {
  background: #0055dd;
}
/**
 * @palmabit/angular-cookie-law - @version v0.5.0 - @author Palmabit Srl<hello@palmabit.com>
 */
'use strict';

angular.module('angular-cookie-law', []);
angular.module('angular-cookie-law')

    .value('cookieLawName', '_cle')
    .value('cookieLawAccepted', 'accepted')
    .value('cookieLawDeclined', 'declined');
angular.module('angular-cookie-law')



    .directive('cookieLawBanner', ['$compile', 'CookieLawService', function ($compile, CookieLawService) {
      return {
        restrict: 'EA',
        replace: true,
        scope: {
          position: '@',
          message: '@',
          acceptText: '@',
          declineText: '@',
          policyText: '@',
          policyURL: '@',
          acceptButton: '@',
          declineButton: '@',
          policyButton: '@',
          policyBlank: '@',
          expireDays: '@',
          element: '@',
        },
        link: function (scope, element, attr) {
          var template, options, expireDate;

          scope.$watchGroup([
            'position',
            'message',
            'acceptText',
            'declineText',
            'policyText',
            'policyURL',
            'acceptButton',
            'declineButton',
            'policyButton',
            'policyBlank',
            'expireDays',
            'element',
          ], function() {
            if (CookieLawService.isEnabled()) {
              return;
            }

            options = {
              position: attr.position === 'bottom' ? 'bottom' : 'top', //Position of the banner. (Default: 'top')
              message: attr.message || 'We use cookies to track usage and preferences.', //Message displayed on bar
              acceptButton: attr.acceptButton === 'false' ? false : true, //Set to true to show accept/enable button
              acceptText: attr.acceptText || 'I Understand', //Text on accept/enable button
              declineButton: attr.declineButton || false, //Set to true to show decline/disable button
              declineText: attr.declineText || 'Disable Cookies', //Text on decline/disable button
              policyButton: attr.policyButton || false, //Set to true to show Privacy Policy button
              policyText: attr.policyText || 'Privacy Policy', //Text on Privacy Policy button
              policyURL: attr.policyUrl || '/privacy-policy/', //URL of Privacy Policy
              policyBlank: attr.policyBlank && attr.policyBlank === 'true' ? 'target="_blank"' : '',
              expireDays: attr.expireDays || 365, //Number of days for cookieBar cookie to be stored for
              element: attr.element || 'body' //Element to append/prepend cookieBar to. Remember "." for class or "#" for id.
            };

            //Sets expiration date for cookie
            expireDate = new Date();
            expireDate.setTime(expireDate.getTime() + (options.expireDays * 24 * 60 * 60 * 1000));
            expireDate = expireDate.toGMTString();

            if (options.acceptButton) {
             var acceptButton = '<a href="" class="cl-accept" ng-click="accept()">' + options.acceptText + '</a>';
            }

            if (options.declineButton) {
             var declineButton = ' <a href="" class="cl-disable" ng-click="decline()">' + options.declineText + '</a>';
            }

            if (options.policyButton) {
             var policyButton =
                ' <a href="' + options.policyURL + '" class="cl-policy" ' + options.policyBlank + '>' + options.policyText + '</a>';
            }

            template =
              '<div class="cl-banner ' + options.position + '"><p>' + options.message + '<br>' + acceptButton + declineButton + policyButton + '</p></div>';

            element.html(template);
            $compile(element.contents())(scope);

            scope.accept = function() {
              CookieLawService.accept(expireDate);
              scope.onAccept();
              element.remove();
              scope.onDismiss();
            };

            scope.decline = function() {
              CookieLawService.decline(expireDate);
              scope.onDecline();
              element.remove();
              scope.onDismiss();
            };
          });
        },
        controller: ['$rootScope', '$scope', function ($rootScope, scope) {
          scope.onAccept = function () {
            $rootScope.$broadcast('cookieLaw.accept');
          };

          scope.onDismiss = function () {
            $rootScope.$broadcast('cookieLaw.dismiss');
          };

          scope.onDecline = function () {
            $rootScope.$broadcast('cookieLaw.decline');
          };
        }]
      }
    }]);
angular.module('angular-cookie-law')

    .directive('cookieLawWait', ['CookieLawService', function (CookieLawService) {
      return {
        priority: 1,
        terminal: true,
        restrict: 'EA',
        replace: true,
        template: '<span ng-transclude></span>',
        transclude: true,
        scope: false,
        link: function link(scope, element, attrs, controller, transclude) {
          function loadTransclude () {
            element.html('');

            transclude(scope, function (clone) {
              element.html('');
              element.append(clone);
            });
          }

          if (CookieLawService.isEnabled()) {
            loadTransclude();
          }

          scope.$on('cookieLaw.accept', function () {
            loadTransclude();
          });
        }
      };
    }]);
angular.module('angular-cookie-law')

    .factory('CookieLawService', [
      'CookieService',
      'cookieLawName',
      'cookieLawAccepted',
      'cookieLawDeclined',
      function (CookieService, cookieLawName, cookieLawAccepted, cookieLawDeclined) {
        var accept = function (expireDate) {
          CookieService.set(cookieLawName, cookieLawAccepted + ';expires=' + expireDate);
        };

        var decline = function (expireDate) {
          CookieService.set(cookieLawName, cookieLawDeclined + ';expires=' + expireDate);
        };

        var isEnabled = function () {
          return CookieService.get(cookieLawName) === cookieLawAccepted || CookieService.get(cookieLawName) === cookieLawDeclined;
        };

        var isAccepted = function () {
          return CookieService.get(cookieLawName) === cookieLawAccepted;
        };

        var isDeclined = function () {
          return CookieService.get(cookieLawName) === cookieLawDeclined;
        };

        return {
          accept: accept,
          decline: decline,
          isEnabled: isEnabled,
          isAccepted: isAccepted,
          isDeclined: isDeclined
        }
      }]);
angular.module('angular-cookie-law')

    .factory('CookieService', function () {
      var readCookie = function (key) {
        var nameEQ = key + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
          var c = ca[i];
          while (c.charAt(0) == ' ') c = c.substring(1, c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
      }

      var get = function (key) {
        return readCookie(key);
      };

      var set = function (key, value) {
        document.cookie = key + '=' + value;
      };

      return {
        get: get,
        set: set
      }
    });