'use strict'; /* Directives */ var directives = angular.module('afroApp.directives', []); directives.directive('appVersion', ['version', function(version) { return function(scope, elm, attrs) { elm.text(version); }; }]); directives.directive('ilErrorSrc', [function () { return { link: function (scope, elm, attrs) { elm.bind('error', function() { elm.attr('src', attrs.errorSrc); }); } }; }]); directives.directive('ilFocus', ['$timeout', function ($timeout) { return { link: function (scope, elm) { $timeout(function () { elm.focus(); }, 0); } }; }]); directives.directive('ilForceUpper', ['$parse', function ($parse) { return { require: 'ngModel', link: function (scope, elm, attrs, ctrl) { ctrl.$parsers.push(function(viewValue) { if (viewValue === undefined) { viewValue = ''; } var upperCased = viewValue.toUpperCase(); if (upperCased !== viewValue) { ctrl.$setViewValue(upperCased); ctrl.$render(); } return upperCased; }); } }; }]); directives.directive('ilForceUpperFirstChar', ['$parse', function ($parse) { return { require: 'ngModel', link: function (scope, elm, attrs, ctrl) { ctrl.$parsers.push(function(viewValue) { if (viewValue === undefined) { viewValue = ''; } var firstCharUpperCased = viewValue.charAt(0).toUpperCase() + viewValue.substring(1); if (firstCharUpperCased !== viewValue) { ctrl.$setViewValue(firstCharUpperCased); ctrl.$render(); } return firstCharUpperCased; }); } }; }]); // Validates credit card numbers using jQuery Credit Card Validator (http://jquerycreditcardvalidator.com/) // The attribute value of this directive should be the scope property that you want to use to store the // validation result's 'card_type' object, eg: // Note: Stripe.js has its own validation functions (https://stripe.com/docs/stripe.js#card-validation-helpers) but doesn't add anything apart from CVC // validation (and it's unclear how exactly they validate it). We're currently just checking that the CVC is a 3 or 4 digit number. // The Stripe validation functions also don't let you restrict the permissable card types. directives.directive('ilCreditCard', ['$parse', function($parse) { return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { ctrl.$parsers.push(function(viewValue) { var validationResult = elm.validateCreditCard({accept: ['visa', 'visa_electron', 'mastercard', 'maestro']}); // set the scope property identified by the attribute value to be the card_type var model = $parse(attrs.ilCreditCard); model.assign(scope, validationResult.card_type); if (validationResult.valid) { // it is valid ctrl.$setValidity('creditCard', true); return viewValue; } else { // it is invalid, return undefined (no model update) ctrl.$setValidity('creditCard', false); return undefined; } }); } }; }]); // Validates credit card expiry dates from text inputs // Compatible with AngularUI UI-Utils Mask directive directives.directive('ilCcExpiry', [function() { return { priority: 101, // ui-mask priority is 100 and we want to run after that require: 'ngModel', link: function(scope, elm, attrs, ctrl) { ctrl.$parsers.push(function(viewValue) { if (!(angular.isString(viewValue) && viewValue.length == 4)){ ctrl.$setValidity('ccExpiry', false); return undefined; } var month = Number(viewValue.substring(0, 2)); var year = Number(viewValue.substring(2)); var now = new Date(); var currentYear = now.getFullYear(); var currentYearTwoDigits = Number(String(currentYear).substring(2)); var currentMonth = now.getMonth() + 1; var isYearValid = year >= currentYearTwoDigits; var isMonthValid = month >= 1 && month <= 12 && (year == currentYearTwoDigits ? month >= currentMonth : true); if (isYearValid && isMonthValid) { // it is valid ctrl.$setValidity('ccExpiry', true); return viewValue; } else { // it is invalid, return undefined (no model update) ctrl.$setValidity('ccExpiry', false); return undefined; } }); } }; }]); directives.directive('ilStopEvent', function () { return { restrict: 'A', link: function (scope, element, attr) { element.bind('click', function (e) { e.stopPropagation(); }); } }; }); directives.directive('ilTouchstart', function() { return function(scope, element, attr) { element.on('touchstart', function(event) { scope.$apply(function() { scope.$eval(attr.ilTouchstart); }); }); }; }); directives.directive('ilTouchend', function() { return function(scope, element, attr) { element.on('touchend', function(event) { scope.$apply(function() { scope.$eval(attr.ilTouchend); }); }); }; });