I want to format numbers using JavaScript.
For example:
10 => 10.00
100 => 100.00
1000 => 1,000.00
10000 => 10,000.00
100000 => 100,000.00
This question is related to
javascript
Short solution:
var n = 1234567890;
String(n).replace(/(.)(?=(\d{3})+$)/g,'$1,')
// "1,234,567,890"
Let me also throw my solution in here. I've commented each line for ease of reading and also provided some examples, so it may look big.
function format(number) {_x000D_
_x000D_
var decimalSeparator = ".";_x000D_
var thousandSeparator = ",";_x000D_
_x000D_
// make sure we have a string_x000D_
var result = String(number);_x000D_
_x000D_
// split the number in the integer and decimals, if any_x000D_
var parts = result.split(decimalSeparator);_x000D_
_x000D_
// if we don't have decimals, add .00_x000D_
if (!parts[1]) {_x000D_
parts[1] = "00";_x000D_
}_x000D_
_x000D_
// reverse the string (1719 becomes 9171)_x000D_
result = parts[0].split("").reverse().join("");_x000D_
_x000D_
// add thousand separator each 3 characters, except at the end of the string_x000D_
result = result.replace(/(\d{3}(?!$))/g, "$1" + thousandSeparator);_x000D_
_x000D_
// reverse back the integer and replace the original integer_x000D_
parts[0] = result.split("").reverse().join("");_x000D_
_x000D_
// recombine integer with decimals_x000D_
return parts.join(decimalSeparator);_x000D_
}_x000D_
_x000D_
document.write("10 => " + format(10) + "<br/>");_x000D_
document.write("100 => " + format(100) + "<br/>");_x000D_
document.write("1000 => " + format(1000) + "<br/>");_x000D_
document.write("10000 => " + format(10000) + "<br/>");_x000D_
document.write("100000 => " + format(100000) + "<br/>");_x000D_
document.write("100000.22 => " + format(100000.22) + "<br/>");
_x000D_
I think with this jQuery-numberformatter you could solve your problem.
Of course, this is assuming that you don't have problem with using jQuery in your project. Please notice that the functionality is tied to the blur event.
$("#salary").blur(function(){_x000D_
$(this).parseNumber({format:"#,###.00", locale:"us"});_x000D_
$(this).formatNumber({format:"#,###.00", locale:"us"});_x000D_
});
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<script src="https://cdn.jsdelivr.net/gh/timdown/jshashtable/hashtable.js"></script>_x000D_
_x000D_
<script src="https://cdn.jsdelivr.net/gh/hardhub/jquery-numberformatter/src/jquery.numberformatter.js"></script>_x000D_
_x000D_
<input type="text" id="salary">
_x000D_
This is an article about your problem. Adding a thousands-seperator is not built in to JavaScript, so you'll have to write your own function like this (example taken from the linked page):
function addSeperator(nStr){
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
This is about 3 times faster version of the accepted answer. It doesn't create array and avoids object creation and string concatenation for whole numbers at the end. This might be useful if you render lots of values e.g. in a table.
function addThousandSeparators(number) {
var whole, fraction
var decIndex = number.lastIndexOf('.')
if (decIndex > 0) {
whole = number.substr(0, decIndex)
fraction = number.substr(decIndex)
} else {
whole = number
}
var rgx = /(\d+)(\d{3})/
while (rgx.test(whole)) {
whole = whole.replace(rgx, '$1' + ',' + '$2')
}
return fraction ? whole + fraction : whole
}
Or you could use the sugar.js library, and the format method:
format( place = 0 , thousands = ',' , decimal = '.' ) Formats the number to a readable string. If place is undefined, will automatically determine the place. thousands is the character used for the thousands separator. decimal is the character used for the decimal point.
Examples:
(56782).format() > "56,782"
(56782).format(2) > "56,782.00"
(4388.43).format(2, ' ') > "4 388.43"
(4388.43).format(3, '.', ',') > "4.388,430"
Use
num = num.toFixed(2);
Where 2 is the number of decimal places
Edit:
Here's the function to format number as you want
function formatNumber(number)
{
number = number.toFixed(2) + '';
x = number.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
Sorce: www.mredkj.com
function formatThousands(n,dp,f) {
// dp - decimal places
// f - format >> 'us', 'eu'
if (n == 0) {
if(f == 'eu') {
return "0," + "0".repeat(dp);
}
return "0." + "0".repeat(dp);
}
/* round to 2 decimal places */
//n = Math.round( n * 100 ) / 100;
var s = ''+(Math.floor(n)), d = n % 1, i = s.length, r = '';
while ( (i -= 3) > 0 ) { r = ',' + s.substr(i, 3) + r; }
var a = s.substr(0, i + 3) + r + (d ? '.' + Math.round((d+1) * Math.pow(10,dp)).toString().substr(1,dp) : '');
/* change format from 20,000.00 to 20.000,00 */
if (f == 'eu') {
var b = a.toString().replace(".", "#");
b = b.replace(",", ".");
return b.replace("#", ",");
}
return a;
}
You may want to consider using toLocaleString()
Working Example:
const number = 1234567890.123;
console.log(number.toLocaleString('en-US')); // US format
console.log(number.toLocaleString('en-IN')); // Indian format
_x000D_
Tested in Chrome v60 and v88
Use the Number function toFixed
and this function to add the commas.
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, '$1' + ',' + '$2');
}
return x1 + x2;
}
n = 10000;
r = n.toFixed(2); //10000.00
addCommas(r); // 10,000.00
Due to the bugs found by JasperV — good points! — I have rewritten my old code. I guess I only ever used this for positive values with two decimal places.
Depending on what you are trying to achieve, you may want rounding or not, so here are two versions split across that divide.
I've introduced the toFixed()
method as it better handles rounding to specific decimal places accurately and is well support. It does slow things down however.
This version still detaches the decimal, but using a different method than before. The w|0
part removes the decimal. For more information on that, this is a good answer. This then leaves the remaining integer, stores it in k
and then subtracts it again from the original number, leaving the decimal by itself.
Also, if we're to take negative numbers into account, we need to while loop (skipping three digits) until we hit b
. This has been calculated to be 1 when dealing with negative numbers to avoid putting something like -,100.00
The rest of the loop is the same as before.
function formatThousandsWithRounding(n, dp){
var w = n.toFixed(dp), k = w|0, b = n < 0 ? 1 : 0,
u = Math.abs(w-k), d = (''+u.toFixed(dp)).substr(2, dp),
s = ''+k, i = s.length, r = '';
while ( (i-=3) > b ) { r = ',' + s.substr(i, 3) + r; }
return s.substr(0, i + 3) + r + (d ? '.'+d: '');
};
In the snippet below you can edit the numbers to test yourself.
function formatThousandsWithRounding(n, dp){_x000D_
var w = n.toFixed(dp), k = w|0, b = n < 0 ? 1 : 0,_x000D_
u = Math.abs(w-k), d = (''+u.toFixed(dp)).substr(2, dp),_x000D_
s = ''+k, i = s.length, r = '';_x000D_
while ( (i-=3) > b ) { r = ',' + s.substr(i, 3) + r; }_x000D_
return s.substr(0, i + 3) + r + (d ? '.'+d: '');_x000D_
};_x000D_
_x000D_
var dp;_x000D_
var createInput = function(v){_x000D_
var inp = jQuery('<input class="input" />').val(v);_x000D_
var eql = jQuery('<span> = </span>');_x000D_
var out = jQuery('<div class="output" />').css('display', 'inline-block');_x000D_
var row = jQuery('<div class="row" />');_x000D_
row.append(inp).append(eql).append(out);_x000D_
inp.keyup(function(){_x000D_
out.text(formatThousandsWithRounding(Number(inp.val()), Number(dp.val())));_x000D_
});_x000D_
inp.keyup();_x000D_
jQuery('body').append(row);_x000D_
return inp;_x000D_
};_x000D_
_x000D_
jQuery(function(){_x000D_
var numbers = [_x000D_
0, 99.999, -1000, -1000000, 1000000.42, -1000000.57, -1000000.999_x000D_
], inputs = $();_x000D_
dp = jQuery('#dp');_x000D_
for ( var i=0; i<numbers.length; i++ ) {_x000D_
inputs = inputs.add(createInput(numbers[i]));_x000D_
}_x000D_
dp.on('input change', function(){_x000D_
inputs.keyup();_x000D_
});_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<input id="dp" type="range" min="0" max="5" step="1" value="2" title="number of decimal places?" />
_x000D_
This takes a different route and attempts to avoid mathematical calculation (as this can introduce rounding, or rounding errors). If you don't want rounding, then you are only dealing with things as a string i.e. 1000.999 converted to two decimal places will only ever be 1000.99 and not 1001.00.
This method avoids using .split()
and RegExp()
however, both of which are very slow in comparison. And whilst I learned something new from Michael's answer about toLocaleString
, I also was surprised to learn that it is — by quite a way — the slowest method out of them all (at least in Firefox and Chrome; Mac OSX).
Using lastIndexOf()
we find the possibly existent decimal point, and from there everything else is pretty much the same. Save for the padding with extra 0s where needed. This code is limited to 5 decimal places. Out of my test this was the faster method.
var formatThousandsNoRounding = function(n, dp){
var e = '', s = e+n, l = s.length, b = n < 0 ? 1 : 0,
i = s.lastIndexOf('.'), j = i == -1 ? l : i,
r = e, d = s.substr(j+1, dp);
while ( (j-=3) > b ) { r = ',' + s.substr(j, 3) + r; }
return s.substr(0, j + 3) + r +
(dp ? '.' + d + ( d.length < dp ?
('00000').substr(0, dp - d.length):e):e);
};
var formatThousandsNoRounding = function(n, dp){_x000D_
var e = '', s = e+n, l = s.length, b = n < 0 ? 1 : 0,_x000D_
i = s.lastIndexOf('.'), j = i == -1 ? l : i,_x000D_
r = e, d = s.substr(j+1, dp);_x000D_
while ( (j-=3) > b ) { r = ',' + s.substr(j, 3) + r; }_x000D_
return s.substr(0, j + 3) + r + _x000D_
(dp ? '.' + d + ( d.length < dp ? _x000D_
('00000').substr(0, dp - d.length):e):e);_x000D_
};_x000D_
_x000D_
var dp;_x000D_
var createInput = function(v){_x000D_
var inp = jQuery('<input class="input" />').val(v);_x000D_
var eql = jQuery('<span> = </span>');_x000D_
var out = jQuery('<div class="output" />').css('display', 'inline-block');_x000D_
var row = jQuery('<div class="row" />');_x000D_
row.append(inp).append(eql).append(out);_x000D_
inp.keyup(function(){_x000D_
out.text(formatThousandsNoRounding(Number(inp.val()), Number(dp.val())));_x000D_
});_x000D_
inp.keyup();_x000D_
jQuery('body').append(row);_x000D_
return inp;_x000D_
};_x000D_
_x000D_
jQuery(function(){_x000D_
var numbers = [_x000D_
0, 99.999, -1000, -1000000, 1000000.42, -1000000.57, -1000000.999_x000D_
], inputs = $();_x000D_
dp = jQuery('#dp');_x000D_
for ( var i=0; i<numbers.length; i++ ) {_x000D_
inputs = inputs.add(createInput(numbers[i]));_x000D_
}_x000D_
dp.on('input change', function(){_x000D_
inputs.keyup();_x000D_
});_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<input id="dp" type="range" min="0" max="5" step="1" value="2" title="number of decimal places?" />
_x000D_
I'll update with an in-page snippet demo shortly, but for now here is a fiddle:
https://jsfiddle.net/bv2ort0a/2/
Why use RegExp for this? — don't use a hammer when a toothpick will do i.e. use string manipulation:
var formatThousands = function(n, dp){
var s = ''+(Math.floor(n)), d = n % 1, i = s.length, r = '';
while ( (i -= 3) > 0 ) { r = ',' + s.substr(i, 3) + r; }
return s.substr(0, i + 3) + r +
(d ? '.' + Math.round(d * Math.pow(10, dp || 2)) : '');
};
formatThousands( 1000000.42 );
First strip off decimal:
s = '1000000', d = ~ 0.42
Work backwards from the end of the string:
',' + '000'
',' + '000' + ',000'
Finalise by adding the leftover prefix and the decimal suffix (with rounding to dp
no. decimal points):
'1' + ',000,000' + '.42'
function numberWithCommas(x) {_x000D_
x=String(x).toString();_x000D_
var afterPoint = '';_x000D_
if(x.indexOf('.') > 0)_x000D_
afterPoint = x.substring(x.indexOf('.'),x.length);_x000D_
x = Math.floor(x);_x000D_
x=x.toString();_x000D_
var lastThree = x.substring(x.length-3);_x000D_
var otherNumbers = x.substring(0,x.length-3);_x000D_
if(otherNumbers != '')_x000D_
lastThree = ',' + lastThree;_x000D_
return otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree + afterPoint;_x000D_
}_x000D_
_x000D_
console.log(numberWithCommas(100000));_x000D_
console.log(numberWithCommas(10000000));
_x000D_
1,00,000
1,00,00,000
On browsers that support the ECMAScript® 2016 Internationalization API Specification (ECMA-402), you can use an Intl.NumberFormat
instance:
var nf = Intl.NumberFormat();
var x = 42000000;
console.log(nf.format(x)); // 42,000,000 in many locales
// 42.000.000 in many other locales
if (typeof Intl === "undefined" || !Intl.NumberFormat) {_x000D_
console.log("This browser doesn't support Intl.NumberFormat");_x000D_
} else {_x000D_
var nf = Intl.NumberFormat();_x000D_
var x = 42000000;_x000D_
console.log(nf.format(x)); // 42,000,000 in many locales_x000D_
// 42.000.000 in many other locales_x000D_
}
_x000D_
function formatNumber1(number) {
var comma = ',',
string = Math.max(0, number).toFixed(0),
length = string.length,
end = /^\d{4,}$/.test(string) ? length % 3 : 0;
return (end ? string.slice(0, end) + comma : '') + string.slice(end).replace(/(\d{3})(?=\d)/g, '$1' + comma);
}
function formatNumber2(number) {
return Math.max(0, number).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g, ',');
}
Source: http://jsperf.com/number-format
This will get you your comma seperated values as well as add the fixed notation to the end.
nStr="1000";
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
commaSeperated = x1 + x2 + ".00";
alert(commaSeperated);
If you want to use built-in code, you can use toLocaleString()
with minimumFractionDigits
. Browser compatibility for the extended options on toLocaleString()
was limited when I first wrote this answer, but the current status looks good.
var n = 100000;
var value = n.toLocaleString(
undefined, // leave undefined to use the browser's locale,
// or use a string like 'en-US' to override it.
{ minimumFractionDigits: 2 }
);
console.log(value);
// In en-US, logs '100,000.00'
// In de-DE, logs '100.000,00'
// In hi-IN, logs '1,00,000.00'
_x000D_
If you're using Node.js, you will need to npm install
the intl
package.
If you're using jQuery, you could use the format or number format plugins.
Source: Stackoverflow.com