Currency validation
Asked Answered
R

6

35

Please help with me writing a JavaScript Validation for currency/money field.

So please provide any regular expressions if u have :)

Also, for my region, don't need any currency symbols like '$' in the field.

Only decimals are to be included for validation as special chars., along with numbers.

Research answered 9/2, 2010 at 7:6 Comment(2)
is the part after decimal point optional? is 103.5 valid, or should it be 103.50?Annunciator
part after decimal is optional.Research
D
47

You could use a regexp:

var regex  = /^\d+(?:\.\d{0,2})$/;
var numStr = "123.20";
if (regex.test(numStr))
    alert("Number is valid");

If you're not looking to be as strict with the decimal places you might find it easier to use the unary (+) operator to cast to a number to check it's validity:

var numStr = "123.20";
var numNum = +numStr; // gives 123.20

If the number string is invalid, it will return NaN (Not a Number), something you can test for easily:

var numStr = "ab123c";
var numNum = +numStr;
if (isNaN(numNum))
    alert("numNum is not a number");

It will, of course, allow a user to add more decimal places but you can chop any extra off using number.toFixed(2) to round to 2 decimal places. parseFloat is much less strict with input and will pluck the first number it can find out of a string, as long as that string starts with a number, eg. parseFloat("123abc") would yield 123.

Drummond answered 9/2, 2010 at 7:33 Comment(6)
regex used to test validity of string doesn't accept commas. Use /^[1-9]\d*(((,\d{3}){1})?(\.\d{0,2})?)$/ instead.Aten
To /^\d+(?:\.\d{0,2})$/ I would add an interrogation at the end /^\d+(?:\.\d{0,2})?$/ so the decimal point is optional.Bowser
"1." such thing will pass the checkVivian
Your regex says the '.' is mandatory. Which I don't think it ought to be. If the '.00' part is left off, the string is still a valid dollar amount. For example, $100.00 is a valid dollar amount; so is $100Handel
This regex worked better for me: /^\d+\.?\d{0,2}?$/ Optional '.' and optional mantissa.Handel
"0123" will pass the regex checkRemissible
B
36

I built my answer from the accepted answer.

var regex = /^[1-9]\d*(((,\d{3}){1})?(\.\d{0,2})?)$/;

^[1-9] The number must start with 1-9
\d* The number can then have any number of any digits
(...)$ look at the next group from the end (...)$
(...)?(...)? Look for two groups optionally. The first is for the comma, the second is for the decimal.
(,\d{3}){1} Look for one occurance of a comma followed by exactly three digits
\.\d{0,2} Look for a decimal followed by zero, one, or two digits.

This regex works off of these rules:

  • Valid values are numbers 0-9, comma and decimal point.
  • If a customer enters more than one decimal point or more than one comma, the value is invalid and will not be accepted.

  • Examples of invalid input values

    • 1.2.3
    • 1,2,4
  • Examples of valid input values
    • 1.23
    • 1,000
    • 3967.
    • 23
    • 1.2
    • 999,999.99

An example can be seen here: http://jsfiddle.net/rat141312/Jpxu6/1/

UPDATE

by changing the [1-9] in the regex to [0-9] any number less than 1 can also be validated. Example: 0.42, 007

Burlingame answered 2/8, 2012 at 15:21 Comment(8)
Useful! Combined with the accepted answer, this turned out to be a good solution to a problem I was having.Whitworth
...except that it doesn't allow for numbers less than 1.00.Drummond
Andy, saw your comment late. You're right :( no values less than 1 allowed. By changing the 1-9 to 0-9 it will work.Burlingame
How do you amend this recommendation for international currency formats, such as: 1.000,00Swash
Thank you! This works great for validating on the fly.Felonious
@DmitryPavlov Try this: var regex = /^[0-9]\d*(((,\d{3})*)?(\.\d{0,2})?)$/;Iand
@BenCoffin I'd recommend a different regex for each type of currency you're validating. Otherwise this blurb will get even more complex than it needs to be and at two or three different currencies it just won't be worth it to try to combine all in one. Sorry for the incredible delay in response, I was taking a nap.Burlingame
The ? for the comma should be *. Because 999,999,999 is also a valid currencyJilljillana
L
1
/[1-9]\d*(?:\.\d{0,2})?/

[1-9] - must start with 1 to 9
\d* - any number of other digits
(?: )? - non capturing optional group
\. - a decimal point
\d{0,2} - 0 to 2 digits

does that work for you? or maybe parseFloat:

var float = parseFloat( input );
Longlegged answered 9/2, 2010 at 7:18 Comment(1)
I don't think parseFloat or parseInt are that great for validation, they will parse strings like "123abc" as "123". Also, your regex tests true on the following string: "a01.9bc", you need to add ^ and $ to match the beginning and end of the string respectively. Actually, even then a string like "0.91" won't work.Drummond
A
1

 let amount = document.querySelector('#amount'), preAmount = amount.value;
        amount.addEventListener('input', function(){
            if(isNaN(Number(amount.value))){
                amount.value = preAmount;
                return;
            }

            let numberAfterDecimal = amount.value.split(".")[1];
            if(numberAfterDecimal && numberAfterDecimal.length > 3){
                amount.value = Number(amount.value).toFixed(3);;
            }
            preAmount = amount.value;
        })
<input type="text" id="amount">
Antitragus answered 24/12, 2018 at 10:27 Comment(0)
N
0

For me its working fine for Indian currency in INR

var regex = /^[1-9]{0,2}(,{0,1})(\d{2},)*(\d{3})*(?:\.\d{0,2})$/;
var a = '1,111.11';
regex.test(a); 
Ninebark answered 27/5, 2017 at 12:30 Comment(0)
T
0

Now I use this:

let func = function (vStr) {
    let v0 = Number(vStr);
    let v1 = Number(v0.toFixed(2));
    return v0 === v1;
};

Note that, NaN === NaN returns false. Maybe some substitution for '$' and ',' before parsing is needed, for other cases. And there is a problem of precision for very large number, longer than 16 digits. As well as values of '0x3a', '68n' is considered valid.

Nowadays, <input> of type="number", with step='.01' may be more proper.

Tricotine answered 10/12, 2021 at 0:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.