The reference cited in the original answer below was wrong. There is a built in function for this, which is exactly what kaiser suggests below: toLocaleString
So you can do:
(1234567.89).toLocaleString('en') // for numeric input
parseFloat("1234567.89").toLocaleString('en') // for string input
The function implemented below works, too, but simply isn't necessary.
(I thought perhaps I'd get lucky and find out that it was necessary back in 2010, but no. According to this more reliable reference, toLocaleString has been part of the standard since ECMAScript 3rd Edition [1999], which I believe means it would have been supported as far back as IE 5.5.)
Original Answer
According to this reference there isn't a built in function for adding commas to a number. But that page includes an example of how to code it yourself:
function addCommas(nStr) {
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '
2');
}
return x1 + x2;
}
Edit: To go the other way (convert string with commas to number), you could do something like this:
parseFloat("1,234,567.89".replace(/,/g,''))
Answer from Tim Goodman on Stack OverflowThe reference cited in the original answer below was wrong. There is a built in function for this, which is exactly what kaiser suggests below: toLocaleString
So you can do:
(1234567.89).toLocaleString('en') // for numeric input
parseFloat("1234567.89").toLocaleString('en') // for string input
The function implemented below works, too, but simply isn't necessary.
(I thought perhaps I'd get lucky and find out that it was necessary back in 2010, but no. According to this more reliable reference, toLocaleString has been part of the standard since ECMAScript 3rd Edition [1999], which I believe means it would have been supported as far back as IE 5.5.)
Original Answer
According to this reference there isn't a built in function for adding commas to a number. But that page includes an example of how to code it yourself:
function addCommas(nStr) {
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '
2');
}
return x1 + x2;
}
Edit: To go the other way (convert string with commas to number), you could do something like this:
parseFloat("1,234,567.89".replace(/,/g,''))
If is about localizing thousands separators, delimiters and decimal separators, go with the following:
// --> numObj.toLocaleString( [locales [, options] ] )
parseInt( number ).toLocaleString();
There are several options you can use (and even locales with fallbacks):
number = 123456.7089;
result = parseInt( number ).toLocaleString() + "<br>";
result += number.toLocaleString( 'de-DE' ) + "<br>";
result += number.toLocaleString( 'ar-EG' ) + "<br>";
result += number.toLocaleString( 'ja-JP', {
style : 'currency',
currency : 'JPY',
currencyDisplay : 'symbol',
useGrouping : true
} ) + "<br>";
result += number.toLocaleString( [ 'jav', 'en' ], {
localeMatcher : 'lookup',
style : 'decimal',
minimumIntegerDigits : 2,
minimumFractionDigits : 2,
maximumFractionDigits : 3,
minimumSignificantDigits : 2,
maximumSignificantDigits : 3
} ) + "<br>";
var el = document.getElementById( 'result' );
el.innerHTML = result;
<div id="result"></div>
Details on the MDN info page.
Edit: Commentor @I like Serena adds the following:
To support browsers with a non-English locale where we still want English formatting, use
value.toLocaleString('en'). Also works for floating point.
javascript - How to get Decimal and Thousand separator of toLocaleString() method? - Stack Overflow
javascript - Chrome - toLocaleString() - Thousands separator is not working for Spanish - Stack Overflow
Add dot (.) as a thousands separator as the user types on input
How to determine thousands separator in JavaScript - Stack Overflow
One option is to format to a string with known separators, and then do a find/replace with the unknown separators.
function formatNum(num, separator, fraction) {
var str = num.toLocaleString('en-US');
str = str.replace(/\./, fraction);
str = str.replace(/,/g, separator);
return str;
}
formatNum(12342.2, "a", "x");
//12a342x2
The original answer on this page won't work if a comma is used as the decimal separator (the parameter fraction). That's problematic, because comma is used as the decimal separator widely e.g. in Europe (Spain, France, Norway, Czechia, Denmark...).
In order to make it work, the replacement can be done in two steps instead using an intermediate placeholder for the fraction symbol:
function formatNum(num, separator, fraction) {
return num
.toLocaleString('en-US');
.replace(/\./, "<fraction>")
.replace(/,/g, separator)
.replace(/<fraction>/, fraction);
}
formatNum(12342.2, " ", ",");
//12 342,2
Somthing like this should work (not tested):
let thousandsSeparator = Number(1000).toLocaleString().charAt(1)
let decimalSeparator = Number(1.1).toLocaleString().charAt(1)
you can get decimal separator and group separator from value. I can write below two function:
function getDecimalSeparator(locale) {
const numberWithDecimalSeparator = 1.1;
return Intl.NumberFormat(locale)
.formatToParts(numberWithDecimalSeparator)
.find(part => part.type === 'decimal')
.value;
}
function getNumberGroupSeparator(locale) {
const numberWithDecimalSeparator = 1000.1;
return Intl.NumberFormat(locale)
.formatToParts(numberWithDecimalSeparator)
.find(part => part.type === 'group')
.value;
}
console.log(getDecimalSeparator("en"));
console.log(getDecimalSeparator("fr"));
console.log(getNumberGroupSeparator("en"));
console.log(getNumberGroupSeparator("fr"));
According to the CLDR, this is the intended behavior. The "Minimum Grouping Digits" is 2, meaning that, only when a number has 2 digits before the other 3 digits, the thousand separator would appear. Apparently, this was only applied to chrome, since other browsers are using the "old" specifications.
Check this https://st.unicode.org/cldr-apps/v#/es/Symbols/70ef5e0c9d323e01
A possible workaround I used FOR SPECIFIC CASES, is to set it to the German locale ("de") instead of Spanish:
(1000).toLocaleString("de")
"1.000"
The behaviour is indeed the one mentioned in the accepted answer.
However, rather than using the workaround mentioned above which defeats the purpose of using the toLocaleString() function, I would suggest using the useGrouping: true parameter.
const number = 1000
const localNumber = number.toLocaleString("es-ES", { useGrouping: true })
console.log(localNumber)
// expected output: '1.000'
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#usegrouping
I have a text type input and I’d like for it to show thousands separator with a dot (.) (NOT comma). For example, 1.200 or 125.500
I’ve tried this with a onkeyup event, and I added a regular expression I found online, but the problem is, it adds unnecessary dots. For example, I’ll recreate a user inputting a number:
1 12 120 1.200 1.2.000 1.2.0.000
It’s like it applies it continually but I want the final result to be: 120.000
Is there a way to do this? Maybe it’s not with an onkeyup event on the input tag, maybe it’s something else. But I can’t think of a way.
Thanks. If you need, I’ll look up the regex code I used.
A little further digging and I found Intl.NumberFormat. I think this is more elegant...
const thousandsSeparator = (function(){
if (typeof Intl !== 'object') {
return ','; // fallback
}
// Get the formatting object for your locale
const numFormat = new Intl.NumberFormat();
// The resolved.pattern will be something like "#,##0.###"
return numFormat.resolved.pattern.substr(1,1);
})();
Or if you really need it ultra-concise...
const thousandsSeparator = (Intl) ? (new Intl.NumberFormat()).resolved.pattern.substr(1,1) : ",";
Compatibility warning (2015):
- The
Intlobject may not be supported in Safari for some reason -- http://caniuse.com/#feat=internationalization -- despite it being part of standard ECMAScript. - While the
Intlobject may exist in some ECMAScript-standard browsers, the code above will only work in Chrome. - Sadly Firefox 40 and IE 11 currently do not have a
resolvedproperty innumFormat.
An elegant cross-browser solution is still out there...
Update (2021):
Intl, and numFormat.resolved may have better browser support in non-Chrome browsers now. See comments for latest information.
Easy, I guess. This should help you to start with this ES6 solution
function getThousandSeparator(locale){
const mapperRE = /(.{1})\d{3}(\D)\d$/,
digitRE = /\d/,
formattedValue = (new Intl.NumberFormat(locale?? navigator.language)).format(1000.1);
let [_,thousand, decimal] = mapperRE.exec(formattedValue) ?? [null,null,null];
//In case the captured position is number it means there's no thousand separator
if(digitRE.test(thousand))
thousand = '';
return {thousand, decimal}
}
You may use second argument to provide some options. In your case, with default locale:
number.toLocaleString(undefined, { minimumFractionDigits: 4 })
I found that
var number = 49.9712;
number.toLocaleString( { minimumFractionDigits: 4 })
gave the result of "49.971"
In order to actually get the 4 decimal place digits, I did this:
number.toLocaleString(undefined, { minimumFractionDigits: 4 })
Also filling in a country code worked:
number.toLocaleString('en-US', { minimumFractionDigits: 4 })
In both cases I got 49.9712 for the answer.
I used the idea from Kerry's answer, but I simplified it since I was just looking for something simple for my specific purpose. Here is what I have:
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
function test(x, expect) {
const result = numberWithCommas(x);
const pass = result === expect;
console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
return pass;
}
let failures = 0;
failures += !test(0, "0");
failures += !test(100, "100");
failures += !test(1000, "1,000");
failures += !test(10000, "10,000");
failures += !test(100000, "100,000");
failures += !test(1000000, "1,000,000");
failures += !test(10000000, "10,000,000");
if (failures) {
console.log(`${failures} test(s) failed`);
} else {
console.log("All tests passed");
}
.as-console-wrapper {
max-height: 100% !important;
}
The regex uses two lookahead assertions:
- a positive one to look for any point in the string that has a multiple of 3 digits in a row after it,
- a negative assertion to make sure that point only has exactly a multiple of 3 digits. The replacement expression puts a comma there.
For example, if you pass it 123456789.01, the positive assertion will match every spot to the left of the 7 (since 789 is a multiple of 3 digits, 678 is a multiple of 3 digits, 567, etc.).
The negative assertion checks that the multiple of 3 digits does not have any digits after it. 789 has a period after it so it is exactly a multiple of 3 digits, so a comma goes there. 678 is a multiple of 3 digits, but it has a 9 after it, so those 3 digits are part of a group of 4, and a comma does not go there. Similarly for 567.
456789 is 6 digits, which is a multiple of 3, so a comma goes before that. 345678 is a multiple of 3, but it has a 9 after it, so no comma goes there. And so on. The \B keeps the regex from putting a comma at the beginning of the string.
neu-rah mentioned that this function adds commas in undesirable places if there are more than 3 digits after the decimal point. If this is a problem, you can use this function:
function numberWithCommas(x) {
var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
function numberWithCommas(x) {
var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
function test(x, expect) {
const result = numberWithCommas(x);
const pass = result === expect;
console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
return pass;
}
let failures = 0;
failures += !test(0 , "0");
failures += !test(0.123456 , "0.123456");
failures += !test(100 , "100");
failures += !test(100.123456 , "100.123456");
failures += !test(1000 , "1,000");
failures += !test(1000.123456 , "1,000.123456");
failures += !test(10000 , "10,000");
failures += !test(10000.123456 , "10,000.123456");
failures += !test(100000 , "100,000");
failures += !test(100000.123456 , "100,000.123456");
failures += !test(1000000 , "1,000,000");
failures += !test(1000000.123456 , "1,000,000.123456");
failures += !test(10000000 , "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
console.log(`${failures} test(s) failed`);
} else {
console.log("All tests passed");
}
.as-console-wrapper {
max-height: 100% !important;
}
T.J. Crowder pointed out that now that JavaScript has lookbehind (support info), it can be solved in the regular expression itself:
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
function test(x, expect) {
const result = numberWithCommas(x);
const pass = result === expect;
console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
return pass;
}
let failures = 0;
failures += !test(0, "0");
failures += !test(0.123456, "0.123456");
failures += !test(100, "100");
failures += !test(100.123456, "100.123456");
failures += !test(1000, "1,000");
failures += !test(1000.123456, "1,000.123456");
failures += !test(10000, "10,000");
failures += !test(10000.123456, "10,000.123456");
failures += !test(100000, "100,000");
failures += !test(100000.123456, "100,000.123456");
failures += !test(1000000, "1,000,000");
failures += !test(1000000.123456, "1,000,000.123456");
failures += !test(10000000, "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
console.log(`${failures} test(s) failed`);
} else {
console.log("All tests passed");
}
.as-console-wrapper {
max-height: 100% !important;
}
(?<!\.\d*) is a negative lookbehind that says the match can't be preceded by a . followed by zero or more digits. The negative lookbehind is faster than the split and join solution (comparison), at least in V8.
I'm surprised nobody mentioned Number.prototype.toLocaleString. It's implemented in JavaScript 1.5 (which was introduced in 1999), so it's basically supported across all major browsers.
var n = 34523453.345;
console.log(n.toLocaleString()); // "34,523,453.345"
It also works in Node.js as of v0.12 via inclusion of Intl.
If you want something different, Numeral.js might be interesting.