diff --git a/card-js.core.min.js b/card-js.core.min.js index 1bbe6cf..e6cb7a3 100644 --- a/card-js.core.min.js +++ b/card-js.core.min.js @@ -1 +1 @@ -function CardJs(elem){this.elem=jQuery(elem),this.captureName=!!this.elem.data("capture-name")&&this.elem.data("capture-name"),this.iconColour=!!this.elem.data("icon-colour")&&this.elem.data("icon-colour"),this.stripe=!!this.elem.data("stripe")&&this.elem.data("stripe"),this.stripe&&(this.captureName=!1),this.initCardNumberInput(),this.initNameInput(),this.initExpiryMonthInput(),this.initExpiryYearInput(),this.initCvcInput(),this.elem.empty(),this.setupCardNumberInput(),this.setupNameInput(),this.setupExpiryInput(),this.setupCvcInput(),this.iconColour&&this.setIconColour(this.iconColour),this.refreshCreditCardTypeIcon()}CardJs.KEYS={0:48,9:57,NUMPAD_0:96,NUMPAD_9:105,DELETE:46,BACKSPACE:8,ARROW_LEFT:37,ARROW_RIGHT:39,ARROW_UP:38,ARROW_DOWN:40,HOME:36,END:35,TAB:9,A:65,X:88,C:67,V:86},CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_VISA_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_JCB_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_AMEX_MASK="XXXX XXXXXX XXXXX",CardJs.CREDIT_CARD_NUMBER_DINERS_MASK="XXXX XXXX XXXX XX",CardJs.prototype.creditCardNumberMask=CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK,CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER="Card number",CardJs.NAME_PLACEHOLDER="Name on card",CardJs.EXPIRY_MASK="XX / XX",CardJs.EXPIRY_PLACEHOLDER="MM / YY",CardJs.EXPIRY_USE_DROPDOWNS=!1,CardJs.EXPIRY_NUMBER_OF_YEARS=10,CardJs.CVC_MASK_3="XXX",CardJs.CVC_MASK_4="XXXX",CardJs.CVC_PLACEHOLDER="CVC",CardJs.CREDIT_CARD_SVG='',CardJs.LOCK_SVG='',CardJs.CALENDAR_SVG='',CardJs.USER_SVG='',CardJs.MAIL_SVG='',CardJs.INFORMATION_SVG='',CardJs.keyCodeFromEvent=function(e){return e.which||e.keyCode},CardJs.keyIsCommandFromEvent=function(e){return e.ctrlKey||e.metaKey},CardJs.keyIsNumber=function(e){return CardJs.keyIsTopNumber(e)||CardJs.keyIsKeypadNumber(e)},CardJs.keyIsTopNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]},CardJs.keyIsKeypadNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9},CardJs.keyIsDelete=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.DELETE},CardJs.keyIsBackspace=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.BACKSPACE},CardJs.keyIsDeletion=function(e){return CardJs.keyIsDelete(e)||CardJs.keyIsBackspace(e)},CardJs.keyIsArrow=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.ARROW_LEFT&&keyCode<=CardJs.KEYS.ARROW_DOWN},CardJs.keyIsNavigation=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode==CardJs.KEYS.HOME||keyCode==CardJs.KEYS.END},CardJs.keyIsKeyboardCommand=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return CardJs.keyIsCommandFromEvent(e)&&(keyCode==CardJs.KEYS.A||keyCode==CardJs.KEYS.X||keyCode==CardJs.KEYS.C||keyCode==CardJs.KEYS.V)},CardJs.keyIsTab=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.TAB},CardJs.copyAllElementAttributes=function(source,destination){$.each(source[0].attributes,function(idx,attr){destination.attr(attr.nodeName,attr.nodeValue)})},CardJs.numbersOnlyString=function(string){for(var numbersOnlyString="",i=0;imask.length)return 0;for(var i=0;imask.length)return 0;for(var i=0;i=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]?keyCode-CardJs.KEYS[0]:keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9?keyCode-CardJs.KEYS.NUMPAD_0:null},CardJs.handleMaskedNumberInputKey=function(e,mask){CardJs.filterNumberOnlyKey(e);var keyCode=e.which||e.keyCode,element=e.target,caretStart=CardJs.caretStartPosition(element),caretEnd=CardJs.caretEndPosition(element),normalisedStartCaretPosition=CardJs.normaliseCaretPosition(mask,caretStart),normalisedEndCaretPosition=CardJs.normaliseCaretPosition(mask,caretEnd),newCaretPosition=caretStart,isNumber=CardJs.keyIsNumber(e),isDelete=CardJs.keyIsDelete(e),isBackspace=CardJs.keyIsBackspace(e);if(isNumber||isDelete||isBackspace){e.preventDefault();var rawText=$(element).val(),numbersOnly=CardJs.numbersOnlyString(rawText),digit=CardJs.digitFromKeyCode(keyCode),rangeHighlighted=normalisedEndCaretPosition>normalisedStartCaretPosition;rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedEndCaretPosition)),caretStart!=mask.length&&(isNumber&&rawText.length<=mask.length&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+digit+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=Math.max(CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+1),CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+2)-1)),isDelete&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedStartCaretPosition+1))),0!=caretStart&&isBackspace&&!rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition-1)+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition-1)),$(element).val(CardJs.applyFormatMask(numbersOnly,mask)),CardJs.setCaretPosition(element,newCaretPosition)}},CardJs.handleCreditCardNumberKey=function(e,cardMask){CardJs.handleMaskedNumberInputKey(e,cardMask)},CardJs.handleCreditCardNumberChange=function(e){},CardJs.handleExpiryKey=function(e){CardJs.handleMaskedNumberInputKey(e,CardJs.EXPIRY_MASK)},CardJs.prototype.getCardNumber=function(){return this.cardNumberInput.val()},CardJs.prototype.getCardType=function(){return CardJs.cardTypeFromNumber(this.getCardNumber())},CardJs.prototype.getName=function(){return this.nameInput.val()},CardJs.prototype.getExpiryMonth=function(){return this.expiryMonthInput.val()},CardJs.prototype.getExpiryYear=function(){return this.expiryYearInput.val()},CardJs.prototype.getCvc=function(){return this.cvcInput.val()},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.refreshCreditCardTypeIcon=function(){this.setCardTypeIconFromNumber(CardJs.numbersOnlyString(this.cardNumberInput.val()))},CardJs.prototype.refreshCreditCardNumberFormat=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cardNumberInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cardNumberInput).val(formattedNumber)},CardJs.prototype.refreshExpiryMonthYearInput=function(){var numbersOnly=CardJs.numbersOnlyString($(this.expiryMonthYearInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,CardJs.EXPIRY_MASK);$(this.expiryMonthYearInput).val(formattedNumber)},CardJs.prototype.refreshCvc=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cvcInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cvcInput).val(formattedNumber)},CardJs.prototype.setCardTypeIconFromNumber=function(number){switch(CardJs.cardTypeFromNumber(number)){case"Visa Electron":case"Visa":this.setCardTypeAsVisa();break;case"Mastercard":this.setCardTypeAsMasterCard();break;case"AMEX":this.setCardTypeAsAmericanExpress();break;case"Discover":this.setCardTypeAsDiscover();break;case"Diners - Carte Blanche":case"Diners":this.setCardTypeAsDiners();break;case"JCB":this.setCardTypeAsJcb();break;default:this.clearCardType()}},CardJs.prototype.setCardMask=function(cardMask){this.creditCardNumberMask=cardMask,this.cardNumberInput.attr("maxlength",cardMask.length)},CardJs.prototype.setCvc3=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length)},CardJs.prototype.setCvc4=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_4.length)},CardJs.prototype.clearCardTypeIcon=function(){this.elem.find(".card-number-wrapper .card-type-icon").removeClass("show")},CardJs.prototype.setCardTypeIconAsVisa=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show visa")},CardJs.prototype.setCardTypeIconAsMasterCard=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show master-card")},CardJs.prototype.setCardTypeIconAsAmericanExpress=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show american-express")},CardJs.prototype.setCardTypeIconAsDiscover=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show discover")},CardJs.prototype.setCardTypeIconAsDiners=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show diners")},CardJs.prototype.setCardTypeIconAsJcb=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show jcb")},CardJs.prototype.clearCardType=function(){this.clearCardTypeIcon(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsVisa=function(){this.setCardTypeIconAsVisa(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_VISA_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsMasterCard=function(){this.setCardTypeIconAsMasterCard(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsAmericanExpress=function(){this.setCardTypeIconAsAmericanExpress(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_AMEX_MASK),this.setCvc4()},CardJs.prototype.setCardTypeAsDiscover=function(){this.setCardTypeIconAsDiscover(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsDiners=function(){this.setCardTypeIconAsDiners(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DINERS_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsJcb=function(){this.setCardTypeIconAsJcb(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_JCB_MASK),this.setCvc3()},CardJs.prototype.initCardNumberInput=function(){this.cardNumberInput=CardJs.detachOrCreateElement(this.elem,".card-number",""),CardJs.elementHasAttribute(this.cardNumberInput,"name")||this.cardNumberInput.attr("name","card-number"),CardJs.elementHasAttribute(this.cardNumberInput,"placeholder")||this.cardNumberInput.attr("placeholder",CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER),this.cardNumberInput.attr("type","tel"),this.cardNumberInput.attr("maxlength",this.creditCardNumberMask.length),this.cardNumberInput.attr("x-autocompletetype","cc-number"),this.cardNumberInput.attr("autocompletetype","cc-number"),this.cardNumberInput.attr("autocorrect","off"),this.cardNumberInput.attr("spellcheck","off"),this.cardNumberInput.attr("autocapitalize","off");var $this=this;this.cardNumberInput.keydown(function(e){CardJs.handleCreditCardNumberKey(e,$this.creditCardNumberMask)}),this.cardNumberInput.keyup(function(){$this.refreshCreditCardTypeIcon()}),this.cardNumberInput.on("paste",function(){setTimeout(function(){$this.refreshCreditCardNumberFormat(),$this.refreshCreditCardTypeIcon()},1)})},CardJs.prototype.initNameInput=function(){this.captureName=null!=this.elem.find(".name")[0],this.nameInput=CardJs.detachOrCreateElement(this.elem,".name",""),CardJs.elementHasAttribute(this.nameInput,"name")||this.nameInput.attr("name","card-number"),CardJs.elementHasAttribute(this.nameInput,"placeholder")||this.nameInput.attr("placeholder",CardJs.NAME_PLACEHOLDER)},CardJs.prototype.initExpiryMonthInput=function(){this.expiryMonthInput=CardJs.detachOrCreateElement(this.elem,".expiry-month","")},CardJs.prototype.initExpiryYearInput=function(){this.expiryYearInput=CardJs.detachOrCreateElement(this.elem,".expiry-year","")},CardJs.prototype.initCvcInput=function(){this.cvcInput=CardJs.detachOrCreateElement(this.elem,".cvc",""),CardJs.elementHasAttribute(this.cvcInput,"placeholder")||this.cvcInput.attr("placeholder",CardJs.CVC_PLACEHOLDER),this.cvcInput.attr("type","tel"),this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length),this.cvcInput.attr("x-autocompletetype","cc-csc"),this.cvcInput.attr("autocompletetype","cc-csc"),this.cvcInput.attr("autocorrect","off"),this.cvcInput.attr("spellcheck","off"),this.cvcInput.attr("autocapitalize","off");var $this=this;this.cvcInput.keydown(CardJs.filterNumberOnlyKey),this.cvcInput.on("paste",function(){setTimeout(function(){$this.refreshCvc()},1)})},CardJs.prototype.setupCardNumberInput=function(){this.stripe&&this.cardNumberInput.attr("data-stripe","number"),this.elem.append("
");var wrapper=this.elem.find(".card-number-wrapper");wrapper.append(this.cardNumberInput),wrapper.append("
"),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CREDIT_CARD_SVG)},CardJs.prototype.setupNameInput=function(){if(this.captureName){this.elem.append("
");var wrapper=this.elem.find(".name-wrapper");wrapper.append(this.nameInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.USER_SVG)}},CardJs.prototype.setupExpiryInput=function(){this.elem.append("
");var expiryInput,wrapper=this.elem.find(".expiry-wrapper");if(this.EXPIRY_USE_DROPDOWNS){expiryInput=$("
");var expiryMonthNew=$(""),expiryMonthOld=this.expiryMonthInput;CardJs.copyAllElementAttributes(expiryMonthOld,expiryMonthNew),this.expiryMonthInput.remove(),this.expiryMonthInput=expiryMonthNew;for(var expiryYearNew=$(""),currentYear=parseInt((new Date).getFullYear().toString().substring(2,4)),i=0;i"+currentYear+""),currentYear=(currentYear+1)%100;var expiryYearOld=this.expiryYearInput;CardJs.copyAllElementAttributes(expiryYearOld,expiryYearNew),this.expiryYearInput.remove(),this.expiryYearInput=expiryYearNew,expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}else{expiryInput=$("
"),"hidden"!=this.expiryMonthInput.attr("type")&&this.expiryMonthInput.attr("type","hidden"),"hidden"!=this.expiryYearInput.attr("type")&&this.expiryYearInput.attr("type","hidden"),this.stripe&&(this.expiryMonthInput.attr("data-stripe","exp-month"),this.expiryYearInput.attr("data-stripe","exp-year")),this.expiryMonthYearInput=CardJs.detachOrCreateElement(this.elem,".expiry",""),CardJs.elementHasAttribute(this.expiryMonthYearInput,"placeholder")||this.expiryMonthYearInput.attr("placeholder",CardJs.EXPIRY_PLACEHOLDER),this.expiryMonthYearInput.attr("type","tel"),this.expiryMonthYearInput.attr("maxlength",CardJs.EXPIRY_MASK.length),this.expiryMonthYearInput.attr("x-autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocorrect","off"),this.expiryMonthYearInput.attr("spellcheck","off"),this.expiryMonthYearInput.attr("autocapitalize","off");var $this=this;this.expiryMonthYearInput.keydown(function(e){CardJs.handleExpiryKey(e);var val=$this.expiryMonthYearInput.val();1==val.length&&parseInt(val)>1&&CardJs.keyIsNumber(e)&&$this.expiryMonthYearInput.val(CardJs.applyFormatMask("0"+val,CardJs.EXPIRY_MASK)),$this.EXPIRY_USE_DROPDOWNS||null==$this.expiryMonthYearInput||($this.expiryMonthInput.val($this.expiryMonth()),$this.expiryYearInput.val(7==val.length?val.substr(5,2):null))}),this.expiryMonthYearInput.blur(function(){$this.refreshExpiryMonthValidation()}),this.expiryMonthYearInput.on("paste",function(){setTimeout(function(){$this.refreshExpiryMonthYearInput()},1)}),expiryInput.append(this.expiryMonthYearInput),expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}wrapper.append(expiryInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CALENDAR_SVG)},CardJs.prototype.setupCvcInput=function(){this.stripe&&this.cvcInput.attr("data-stripe","cvc"),this.elem.append("
");var wrapper=this.elem.find(".cvc-wrapper");wrapper.append(this.cvcInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.LOCK_SVG)},CardJs.prototype.expiryMonth=function(){if(!this.EXPIRY_USE_DROPDOWNS&&null!=this.expiryMonthYearInput){var val=this.expiryMonthYearInput.val();return val.length>=2?parseInt(val.substr(0,2)):null}return null},CardJs.prototype.refreshExpiryMonthValidation=function(){CardJs.isExpiryValid(this.getExpiryMonth(),this.getExpiryYear())?this.setExpiryMonthAsValid():this.setExpiryMonthAsInvalid()},CardJs.prototype.setExpiryMonthAsValid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().removeClass("has-error")},CardJs.prototype.setExpiryMonthAsInvalid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().addClass("has-error")},CardJs.elementHasAttribute=function(element,attributeName){var attr=$(element).attr(attributeName);return void 0!==attr&&!1!==attr},CardJs.detachOrCreateElement=function(parentElement,selector,html){var element=parentElement.find(selector);return element[0]?element.detach():element=$(html),element},CardJs.isValidMonth=function(expiryMonth){return expiryMonth>=1&&expiryMonth<=12},CardJs.isExpiryValid=function(month,year){var today=new Date,currentMonth=today.getMonth()+1,currentYear=""+today.getFullYear();return 2==(""+year).length&&(year=currentYear.substring(0,2)+""+year),currentMonth=parseInt(currentMonth),currentYear=parseInt(currentYear),month=parseInt(month),year=parseInt(year),CardJs.isValidMonth(month)&&(year>currentYear||year==currentYear&&month>=currentMonth)},CardJs.prototype.constructor=CardJs;try{exports.CardJs=CardJs}catch(e){} \ No newline at end of file +function CardJs(elem){this.elem=jQuery(elem),this.captureName=!!this.elem.data("capture-name")&&this.elem.data("capture-name"),this.iconColour=!!this.elem.data("icon-colour")&&this.elem.data("icon-colour"),this.stripe=!!this.elem.data("stripe")&&this.elem.data("stripe"),this.stripe&&(this.captureName=!1),this.initCardNumberInput(),this.initNameInput(),this.initExpiryMonthInput(),this.initExpiryYearInput(),this.initCvcInput(),this.elem.empty(),this.setupCardNumberInput(),this.setupNameInput(),this.setupExpiryInput(),this.setupCvcInput(),this.iconColour&&this.setIconColour(this.iconColour),this.refreshCreditCardTypeIcon()}CardJs.KEYS={0:48,9:57,NUMPAD_0:96,NUMPAD_9:105,DELETE:46,BACKSPACE:8,ARROW_LEFT:37,ARROW_RIGHT:39,ARROW_UP:38,ARROW_DOWN:40,HOME:36,END:35,TAB:9,A:65,X:88,C:67,V:86},CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_VISA_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_JCB_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_AMEX_MASK="XXXX XXXXXX XXXXX",CardJs.CREDIT_CARD_NUMBER_DINERS_MASK="XXXX XXXX XXXX XX",CardJs.prototype.creditCardNumberMask=CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK,CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER="Card number",CardJs.NAME_PLACEHOLDER="Name on card",CardJs.EXPIRY_MASK="XX / XX",CardJs.EXPIRY_PLACEHOLDER="MM / YY",CardJs.EXPIRY_USE_DROPDOWNS=!1,CardJs.EXPIRY_NUMBER_OF_YEARS=10,CardJs.CVC_MASK_3="XXX",CardJs.CVC_MASK_4="XXXX",CardJs.CVC_PLACEHOLDER="CVC",CardJs.CREDIT_CARD_SVG='',CardJs.LOCK_SVG='',CardJs.CALENDAR_SVG='',CardJs.USER_SVG='',CardJs.MAIL_SVG='',CardJs.INFORMATION_SVG='',CardJs.keyCodeFromEvent=function(e){return e.which||e.keyCode},CardJs.keyIsCommandFromEvent=function(e){return e.ctrlKey||e.metaKey},CardJs.keyIsNumber=function(e){return CardJs.keyIsTopNumber(e)||CardJs.keyIsKeypadNumber(e)},CardJs.keyIsTopNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]},CardJs.keyIsKeypadNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9},CardJs.keyIsDelete=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.DELETE},CardJs.keyIsBackspace=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.BACKSPACE},CardJs.keyIsDeletion=function(e){return CardJs.keyIsDelete(e)||CardJs.keyIsBackspace(e)},CardJs.keyIsArrow=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.ARROW_LEFT&&keyCode<=CardJs.KEYS.ARROW_DOWN},CardJs.keyIsNavigation=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode==CardJs.KEYS.HOME||keyCode==CardJs.KEYS.END},CardJs.keyIsKeyboardCommand=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return CardJs.keyIsCommandFromEvent(e)&&(keyCode==CardJs.KEYS.A||keyCode==CardJs.KEYS.X||keyCode==CardJs.KEYS.C||keyCode==CardJs.KEYS.V)},CardJs.keyIsTab=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.TAB},CardJs.copyAllElementAttributes=function(source,destination){$.each(source[0].attributes,function(idx,attr){destination.attr(attr.nodeName,attr.nodeValue)})},CardJs.numbersOnlyString=function(string){for(var numbersOnlyString="",i=0;imask.length)return 0;for(var i=0;imask.length)return 0;for(var i=0;i=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]?keyCode-CardJs.KEYS[0]:keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9?keyCode-CardJs.KEYS.NUMPAD_0:null},CardJs.handleMaskedNumberInputKey=function(e,mask){CardJs.filterNumberOnlyKey(e);var keyCode=e.which||e.keyCode,element=e.target,caretStart=CardJs.caretStartPosition(element),caretEnd=CardJs.caretEndPosition(element),normalisedStartCaretPosition=CardJs.normaliseCaretPosition(mask,caretStart),normalisedEndCaretPosition=CardJs.normaliseCaretPosition(mask,caretEnd),newCaretPosition=caretStart,isNumber=CardJs.keyIsNumber(e),isDelete=CardJs.keyIsDelete(e),isBackspace=CardJs.keyIsBackspace(e);if(isNumber||isDelete||isBackspace){e.preventDefault();var rawText=$(element).val(),numbersOnly=CardJs.numbersOnlyString(rawText),digit=CardJs.digitFromKeyCode(keyCode),rangeHighlighted=normalisedEndCaretPosition>normalisedStartCaretPosition;rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedEndCaretPosition)),caretStart!=mask.length&&(isNumber&&rawText.length<=mask.length&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+digit+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=Math.max(CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+1),CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+2)-1)),isDelete&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedStartCaretPosition+1))),0!=caretStart&&isBackspace&&!rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition-1)+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition-1)),$(element).val(CardJs.applyFormatMask(numbersOnly,mask)),CardJs.setCaretPosition(element,newCaretPosition)}},CardJs.handleCreditCardNumberKey=function(e,cardMask){CardJs.handleMaskedNumberInputKey(e,cardMask)},CardJs.handleCreditCardNumberChange=function(e){},CardJs.handleExpiryKey=function(e){CardJs.handleMaskedNumberInputKey(e,CardJs.EXPIRY_MASK)},CardJs.prototype.getCardNumber=function(){return this.cardNumberInput.val()},CardJs.prototype.getCardType=function(){return CardJs.cardTypeFromNumber(this.getCardNumber())},CardJs.prototype.getName=function(){return this.nameInput.val()},CardJs.prototype.getExpiryMonth=function(){return this.expiryMonthInput.val()},CardJs.prototype.getExpiryYear=function(){return this.expiryYearInput.val()},CardJs.prototype.getCvc=function(){return this.cvcInput.val()},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.refreshCreditCardTypeIcon=function(){this.setCardTypeIconFromNumber(CardJs.numbersOnlyString(this.cardNumberInput.val()))},CardJs.prototype.refreshCreditCardNumberFormat=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cardNumberInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cardNumberInput).val(formattedNumber)},CardJs.prototype.refreshExpiryMonthYearInput=function(){var numbersOnly=CardJs.numbersOnlyString($(this.expiryMonthYearInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,CardJs.EXPIRY_MASK);$(this.expiryMonthYearInput).val(formattedNumber)},CardJs.prototype.refreshCvc=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cvcInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cvcInput).val(formattedNumber)},CardJs.prototype.setCardTypeIconFromNumber=function(number){switch(CardJs.cardTypeFromNumber(number)){case"Visa Electron":case"Visa":this.setCardTypeAsVisa();break;case"Mastercard":this.setCardTypeAsMasterCard();break;case"AMEX":this.setCardTypeAsAmericanExpress();break;case"Discover":this.setCardTypeAsDiscover();break;case"Diners - Carte Blanche":case"Diners":this.setCardTypeAsDiners();break;case"JCB":this.setCardTypeAsJcb();break;default:this.clearCardType()}},CardJs.prototype.setCardMask=function(cardMask){this.creditCardNumberMask=cardMask,this.cardNumberInput.attr("maxlength",cardMask.length)},CardJs.prototype.setCvc3=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length)},CardJs.prototype.setCvc4=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_4.length)},CardJs.prototype.clearCardTypeIcon=function(){this.elem.find(".card-number-wrapper .card-type-icon").removeClass("show")},CardJs.prototype.setCardTypeIconAsVisa=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show visa")},CardJs.prototype.setCardTypeIconAsMasterCard=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show master-card")},CardJs.prototype.setCardTypeIconAsAmericanExpress=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show american-express")},CardJs.prototype.setCardTypeIconAsDiscover=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show discover")},CardJs.prototype.setCardTypeIconAsDiners=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show diners")},CardJs.prototype.setCardTypeIconAsJcb=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show jcb")},CardJs.prototype.clearCardType=function(){this.clearCardTypeIcon(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsVisa=function(){this.setCardTypeIconAsVisa(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_VISA_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsMasterCard=function(){this.setCardTypeIconAsMasterCard(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsAmericanExpress=function(){this.setCardTypeIconAsAmericanExpress(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_AMEX_MASK),this.setCvc4()},CardJs.prototype.setCardTypeAsDiscover=function(){this.setCardTypeIconAsDiscover(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsDiners=function(){this.setCardTypeIconAsDiners(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DINERS_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsJcb=function(){this.setCardTypeIconAsJcb(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_JCB_MASK),this.setCvc3()},CardJs.prototype.initCardNumberInput=function(){this.cardNumberInput=CardJs.detachOrCreateElement(this.elem,".card-number",""),CardJs.elementHasAttribute(this.cardNumberInput,"name")||this.cardNumberInput.attr("name","card-number"),CardJs.elementHasAttribute(this.cardNumberInput,"placeholder")||this.cardNumberInput.attr("placeholder",CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER),this.cardNumberInput.attr("type","tel"),this.cardNumberInput.attr("maxlength",this.creditCardNumberMask.length),this.cardNumberInput.attr("x-autocompletetype","cc-number"),this.cardNumberInput.attr("autocompletetype","cc-number"),this.cardNumberInput.attr("autocorrect","off"),this.cardNumberInput.attr("spellcheck","off"),this.cardNumberInput.attr("autocapitalize","off");var $this=this;this.cardNumberInput.keydown(function(e){CardJs.handleCreditCardNumberKey(e,$this.creditCardNumberMask)}),this.cardNumberInput.keyup(function(){$this.refreshCreditCardTypeIcon()}),this.cardNumberInput.on("paste",function(){setTimeout(function(){$this.refreshCreditCardNumberFormat(),$this.refreshCreditCardTypeIcon()},1)})},CardJs.prototype.initNameInput=function(){this.captureName=null!=this.elem.find(".name")[0],this.nameInput=CardJs.detachOrCreateElement(this.elem,".name",""),CardJs.elementHasAttribute(this.nameInput,"name")||this.nameInput.attr("name","card-number"),CardJs.elementHasAttribute(this.nameInput,"placeholder")||this.nameInput.attr("placeholder",CardJs.NAME_PLACEHOLDER)},CardJs.prototype.initExpiryMonthInput=function(){this.expiryMonthInput=CardJs.detachOrCreateElement(this.elem,".expiry-month","")},CardJs.prototype.initExpiryYearInput=function(){this.expiryYearInput=CardJs.detachOrCreateElement(this.elem,".expiry-year","")},CardJs.prototype.initCvcInput=function(){this.cvcInput=CardJs.detachOrCreateElement(this.elem,".cvc",""),CardJs.elementHasAttribute(this.cvcInput,"placeholder")||this.cvcInput.attr("placeholder",CardJs.CVC_PLACEHOLDER),this.cvcInput.attr("type","tel"),this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length),this.cvcInput.attr("x-autocompletetype","cc-csc"),this.cvcInput.attr("autocompletetype","cc-csc"),this.cvcInput.attr("autocorrect","off"),this.cvcInput.attr("spellcheck","off"),this.cvcInput.attr("autocapitalize","off");var $this=this;this.cvcInput.keydown(CardJs.filterNumberOnlyKey),this.cvcInput.on("paste",function(){setTimeout(function(){$this.refreshCvc()},1)})},CardJs.prototype.setupCardNumberInput=function(){this.stripe&&this.cardNumberInput.attr("data-stripe","number"),this.elem.append("
");var wrapper=this.elem.find(".card-number-wrapper");wrapper.append(this.cardNumberInput),wrapper.append("
"),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CREDIT_CARD_SVG)},CardJs.prototype.setupNameInput=function(){if(this.captureName){this.elem.append("
");var wrapper=this.elem.find(".name-wrapper");wrapper.append(this.nameInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.USER_SVG)}},CardJs.prototype.setupExpiryInput=function(){this.elem.append("
");var expiryInput,wrapper=this.elem.find(".expiry-wrapper");if(this.EXPIRY_USE_DROPDOWNS){expiryInput=$("
");var expiryMonthNew=$(""),expiryMonthOld=this.expiryMonthInput;CardJs.copyAllElementAttributes(expiryMonthOld,expiryMonthNew),this.expiryMonthInput.remove(),this.expiryMonthInput=expiryMonthNew;for(var expiryYearNew=$(""),currentYear=parseInt((new Date).getFullYear().toString().substring(2,4)),i=0;i"+currentYear+""),currentYear=(currentYear+1)%100;var expiryYearOld=this.expiryYearInput;CardJs.copyAllElementAttributes(expiryYearOld,expiryYearNew),this.expiryYearInput.remove(),this.expiryYearInput=expiryYearNew,expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}else{expiryInput=$("
"),"hidden"!=this.expiryMonthInput.attr("type")&&this.expiryMonthInput.attr("type","hidden"),"hidden"!=this.expiryYearInput.attr("type")&&this.expiryYearInput.attr("type","hidden"),this.stripe&&(this.expiryMonthInput.attr("data-stripe","exp-month"),this.expiryYearInput.attr("data-stripe","exp-year")),this.expiryMonthYearInput=CardJs.detachOrCreateElement(this.elem,".expiry",""),CardJs.elementHasAttribute(this.expiryMonthYearInput,"placeholder")||this.expiryMonthYearInput.attr("placeholder",CardJs.EXPIRY_PLACEHOLDER),this.expiryMonthYearInput.attr("type","tel"),this.expiryMonthYearInput.attr("maxlength",CardJs.EXPIRY_MASK.length),this.expiryMonthYearInput.attr("x-autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocorrect","off"),this.expiryMonthYearInput.attr("spellcheck","off"),this.expiryMonthYearInput.attr("autocapitalize","off");var $this=this;this.expiryMonthYearInput.keydown(function(e){CardJs.handleExpiryKey(e);var val=$this.expiryMonthYearInput.val();1==val.length&&parseInt(val)>1&&CardJs.keyIsNumber(e)&&$this.expiryMonthYearInput.val(CardJs.applyFormatMask("0"+val,CardJs.EXPIRY_MASK)),$this.EXPIRY_USE_DROPDOWNS||null==$this.expiryMonthYearInput||($this.expiryMonthInput.val($this.expiryMonth()),$this.expiryYearInput.val(7==val.length?val.substr(5,2):null))}),this.expiryMonthYearInput.on("blur input",function(e){$this.updateHiddenExpiryFields()}),this.cardNumberInput.on("blur input",function(e){$this.updateHiddenExpiryFields()}),this.expiryMonthYearInput.blur(function(){$this.refreshExpiryMonthValidation()}),this.expiryMonthYearInput.on("paste",function(){setTimeout(function(){$this.refreshExpiryMonthYearInput()},1)}),expiryInput.append(this.expiryMonthYearInput),expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}wrapper.append(expiryInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CALENDAR_SVG)},CardJs.prototype.updateHiddenExpiryFields=function(){var vals=this.expiryMonthYearInput.val().match(/^\s*(\d+)\s*\/\s*(\d+)\s*$/);if(null!=vals){var month=vals[1],year=vals[2];this.expiryMonthInput.val(month),this.expiryYearInput.val(year),this.expiryMonthYearInput.val(month+" / "+year)}},CardJs.prototype.setupCvcInput=function(){this.stripe&&this.cvcInput.attr("data-stripe","cvc"),this.elem.append("
");var wrapper=this.elem.find(".cvc-wrapper");wrapper.append(this.cvcInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.LOCK_SVG)},CardJs.prototype.expiryMonth=function(){if(!this.EXPIRY_USE_DROPDOWNS&&null!=this.expiryMonthYearInput){var val=this.expiryMonthYearInput.val();return val.length>=2?parseInt(val.substr(0,2)):null}return null},CardJs.prototype.refreshExpiryMonthValidation=function(){CardJs.isExpiryValid(this.getExpiryMonth(),this.getExpiryYear())?this.setExpiryMonthAsValid():this.setExpiryMonthAsInvalid()},CardJs.prototype.setExpiryMonthAsValid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().removeClass("has-error")},CardJs.prototype.setExpiryMonthAsInvalid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().addClass("has-error")},CardJs.elementHasAttribute=function(element,attributeName){var attr=$(element).attr(attributeName);return void 0!==attr&&!1!==attr},CardJs.detachOrCreateElement=function(parentElement,selector,html){var element=parentElement.find(selector);return element[0]?element.detach():element=$(html),element},CardJs.isValidMonth=function(expiryMonth){return expiryMonth>=1&&expiryMonth<=12},CardJs.isExpiryValid=function(month,year){var today=new Date,currentMonth=today.getMonth()+1,currentYear=""+today.getFullYear();return 2==(""+year).length&&(year=currentYear.substring(0,2)+""+year),currentMonth=parseInt(currentMonth),currentYear=parseInt(currentYear),month=parseInt(month),year=parseInt(year),CardJs.isValidMonth(month)&&(year>currentYear||year==currentYear&&month>=currentMonth)},CardJs.prototype.constructor=CardJs;try{exports.CardJs=CardJs}catch(e){} \ No newline at end of file diff --git a/card-js.min.js b/card-js.min.js index 05a6732..605bee3 100644 --- a/card-js.min.js +++ b/card-js.min.js @@ -1 +1 @@ -function CardJs(elem){this.elem=jQuery(elem),this.captureName=!!this.elem.data("capture-name")&&this.elem.data("capture-name"),this.iconColour=!!this.elem.data("icon-colour")&&this.elem.data("icon-colour"),this.stripe=!!this.elem.data("stripe")&&this.elem.data("stripe"),this.stripe&&(this.captureName=!1),this.initCardNumberInput(),this.initNameInput(),this.initExpiryMonthInput(),this.initExpiryYearInput(),this.initCvcInput(),this.elem.empty(),this.setupCardNumberInput(),this.setupNameInput(),this.setupExpiryInput(),this.setupCvcInput(),this.iconColour&&this.setIconColour(this.iconColour),this.refreshCreditCardTypeIcon()}!function($){var methods={init:function(){return this.data("cardjs",new CardJs(this)),this},cardNumber:function(){return this.data("cardjs").getCardNumber()},cardType:function(){return this.data("cardjs").getCardType()},name:function(){return this.data("cardjs").getName()},expiryMonth:function(){return this.data("cardjs").getExpiryMonth()},expiryYear:function(){return this.data("cardjs").getExpiryYear()},cvc:function(){return this.data("cardjs").getCvc()}};$.fn.CardJs=function(methodOrOptions){return methods[methodOrOptions]?methods[methodOrOptions].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof methodOrOptions&&methodOrOptions?void $.error("Method "+methodOrOptions+" does not exist on jQuery.CardJs"):methods.init.apply(this,arguments)}}(jQuery),$(function(){$(".card-js").each(function(i,obj){$(obj).CardJs()})}),CardJs.KEYS={0:48,9:57,NUMPAD_0:96,NUMPAD_9:105,DELETE:46,BACKSPACE:8,ARROW_LEFT:37,ARROW_RIGHT:39,ARROW_UP:38,ARROW_DOWN:40,HOME:36,END:35,TAB:9,A:65,X:88,C:67,V:86},CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_VISA_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_JCB_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_AMEX_MASK="XXXX XXXXXX XXXXX",CardJs.CREDIT_CARD_NUMBER_DINERS_MASK="XXXX XXXX XXXX XX",CardJs.prototype.creditCardNumberMask=CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK,CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER="Card number",CardJs.NAME_PLACEHOLDER="Name on card",CardJs.EXPIRY_MASK="XX / XX",CardJs.EXPIRY_PLACEHOLDER="MM / YY",CardJs.EXPIRY_USE_DROPDOWNS=!1,CardJs.EXPIRY_NUMBER_OF_YEARS=10,CardJs.CVC_MASK_3="XXX",CardJs.CVC_MASK_4="XXXX",CardJs.CVC_PLACEHOLDER="CVC",CardJs.CREDIT_CARD_SVG='',CardJs.LOCK_SVG='',CardJs.CALENDAR_SVG='',CardJs.USER_SVG='',CardJs.MAIL_SVG='',CardJs.INFORMATION_SVG='',CardJs.keyCodeFromEvent=function(e){return e.which||e.keyCode},CardJs.keyIsCommandFromEvent=function(e){return e.ctrlKey||e.metaKey},CardJs.keyIsNumber=function(e){return CardJs.keyIsTopNumber(e)||CardJs.keyIsKeypadNumber(e)},CardJs.keyIsTopNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]},CardJs.keyIsKeypadNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9},CardJs.keyIsDelete=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.DELETE},CardJs.keyIsBackspace=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.BACKSPACE},CardJs.keyIsDeletion=function(e){return CardJs.keyIsDelete(e)||CardJs.keyIsBackspace(e)},CardJs.keyIsArrow=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.ARROW_LEFT&&keyCode<=CardJs.KEYS.ARROW_DOWN},CardJs.keyIsNavigation=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode==CardJs.KEYS.HOME||keyCode==CardJs.KEYS.END},CardJs.keyIsKeyboardCommand=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return CardJs.keyIsCommandFromEvent(e)&&(keyCode==CardJs.KEYS.A||keyCode==CardJs.KEYS.X||keyCode==CardJs.KEYS.C||keyCode==CardJs.KEYS.V)},CardJs.keyIsTab=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.TAB},CardJs.copyAllElementAttributes=function(source,destination){$.each(source[0].attributes,function(idx,attr){destination.attr(attr.nodeName,attr.nodeValue)})},CardJs.numbersOnlyString=function(string){for(var numbersOnlyString="",i=0;imask.length)return 0;for(var i=0;imask.length)return 0;for(var i=0;i=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]?keyCode-CardJs.KEYS[0]:keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9?keyCode-CardJs.KEYS.NUMPAD_0:null},CardJs.handleMaskedNumberInputKey=function(e,mask){CardJs.filterNumberOnlyKey(e);var keyCode=e.which||e.keyCode,element=e.target,caretStart=CardJs.caretStartPosition(element),caretEnd=CardJs.caretEndPosition(element),normalisedStartCaretPosition=CardJs.normaliseCaretPosition(mask,caretStart),normalisedEndCaretPosition=CardJs.normaliseCaretPosition(mask,caretEnd),newCaretPosition=caretStart,isNumber=CardJs.keyIsNumber(e),isDelete=CardJs.keyIsDelete(e),isBackspace=CardJs.keyIsBackspace(e);if(isNumber||isDelete||isBackspace){e.preventDefault();var rawText=$(element).val(),numbersOnly=CardJs.numbersOnlyString(rawText),digit=CardJs.digitFromKeyCode(keyCode),rangeHighlighted=normalisedEndCaretPosition>normalisedStartCaretPosition;rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedEndCaretPosition)),caretStart!=mask.length&&(isNumber&&rawText.length<=mask.length&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+digit+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=Math.max(CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+1),CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+2)-1)),isDelete&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedStartCaretPosition+1))),0!=caretStart&&isBackspace&&!rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition-1)+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition-1)),$(element).val(CardJs.applyFormatMask(numbersOnly,mask)),CardJs.setCaretPosition(element,newCaretPosition)}},CardJs.handleCreditCardNumberKey=function(e,cardMask){CardJs.handleMaskedNumberInputKey(e,cardMask)},CardJs.handleCreditCardNumberChange=function(e){},CardJs.handleExpiryKey=function(e){CardJs.handleMaskedNumberInputKey(e,CardJs.EXPIRY_MASK)},CardJs.prototype.getCardNumber=function(){return this.cardNumberInput.val()},CardJs.prototype.getCardType=function(){return CardJs.cardTypeFromNumber(this.getCardNumber())},CardJs.prototype.getName=function(){return this.nameInput.val()},CardJs.prototype.getExpiryMonth=function(){return this.expiryMonthInput.val()},CardJs.prototype.getExpiryYear=function(){return this.expiryYearInput.val()},CardJs.prototype.getCvc=function(){return this.cvcInput.val()},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.refreshCreditCardTypeIcon=function(){this.setCardTypeIconFromNumber(CardJs.numbersOnlyString(this.cardNumberInput.val()))},CardJs.prototype.refreshCreditCardNumberFormat=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cardNumberInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cardNumberInput).val(formattedNumber)},CardJs.prototype.refreshExpiryMonthYearInput=function(){var numbersOnly=CardJs.numbersOnlyString($(this.expiryMonthYearInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,CardJs.EXPIRY_MASK);$(this.expiryMonthYearInput).val(formattedNumber)},CardJs.prototype.refreshCvc=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cvcInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cvcInput).val(formattedNumber)},CardJs.prototype.setCardTypeIconFromNumber=function(number){switch(CardJs.cardTypeFromNumber(number)){case"Visa Electron":case"Visa":this.setCardTypeAsVisa();break;case"Mastercard":this.setCardTypeAsMasterCard();break;case"AMEX":this.setCardTypeAsAmericanExpress();break;case"Discover":this.setCardTypeAsDiscover();break;case"Diners - Carte Blanche":case"Diners":this.setCardTypeAsDiners();break;case"JCB":this.setCardTypeAsJcb();break;default:this.clearCardType()}},CardJs.prototype.setCardMask=function(cardMask){this.creditCardNumberMask=cardMask,this.cardNumberInput.attr("maxlength",cardMask.length)},CardJs.prototype.setCvc3=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length)},CardJs.prototype.setCvc4=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_4.length)},CardJs.prototype.clearCardTypeIcon=function(){this.elem.find(".card-number-wrapper .card-type-icon").removeClass("show")},CardJs.prototype.setCardTypeIconAsVisa=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show visa")},CardJs.prototype.setCardTypeIconAsMasterCard=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show master-card")},CardJs.prototype.setCardTypeIconAsAmericanExpress=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show american-express")},CardJs.prototype.setCardTypeIconAsDiscover=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show discover")},CardJs.prototype.setCardTypeIconAsDiners=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show diners")},CardJs.prototype.setCardTypeIconAsJcb=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show jcb")},CardJs.prototype.clearCardType=function(){this.clearCardTypeIcon(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsVisa=function(){this.setCardTypeIconAsVisa(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_VISA_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsMasterCard=function(){this.setCardTypeIconAsMasterCard(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsAmericanExpress=function(){this.setCardTypeIconAsAmericanExpress(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_AMEX_MASK),this.setCvc4()},CardJs.prototype.setCardTypeAsDiscover=function(){this.setCardTypeIconAsDiscover(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsDiners=function(){this.setCardTypeIconAsDiners(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DINERS_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsJcb=function(){this.setCardTypeIconAsJcb(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_JCB_MASK),this.setCvc3()},CardJs.prototype.initCardNumberInput=function(){this.cardNumberInput=CardJs.detachOrCreateElement(this.elem,".card-number",""),CardJs.elementHasAttribute(this.cardNumberInput,"name")||this.cardNumberInput.attr("name","card-number"),CardJs.elementHasAttribute(this.cardNumberInput,"placeholder")||this.cardNumberInput.attr("placeholder",CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER),this.cardNumberInput.attr("type","tel"),this.cardNumberInput.attr("maxlength",this.creditCardNumberMask.length),this.cardNumberInput.attr("x-autocompletetype","cc-number"),this.cardNumberInput.attr("autocompletetype","cc-number"),this.cardNumberInput.attr("autocorrect","off"),this.cardNumberInput.attr("spellcheck","off"),this.cardNumberInput.attr("autocapitalize","off");var $this=this;this.cardNumberInput.keydown(function(e){CardJs.handleCreditCardNumberKey(e,$this.creditCardNumberMask)}),this.cardNumberInput.keyup(function(){$this.refreshCreditCardTypeIcon()}),this.cardNumberInput.on("paste",function(){setTimeout(function(){$this.refreshCreditCardNumberFormat(),$this.refreshCreditCardTypeIcon()},1)})},CardJs.prototype.initNameInput=function(){this.captureName=null!=this.elem.find(".name")[0],this.nameInput=CardJs.detachOrCreateElement(this.elem,".name",""),CardJs.elementHasAttribute(this.nameInput,"name")||this.nameInput.attr("name","card-number"),CardJs.elementHasAttribute(this.nameInput,"placeholder")||this.nameInput.attr("placeholder",CardJs.NAME_PLACEHOLDER)},CardJs.prototype.initExpiryMonthInput=function(){this.expiryMonthInput=CardJs.detachOrCreateElement(this.elem,".expiry-month","")},CardJs.prototype.initExpiryYearInput=function(){this.expiryYearInput=CardJs.detachOrCreateElement(this.elem,".expiry-year","")},CardJs.prototype.initCvcInput=function(){this.cvcInput=CardJs.detachOrCreateElement(this.elem,".cvc",""),CardJs.elementHasAttribute(this.cvcInput,"placeholder")||this.cvcInput.attr("placeholder",CardJs.CVC_PLACEHOLDER),this.cvcInput.attr("type","tel"),this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length),this.cvcInput.attr("x-autocompletetype","cc-csc"),this.cvcInput.attr("autocompletetype","cc-csc"),this.cvcInput.attr("autocorrect","off"),this.cvcInput.attr("spellcheck","off"),this.cvcInput.attr("autocapitalize","off");var $this=this;this.cvcInput.keydown(CardJs.filterNumberOnlyKey),this.cvcInput.on("paste",function(){setTimeout(function(){$this.refreshCvc()},1)})},CardJs.prototype.setupCardNumberInput=function(){this.stripe&&this.cardNumberInput.attr("data-stripe","number"),this.elem.append("
");var wrapper=this.elem.find(".card-number-wrapper");wrapper.append(this.cardNumberInput),wrapper.append("
"),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CREDIT_CARD_SVG)},CardJs.prototype.setupNameInput=function(){if(this.captureName){this.elem.append("
");var wrapper=this.elem.find(".name-wrapper");wrapper.append(this.nameInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.USER_SVG)}},CardJs.prototype.setupExpiryInput=function(){this.elem.append("
");var expiryInput,wrapper=this.elem.find(".expiry-wrapper");if(this.EXPIRY_USE_DROPDOWNS){expiryInput=$("
");var expiryMonthNew=$(""),expiryMonthOld=this.expiryMonthInput;CardJs.copyAllElementAttributes(expiryMonthOld,expiryMonthNew),this.expiryMonthInput.remove(),this.expiryMonthInput=expiryMonthNew;for(var expiryYearNew=$(""),currentYear=parseInt((new Date).getFullYear().toString().substring(2,4)),i=0;i"+currentYear+""),currentYear=(currentYear+1)%100;var expiryYearOld=this.expiryYearInput;CardJs.copyAllElementAttributes(expiryYearOld,expiryYearNew),this.expiryYearInput.remove(),this.expiryYearInput=expiryYearNew,expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}else{expiryInput=$("
"),"hidden"!=this.expiryMonthInput.attr("type")&&this.expiryMonthInput.attr("type","hidden"),"hidden"!=this.expiryYearInput.attr("type")&&this.expiryYearInput.attr("type","hidden"),this.stripe&&(this.expiryMonthInput.attr("data-stripe","exp-month"),this.expiryYearInput.attr("data-stripe","exp-year")),this.expiryMonthYearInput=CardJs.detachOrCreateElement(this.elem,".expiry",""),CardJs.elementHasAttribute(this.expiryMonthYearInput,"placeholder")||this.expiryMonthYearInput.attr("placeholder",CardJs.EXPIRY_PLACEHOLDER),this.expiryMonthYearInput.attr("type","tel"),this.expiryMonthYearInput.attr("maxlength",CardJs.EXPIRY_MASK.length),this.expiryMonthYearInput.attr("x-autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocorrect","off"),this.expiryMonthYearInput.attr("spellcheck","off"),this.expiryMonthYearInput.attr("autocapitalize","off");var $this=this;this.expiryMonthYearInput.keydown(function(e){CardJs.handleExpiryKey(e);var val=$this.expiryMonthYearInput.val();1==val.length&&parseInt(val)>1&&CardJs.keyIsNumber(e)&&$this.expiryMonthYearInput.val(CardJs.applyFormatMask("0"+val,CardJs.EXPIRY_MASK)),$this.EXPIRY_USE_DROPDOWNS||null==$this.expiryMonthYearInput||($this.expiryMonthInput.val($this.expiryMonth()),$this.expiryYearInput.val(7==val.length?val.substr(5,2):null))}),this.expiryMonthYearInput.blur(function(){$this.refreshExpiryMonthValidation()}),this.expiryMonthYearInput.on("paste",function(){setTimeout(function(){$this.refreshExpiryMonthYearInput()},1)}),expiryInput.append(this.expiryMonthYearInput),expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}wrapper.append(expiryInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CALENDAR_SVG)},CardJs.prototype.setupCvcInput=function(){this.stripe&&this.cvcInput.attr("data-stripe","cvc"),this.elem.append("
");var wrapper=this.elem.find(".cvc-wrapper");wrapper.append(this.cvcInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.LOCK_SVG)},CardJs.prototype.expiryMonth=function(){if(!this.EXPIRY_USE_DROPDOWNS&&null!=this.expiryMonthYearInput){var val=this.expiryMonthYearInput.val();return val.length>=2?parseInt(val.substr(0,2)):null}return null},CardJs.prototype.refreshExpiryMonthValidation=function(){CardJs.isExpiryValid(this.getExpiryMonth(),this.getExpiryYear())?this.setExpiryMonthAsValid():this.setExpiryMonthAsInvalid()},CardJs.prototype.setExpiryMonthAsValid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().removeClass("has-error")},CardJs.prototype.setExpiryMonthAsInvalid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().addClass("has-error")},CardJs.elementHasAttribute=function(element,attributeName){var attr=$(element).attr(attributeName);return void 0!==attr&&!1!==attr},CardJs.detachOrCreateElement=function(parentElement,selector,html){var element=parentElement.find(selector);return element[0]?element.detach():element=$(html),element},CardJs.isValidMonth=function(expiryMonth){return expiryMonth>=1&&expiryMonth<=12},CardJs.isExpiryValid=function(month,year){var today=new Date,currentMonth=today.getMonth()+1,currentYear=""+today.getFullYear();return 2==(""+year).length&&(year=currentYear.substring(0,2)+""+year),currentMonth=parseInt(currentMonth),currentYear=parseInt(currentYear),month=parseInt(month),year=parseInt(year),CardJs.isValidMonth(month)&&(year>currentYear||year==currentYear&&month>=currentMonth)},CardJs.prototype.constructor=CardJs;try{exports.CardJs=CardJs}catch(e){} \ No newline at end of file +function CardJs(elem){this.elem=jQuery(elem),this.captureName=!!this.elem.data("capture-name")&&this.elem.data("capture-name"),this.iconColour=!!this.elem.data("icon-colour")&&this.elem.data("icon-colour"),this.stripe=!!this.elem.data("stripe")&&this.elem.data("stripe"),this.stripe&&(this.captureName=!1),this.initCardNumberInput(),this.initNameInput(),this.initExpiryMonthInput(),this.initExpiryYearInput(),this.initCvcInput(),this.elem.empty(),this.setupCardNumberInput(),this.setupNameInput(),this.setupExpiryInput(),this.setupCvcInput(),this.iconColour&&this.setIconColour(this.iconColour),this.refreshCreditCardTypeIcon()}!function($){var methods={init:function(){return this.data("cardjs",new CardJs(this)),this},cardNumber:function(){return this.data("cardjs").getCardNumber()},cardType:function(){return this.data("cardjs").getCardType()},name:function(){return this.data("cardjs").getName()},expiryMonth:function(){return this.data("cardjs").getExpiryMonth()},expiryYear:function(){return this.data("cardjs").getExpiryYear()},cvc:function(){return this.data("cardjs").getCvc()}};$.fn.CardJs=function(methodOrOptions){return methods[methodOrOptions]?methods[methodOrOptions].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof methodOrOptions&&methodOrOptions?void $.error("Method "+methodOrOptions+" does not exist on jQuery.CardJs"):methods.init.apply(this,arguments)}}(jQuery),$(function(){$(".card-js").each(function(i,obj){$(obj).CardJs()})}),CardJs.KEYS={0:48,9:57,NUMPAD_0:96,NUMPAD_9:105,DELETE:46,BACKSPACE:8,ARROW_LEFT:37,ARROW_RIGHT:39,ARROW_UP:38,ARROW_DOWN:40,HOME:36,END:35,TAB:9,A:65,X:88,C:67,V:86},CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_VISA_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_JCB_MASK="XXXX XXXX XXXX XXXX",CardJs.CREDIT_CARD_NUMBER_AMEX_MASK="XXXX XXXXXX XXXXX",CardJs.CREDIT_CARD_NUMBER_DINERS_MASK="XXXX XXXX XXXX XX",CardJs.prototype.creditCardNumberMask=CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK,CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER="Card number",CardJs.NAME_PLACEHOLDER="Name on card",CardJs.EXPIRY_MASK="XX / XX",CardJs.EXPIRY_PLACEHOLDER="MM / YY",CardJs.EXPIRY_USE_DROPDOWNS=!1,CardJs.EXPIRY_NUMBER_OF_YEARS=10,CardJs.CVC_MASK_3="XXX",CardJs.CVC_MASK_4="XXXX",CardJs.CVC_PLACEHOLDER="CVC",CardJs.CREDIT_CARD_SVG='',CardJs.LOCK_SVG='',CardJs.CALENDAR_SVG='',CardJs.USER_SVG='',CardJs.MAIL_SVG='',CardJs.INFORMATION_SVG='',CardJs.keyCodeFromEvent=function(e){return e.which||e.keyCode},CardJs.keyIsCommandFromEvent=function(e){return e.ctrlKey||e.metaKey},CardJs.keyIsNumber=function(e){return CardJs.keyIsTopNumber(e)||CardJs.keyIsKeypadNumber(e)},CardJs.keyIsTopNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]},CardJs.keyIsKeypadNumber=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9},CardJs.keyIsDelete=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.DELETE},CardJs.keyIsBackspace=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.BACKSPACE},CardJs.keyIsDeletion=function(e){return CardJs.keyIsDelete(e)||CardJs.keyIsBackspace(e)},CardJs.keyIsArrow=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode>=CardJs.KEYS.ARROW_LEFT&&keyCode<=CardJs.KEYS.ARROW_DOWN},CardJs.keyIsNavigation=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return keyCode==CardJs.KEYS.HOME||keyCode==CardJs.KEYS.END},CardJs.keyIsKeyboardCommand=function(e){var keyCode=CardJs.keyCodeFromEvent(e);return CardJs.keyIsCommandFromEvent(e)&&(keyCode==CardJs.KEYS.A||keyCode==CardJs.KEYS.X||keyCode==CardJs.KEYS.C||keyCode==CardJs.KEYS.V)},CardJs.keyIsTab=function(e){return CardJs.keyCodeFromEvent(e)==CardJs.KEYS.TAB},CardJs.copyAllElementAttributes=function(source,destination){$.each(source[0].attributes,function(idx,attr){destination.attr(attr.nodeName,attr.nodeValue)})},CardJs.numbersOnlyString=function(string){for(var numbersOnlyString="",i=0;imask.length)return 0;for(var i=0;imask.length)return 0;for(var i=0;i=CardJs.KEYS[0]&&keyCode<=CardJs.KEYS[9]?keyCode-CardJs.KEYS[0]:keyCode>=CardJs.KEYS.NUMPAD_0&&keyCode<=CardJs.KEYS.NUMPAD_9?keyCode-CardJs.KEYS.NUMPAD_0:null},CardJs.handleMaskedNumberInputKey=function(e,mask){CardJs.filterNumberOnlyKey(e);var keyCode=e.which||e.keyCode,element=e.target,caretStart=CardJs.caretStartPosition(element),caretEnd=CardJs.caretEndPosition(element),normalisedStartCaretPosition=CardJs.normaliseCaretPosition(mask,caretStart),normalisedEndCaretPosition=CardJs.normaliseCaretPosition(mask,caretEnd),newCaretPosition=caretStart,isNumber=CardJs.keyIsNumber(e),isDelete=CardJs.keyIsDelete(e),isBackspace=CardJs.keyIsBackspace(e);if(isNumber||isDelete||isBackspace){e.preventDefault();var rawText=$(element).val(),numbersOnly=CardJs.numbersOnlyString(rawText),digit=CardJs.digitFromKeyCode(keyCode),rangeHighlighted=normalisedEndCaretPosition>normalisedStartCaretPosition;rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedEndCaretPosition)),caretStart!=mask.length&&(isNumber&&rawText.length<=mask.length&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+digit+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=Math.max(CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+1),CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition+2)-1)),isDelete&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition)+numbersOnly.slice(normalisedStartCaretPosition+1))),0!=caretStart&&isBackspace&&!rangeHighlighted&&(numbersOnly=numbersOnly.slice(0,normalisedStartCaretPosition-1)+numbersOnly.slice(normalisedStartCaretPosition),newCaretPosition=CardJs.denormaliseCaretPosition(mask,normalisedStartCaretPosition-1)),$(element).val(CardJs.applyFormatMask(numbersOnly,mask)),CardJs.setCaretPosition(element,newCaretPosition)}},CardJs.handleCreditCardNumberKey=function(e,cardMask){CardJs.handleMaskedNumberInputKey(e,cardMask)},CardJs.handleCreditCardNumberChange=function(e){},CardJs.handleExpiryKey=function(e){CardJs.handleMaskedNumberInputKey(e,CardJs.EXPIRY_MASK)},CardJs.prototype.getCardNumber=function(){return this.cardNumberInput.val()},CardJs.prototype.getCardType=function(){return CardJs.cardTypeFromNumber(this.getCardNumber())},CardJs.prototype.getName=function(){return this.nameInput.val()},CardJs.prototype.getExpiryMonth=function(){return this.expiryMonthInput.val()},CardJs.prototype.getExpiryYear=function(){return this.expiryYearInput.val()},CardJs.prototype.getCvc=function(){return this.cvcInput.val()},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.setIconColour=function(colour){this.elem.find(".icon .svg").css({fill:colour})},CardJs.prototype.refreshCreditCardTypeIcon=function(){this.setCardTypeIconFromNumber(CardJs.numbersOnlyString(this.cardNumberInput.val()))},CardJs.prototype.refreshCreditCardNumberFormat=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cardNumberInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cardNumberInput).val(formattedNumber)},CardJs.prototype.refreshExpiryMonthYearInput=function(){var numbersOnly=CardJs.numbersOnlyString($(this.expiryMonthYearInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,CardJs.EXPIRY_MASK);$(this.expiryMonthYearInput).val(formattedNumber)},CardJs.prototype.refreshCvc=function(){var numbersOnly=CardJs.numbersOnlyString($(this.cvcInput).val()),formattedNumber=CardJs.applyFormatMask(numbersOnly,this.creditCardNumberMask);$(this.cvcInput).val(formattedNumber)},CardJs.prototype.setCardTypeIconFromNumber=function(number){switch(CardJs.cardTypeFromNumber(number)){case"Visa Electron":case"Visa":this.setCardTypeAsVisa();break;case"Mastercard":this.setCardTypeAsMasterCard();break;case"AMEX":this.setCardTypeAsAmericanExpress();break;case"Discover":this.setCardTypeAsDiscover();break;case"Diners - Carte Blanche":case"Diners":this.setCardTypeAsDiners();break;case"JCB":this.setCardTypeAsJcb();break;default:this.clearCardType()}},CardJs.prototype.setCardMask=function(cardMask){this.creditCardNumberMask=cardMask,this.cardNumberInput.attr("maxlength",cardMask.length)},CardJs.prototype.setCvc3=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length)},CardJs.prototype.setCvc4=function(){this.cvcInput.attr("maxlength",CardJs.CVC_MASK_4.length)},CardJs.prototype.clearCardTypeIcon=function(){this.elem.find(".card-number-wrapper .card-type-icon").removeClass("show")},CardJs.prototype.setCardTypeIconAsVisa=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show visa")},CardJs.prototype.setCardTypeIconAsMasterCard=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show master-card")},CardJs.prototype.setCardTypeIconAsAmericanExpress=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show american-express")},CardJs.prototype.setCardTypeIconAsDiscover=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show discover")},CardJs.prototype.setCardTypeIconAsDiners=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show diners")},CardJs.prototype.setCardTypeIconAsJcb=function(){this.elem.find(".card-number-wrapper .card-type-icon").attr("class","card-type-icon show jcb")},CardJs.prototype.clearCardType=function(){this.clearCardTypeIcon(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DEFAULT_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsVisa=function(){this.setCardTypeIconAsVisa(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_VISA_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsMasterCard=function(){this.setCardTypeIconAsMasterCard(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_MASTERCARD_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsAmericanExpress=function(){this.setCardTypeIconAsAmericanExpress(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_AMEX_MASK),this.setCvc4()},CardJs.prototype.setCardTypeAsDiscover=function(){this.setCardTypeIconAsDiscover(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DISCOVER_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsDiners=function(){this.setCardTypeIconAsDiners(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_DINERS_MASK),this.setCvc3()},CardJs.prototype.setCardTypeAsJcb=function(){this.setCardTypeIconAsJcb(),this.setCardMask(CardJs.CREDIT_CARD_NUMBER_JCB_MASK),this.setCvc3()},CardJs.prototype.initCardNumberInput=function(){this.cardNumberInput=CardJs.detachOrCreateElement(this.elem,".card-number",""),CardJs.elementHasAttribute(this.cardNumberInput,"name")||this.cardNumberInput.attr("name","card-number"),CardJs.elementHasAttribute(this.cardNumberInput,"placeholder")||this.cardNumberInput.attr("placeholder",CardJs.CREDIT_CARD_NUMBER_PLACEHOLDER),this.cardNumberInput.attr("type","tel"),this.cardNumberInput.attr("maxlength",this.creditCardNumberMask.length),this.cardNumberInput.attr("x-autocompletetype","cc-number"),this.cardNumberInput.attr("autocompletetype","cc-number"),this.cardNumberInput.attr("autocorrect","off"),this.cardNumberInput.attr("spellcheck","off"),this.cardNumberInput.attr("autocapitalize","off");var $this=this;this.cardNumberInput.keydown(function(e){CardJs.handleCreditCardNumberKey(e,$this.creditCardNumberMask)}),this.cardNumberInput.keyup(function(){$this.refreshCreditCardTypeIcon()}),this.cardNumberInput.on("paste",function(){setTimeout(function(){$this.refreshCreditCardNumberFormat(),$this.refreshCreditCardTypeIcon()},1)})},CardJs.prototype.initNameInput=function(){this.captureName=null!=this.elem.find(".name")[0],this.nameInput=CardJs.detachOrCreateElement(this.elem,".name",""),CardJs.elementHasAttribute(this.nameInput,"name")||this.nameInput.attr("name","card-number"),CardJs.elementHasAttribute(this.nameInput,"placeholder")||this.nameInput.attr("placeholder",CardJs.NAME_PLACEHOLDER)},CardJs.prototype.initExpiryMonthInput=function(){this.expiryMonthInput=CardJs.detachOrCreateElement(this.elem,".expiry-month","")},CardJs.prototype.initExpiryYearInput=function(){this.expiryYearInput=CardJs.detachOrCreateElement(this.elem,".expiry-year","")},CardJs.prototype.initCvcInput=function(){this.cvcInput=CardJs.detachOrCreateElement(this.elem,".cvc",""),CardJs.elementHasAttribute(this.cvcInput,"placeholder")||this.cvcInput.attr("placeholder",CardJs.CVC_PLACEHOLDER),this.cvcInput.attr("type","tel"),this.cvcInput.attr("maxlength",CardJs.CVC_MASK_3.length),this.cvcInput.attr("x-autocompletetype","cc-csc"),this.cvcInput.attr("autocompletetype","cc-csc"),this.cvcInput.attr("autocorrect","off"),this.cvcInput.attr("spellcheck","off"),this.cvcInput.attr("autocapitalize","off");var $this=this;this.cvcInput.keydown(CardJs.filterNumberOnlyKey),this.cvcInput.on("paste",function(){setTimeout(function(){$this.refreshCvc()},1)})},CardJs.prototype.setupCardNumberInput=function(){this.stripe&&this.cardNumberInput.attr("data-stripe","number"),this.elem.append("
");var wrapper=this.elem.find(".card-number-wrapper");wrapper.append(this.cardNumberInput),wrapper.append("
"),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CREDIT_CARD_SVG)},CardJs.prototype.setupNameInput=function(){if(this.captureName){this.elem.append("
");var wrapper=this.elem.find(".name-wrapper");wrapper.append(this.nameInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.USER_SVG)}},CardJs.prototype.setupExpiryInput=function(){this.elem.append("
");var expiryInput,wrapper=this.elem.find(".expiry-wrapper");if(this.EXPIRY_USE_DROPDOWNS){expiryInput=$("
");var expiryMonthNew=$(""),expiryMonthOld=this.expiryMonthInput;CardJs.copyAllElementAttributes(expiryMonthOld,expiryMonthNew),this.expiryMonthInput.remove(),this.expiryMonthInput=expiryMonthNew;for(var expiryYearNew=$(""),currentYear=parseInt((new Date).getFullYear().toString().substring(2,4)),i=0;i"+currentYear+""),currentYear=(currentYear+1)%100;var expiryYearOld=this.expiryYearInput;CardJs.copyAllElementAttributes(expiryYearOld,expiryYearNew),this.expiryYearInput.remove(),this.expiryYearInput=expiryYearNew,expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}else{expiryInput=$("
"),"hidden"!=this.expiryMonthInput.attr("type")&&this.expiryMonthInput.attr("type","hidden"),"hidden"!=this.expiryYearInput.attr("type")&&this.expiryYearInput.attr("type","hidden"),this.stripe&&(this.expiryMonthInput.attr("data-stripe","exp-month"),this.expiryYearInput.attr("data-stripe","exp-year")),this.expiryMonthYearInput=CardJs.detachOrCreateElement(this.elem,".expiry",""),CardJs.elementHasAttribute(this.expiryMonthYearInput,"placeholder")||this.expiryMonthYearInput.attr("placeholder",CardJs.EXPIRY_PLACEHOLDER),this.expiryMonthYearInput.attr("type","tel"),this.expiryMonthYearInput.attr("maxlength",CardJs.EXPIRY_MASK.length),this.expiryMonthYearInput.attr("x-autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocompletetype","cc-exp"),this.expiryMonthYearInput.attr("autocorrect","off"),this.expiryMonthYearInput.attr("spellcheck","off"),this.expiryMonthYearInput.attr("autocapitalize","off");var $this=this;this.expiryMonthYearInput.keydown(function(e){CardJs.handleExpiryKey(e);var val=$this.expiryMonthYearInput.val();1==val.length&&parseInt(val)>1&&CardJs.keyIsNumber(e)&&$this.expiryMonthYearInput.val(CardJs.applyFormatMask("0"+val,CardJs.EXPIRY_MASK)),$this.EXPIRY_USE_DROPDOWNS||null==$this.expiryMonthYearInput||($this.expiryMonthInput.val($this.expiryMonth()),$this.expiryYearInput.val(7==val.length?val.substr(5,2):null))}),this.expiryMonthYearInput.on("blur input",function(e){$this.updateHiddenExpiryFields()}),this.cardNumberInput.on("blur input",function(e){$this.updateHiddenExpiryFields()}),this.expiryMonthYearInput.blur(function(){$this.refreshExpiryMonthValidation()}),this.expiryMonthYearInput.on("paste",function(){setTimeout(function(){$this.refreshExpiryMonthYearInput()},1)}),expiryInput.append(this.expiryMonthYearInput),expiryInput.append(this.expiryMonthInput),expiryInput.append(this.expiryYearInput)}wrapper.append(expiryInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.CALENDAR_SVG)},CardJs.prototype.updateHiddenExpiryFields=function(){var vals=this.expiryMonthYearInput.val().match(/^\s*(\d+)\s*\/\s*(\d+)\s*$/);if(null!=vals){var month=vals[1],year=vals[2];this.expiryMonthInput.val(month),this.expiryYearInput.val(year),this.expiryMonthYearInput.val(month+" / "+year)}},CardJs.prototype.setupCvcInput=function(){this.stripe&&this.cvcInput.attr("data-stripe","cvc"),this.elem.append("
");var wrapper=this.elem.find(".cvc-wrapper");wrapper.append(this.cvcInput),wrapper.append("
"),wrapper.find(".icon").append(CardJs.LOCK_SVG)},CardJs.prototype.expiryMonth=function(){if(!this.EXPIRY_USE_DROPDOWNS&&null!=this.expiryMonthYearInput){var val=this.expiryMonthYearInput.val();return val.length>=2?parseInt(val.substr(0,2)):null}return null},CardJs.prototype.refreshExpiryMonthValidation=function(){CardJs.isExpiryValid(this.getExpiryMonth(),this.getExpiryYear())?this.setExpiryMonthAsValid():this.setExpiryMonthAsInvalid()},CardJs.prototype.setExpiryMonthAsValid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().removeClass("has-error")},CardJs.prototype.setExpiryMonthAsInvalid=function(){this.EXPIRY_USE_DROPDOWNS||this.expiryMonthYearInput.parent().addClass("has-error")},CardJs.elementHasAttribute=function(element,attributeName){var attr=$(element).attr(attributeName);return void 0!==attr&&!1!==attr},CardJs.detachOrCreateElement=function(parentElement,selector,html){var element=parentElement.find(selector);return element[0]?element.detach():element=$(html),element},CardJs.isValidMonth=function(expiryMonth){return expiryMonth>=1&&expiryMonth<=12},CardJs.isExpiryValid=function(month,year){var today=new Date,currentMonth=today.getMonth()+1,currentYear=""+today.getFullYear();return 2==(""+year).length&&(year=currentYear.substring(0,2)+""+year),currentMonth=parseInt(currentMonth),currentYear=parseInt(currentYear),month=parseInt(month),year=parseInt(year),CardJs.isValidMonth(month)&&(year>currentYear||year==currentYear&&month>=currentMonth)},CardJs.prototype.constructor=CardJs;try{exports.CardJs=CardJs}catch(e){} \ No newline at end of file diff --git a/package.json b/package.json index 30b2cdf..0755d05 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "Colin Stannard " ], "description": "Credit Card input form with validation", - "version": "1.1.1", + "version": "1.1.2", "main": "card-js.min.js", "moduleType": [ "globals" diff --git a/src/js/card-js.js b/src/js/card-js.js index 173d733..b205542 100644 --- a/src/js/card-js.js +++ b/src/js/card-js.js @@ -1266,6 +1266,13 @@ CardJs.prototype.setupExpiryInput = function() { } }); + this.expiryMonthYearInput.on('blur input', function(e) { + $this.updateHiddenExpiryFields(); + }); + this.cardNumberInput.on('blur input', function(e) { + $this.updateHiddenExpiryFields(); + }); + this.expiryMonthYearInput.blur(function() { $this.refreshExpiryMonthValidation(); }); @@ -1288,6 +1295,18 @@ CardJs.prototype.setupExpiryInput = function() { }; +CardJs.prototype.updateHiddenExpiryFields = function () { + var vals = this.expiryMonthYearInput.val().match(/^\s*(\d+)\s*\/\s*(\d+)\s*$/); + if (vals != null) { + var month = vals[1]; + var year = vals[2]; + this.expiryMonthInput.val(month); + this.expiryYearInput.val(year); + this.expiryMonthYearInput.val(month + " / " + year); + } +} + + CardJs.prototype.setupCvcInput = function() { if(this.stripe) { this.cvcInput.attr("data-stripe", "cvc"); } this.elem.append("
");