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 - 19 November 2013 [«« Reply to this]
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 - 19 November 2013 [«« Reply to this]
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 - 19 November 2013 [«« Reply to this]
mmm
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 - 19 November 2013 [«« Reply to this]
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 - 19 November 2013 [«« Reply to this]
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 - 20 November 2013 [«« Reply to this]
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 - 20 November 2013 [«« Reply to this]
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 - 19 November 2013 [«« Reply to this]
At least it works on iOS Safari. I just tested that.
Steve Friedl - 19 November 2013 [«« Reply to this]
This puts sites on my "No Dashes Or Spaces" Hall of Shame at unixwiz.net
Peter Bengtsson - 19 November 2013 [«« Reply to this]
That's funny! http://unixwiz.net/ndos-shame.html

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 - 19 November 2013 [«« Reply to this]
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.


Your email will never ever be published