skip to content

JavaScript: Form Validation: Credit Card numbers

It's still amazing to me that so many sites have no idea how to make a simple form usable. This article presents methods for validating credit card numbers in a user-friendly fashion.

Validating Credit Card Numbers

Everyone knows that a credit card number is normally made up of 12-16 numbers. However there are many ways that people type their number into a form, often including spaces or hyphens to break up the number and make it more readable.

A lot of forms set the maxlength of the field to 16 characters which means that you can type most of your number - using spaces or dashes to separate blocks of numbers - before running out of space and having to go back and remove the spaces before entering the rest. Why?!?

Others will let you enter the number with extra characters, but then send you back an error message when the form is submitted. Again, why?!?

Let's see how we can do it better:

(eg. 4111-1111-1111-1111)

What have we done then?:

  • input length limited to 20 characters using maxlength;
  • you can type the number however you want - using spaces or dashes or other characters as separators;
  • when you exit the field (onblur) any non-numeric characters are stripped out;
  • when you return to the field (onfocus) your formatted string is replaced.

To achieve all this extra functionality you just need to add the following to your page:

<script> // initialise variable to save cc input string var cc_number_saved = ""; </script>

and this is the code for the relevant form field (comments can be removed):

<input type="text" size="24" maxlength="20" name="cc_number" onblur=" // save input string and strip out non-numbers cc_number_saved = this.value; this.value = this.value.replace(/[^\d]/g, ''); " onfocus=" // restore saved string if(this.value != cc_number_saved) this.value = cc_number_saved; ">

When the form is submitted the credit card input will be numbers only which is handy for processing, but you shouldn't force the user to do the work for you.

Remember it is always necessary to validate form input values using a server-side script to cater for non-JavaScript browsers or exploit attempts.

Checking for valid credit card numbers

This example goes one step futher and also checks that the number entered is valid according to the Luhn algorithm (also known as the "mod 10" algorithm).

(eg. 4111-1111-1111-1111)

This requires an extra JavaScript function that implements the Luhn algorithm:

function checkLuhn(input) { var sum = 0; var numdigits = input.length; var parity = numdigits % 2; for(var i=0; i < numdigits; i++) { var digit = parseInt(input.charAt(i)) if(i % 2 == parity) digit *= 2; if(digit > 9) digit -= 9; sum += digit; } return (sum % 10) == 0; }

For the logic and history behind the algorithm see the link above. Basically it's a method used by credit card companies for decades now to detect errors in card numbers without having to look up the actual account.

We then make a small addition to the onblur handler from the previous example:

<input type="text" size="24" maxlength="20" name="cc_number" onblur=" // save input string and strip out non-numbers cc_number_saved = this.value; this.value = this.value.replace(/[^\d]/g, ''); if(!checkLuhn(this.value)) { alert('Sorry, that is not a valid number - please try again!'); this.value = ''; } " onfocus=" // restore saved string if(this.value != cc_number_saved) this.value = cc_number_saved; ">

You can test this with your own credit card number or, if you're a less trusting individual, the sample next to the input box will also pass the test. Or you can save the contents of this link to your computer and do the testing there:

[Stand-alone example]

Checking onSubmit instead of onChange

If you don't want to clutter up your form with all those JavaScript events then the same checks can be made in a checkForm function called when the form is submitted:

<script> function checkLuhn(input) { ... } function checkForm(form) { ... if(!checkLuhn(form.cc_number.value.replace(/[^\d]/g, ''))) { alert("You have not entered a valid Card number, please check and try again"); form.cc_number.focus(); return false; } ... } </script>

Why bother?

Some programmers are dismissive of client-side validation as it can't be used as a replacement for server-side validation and therefore creates more code to maintain. The reality is that some quite simple HTML, JavaScript or even Ajax code can make a big difference in terms of reducing the number of requests to the server and keeping your users happy.

The point of the above examples is to show how you can use a number of different techniques to filter form input. You can use the HTML maxlength attribute to restrict the number of input characters, filtering 'as you type' to limit or format input, and present 'feedback' to highlight where there might be problems before the form is submitted.

The key thing to keep in mind at all times is the user experience. If you're doing something to the input it should be obvious that it's happening and clear as to why it's being done.


< JavaScript

Post your comment or question