src/expiration.js
'use strict'
var expiration = require('creditcards').expiration
var month = expiration.month
var year = expiration.year
var ap = require('ap')
exports = module.exports = function ccExp () {
return {
restrict: 'AE',
require: 'ccExp',
controller: CcExpController,
link: function (scope, element, attributes, ccExp) {
ccExp.$watch()
}
}
}
CcExpController.$inject = ['$scope', '$element']
function CcExpController ($scope, $element) {
var nullFormCtrl = {
$setValidity: noop
}
var parentForm = $element.inheritedData('$formController') || nullFormCtrl
var ngModel = {
year: {},
month: {}
}
this.setMonth = function (monthCtrl) {
ngModel.month = monthCtrl
}
this.setYear = function (yearCtrl) {
ngModel.year = yearCtrl
}
function setValidity (exp) {
var expMonth = exp.month
var expYear = exp.year
var valid = (expMonth == null && expYear == null) || !!expMonth && !!expYear && !expiration.isPast(expMonth, expYear)
parentForm.$setValidity('ccExp', valid, $element)
}
this.$watch = function $watchExp () {
$scope.$watch(function watchExp () {
return {
month: ngModel.month.$modelValue,
year: ngModel.year.$modelValue
}
}, setValidity, true)
}
}
var nullCcExp = {
setMonth: noop,
setYear: noop
}
exports.month = function ccExpMonth () {
return {
restrict: 'A',
require: ['ngModel', '^?ccExp'],
compile: function (element, attributes) {
attributes.$set('maxlength', 2)
attributes.$set('pattern', '[0-9]*')
attributes.$set('xAutocompletetype', 'cc-exp-month')
return function (scope, element, attributes, controllers) {
var ngModel = controllers[0]
var ccExp = controllers[1] || nullCcExp
ccExp.setMonth(ngModel)
ngModel.$parsers.unshift(month.parse)
ngModel.$validators.ccExpMonth = function validateExpMonth (value) {
return ngModel.$isEmpty(ngModel.$viewValue) || month.isValid(value)
}
}
}
}
}
exports.year = function ccExpYear () {
return {
restrict: 'A',
require: ['ngModel', '^?ccExp'],
compile: function (element, attributes) {
var fullYear = attributes.fullYear !== undefined
attributes.$set('maxlength', fullYear ? 4 : 2)
attributes.$set('pattern', '[0-9]*')
attributes.$set('xAutocompletetype', 'cc-exp-year')
return function (scope, element, attributes, controllers) {
var ngModel = controllers[0]
var ccExp = controllers[1] || nullCcExp
ccExp.setYear(ngModel)
ngModel.$parsers.unshift(ap.partialRight(year.parse, !fullYear))
ngModel.$formatters.unshift(function formatExpYear (value) {
return value ? year.format(value, !fullYear) : ''
})
ngModel.$validators.ccExpYear = function validateExpYear (value) {
return ngModel.$isEmpty(ngModel.$viewValue) || (year.isValid(value) && !year.isPast(value))
}
}
}
}
}
function noop () {}