Credit Card formatter in Javascript

19 November 2013   20 comments   Javascript

Powered by Fusion×

I looked around for Javascript libs that do automatic input formatting for credit card inputs.

The first one was formatter.js which looked promising but it weighs over 6Kb minified and also, when you apply it the placeholder attribute you have on the input disappears.

So, in true software engineering fashion I wrote my own:

function cc_format(value) {
  var v = value.replace(/\s+/g, '').replace(/[^0-9]/gi, '')
  var matches = v.match(/\d{4,16}/g);
  var match = matches && matches[0] || ''
  var parts = []
  for (i=0, len=match.length; i<len; i+=4) {
    parts.push(match.substring(i, i+4))
  if (parts.length) {
    return parts.join(' ')
  } else {
    return value

And some tests to prove it:

assert(cc_format('1234') === '1234')
assert(cc_format('123456') === '1234 56')
assert(cc_format('123456789') === '1234 5678 9')
assert(cc_format('') === '')
assert(cc_format('1234 1234 5') === '1234 1234 5')
assert(cc_format('1234 a 1234x 5') === '1234 1234 5')

Check out the Demo


tulio serpio
when i type numbers, the fifth char inserts a space, but the caret places in the fourth position. the sixth char places incorrectly.

just my two cents
Peter Bengtsson
I don't understand. What's not working? The fifth input should be preceded by space. I don't see anything there being incorrect.
tulio serpio
when I type in my desktop your demo works Ok.
But, in my celular (htc sense with firefox beta, with hardware keyboard) I have to type FN + number.
When I type '12345' the caret moves to the begining of the '5', so when I type '6' the result is '1234 65'
Peter Bengtsson
I see. That's frustrating.
I'll talk to the people who work on that and try to figure out if it's a bug in Firefox or a bug in my code.
tulio serpio
I would suggest you apply the formatting on lost focus, because the interaction with the caret is a very hard task. try this on desktop:

1. type "12345678" (the field shows '1234 5678' )
2. place the caret at the begining of field
3. type "12345678" (the field shows '1123 4567 8234 5678' , when I expect '1234 5678' 1234 5678' )

As you can see, the caret changes after the 2nd '1', going to the end of input. This is an unexpected behavior, and a hard problem to solve. You'd have to track current/after caret position. I can't remember if that can be done in javascript.
Peter Bengtsson
What about something like onkeyup? I like the idea of changing it as you type because then it's easier to see a long list of strings you've typed in so far.
Peter Bengtsson
Surely it must be a bug in Firefox Android that the caret isn't at the end even if the input value is changed in async events.
Peter Bengtsson
At least it works on iOS Safari. I just tested that.
Steve Friedl
This puts sites on my "No Dashes Or Spaces" Hall of Shame at
Peter Bengtsson
That's funny!

I hate when sites can't process the numbers just because the visual presentation is different. For a server to do `.replace(' ', '')` before talking to the gateway is just so incredible trivial.
Neil Rashbrook
return value.replace(/\D/g, '').match(/.{1,4}|^$/g).join(' ');

This was the shortest code that I was able to write. I wasn't sure whether \D is an exact alias for [^0-9] but it says so on MDN (you could add a + to improve performance slightly). The |^$ is just one way to work around the otherwise null match for an empty value.
Man Hoang
Please check out my demo, which correctly handles the caret. You're gonna love it!
Peter Bengtsson
It works on Safari on iOS.
Mohamed shakir
it's working fine..
Dick from the internet
Shouldn't the length be max of 20 for non standard cards?
Can I use it my projects? What license?
How does it work with different card type? ie AE have different amount of numbers
Peter Bengtsson
It doesn't :)
hii i want to print account no like in this format 11-11-111-111
 how do i do ?

Nicholas Koskowski
Anyone have a patch for this to work with AMEX?
Thank you for posting a comment

Your email will never ever be published

Related posts

A Django base class for all your Forms 16 November 2013
Welcome to the world, Wish List Granted 27 November 2013
jsonpprint - a Python script to format JSON data nicely 21 November 2010
Formatting numeric amounts in Javascript 16 January 2009
Date formatting in Python or in PostgreSQL (part II) 19 April 2006
Date formatting in python or in PostgreSQL 20 July 2004