I would like to format a price in JavaScript. I'd like a function which takes a float
as an argument and returns a string
formatted like this:
"$ 2,500.00"
What's the best way to do this?
This question is related to
javascript
formatting
currency
A shorter method (for inserting space, comma or point) with regular expression ?
Number.prototype.toCurrencyString=function(){
return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
}
n=12345678.9;
alert(n.toCurrencyString());
A function to handle currency output, including negatives.
Sample Output:
$5.23
-$5.23
function formatCurrency(total) {
var neg = false;
if(total < 0) {
neg = true;
total = Math.abs(total);
}
return (neg ? "-$" : '$') + parseFloat(total, 10).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").toString();
}
I found this from: accounting.js . Its very easy and perfectly fits my need.
// Default usage:_x000D_
accounting.formatMoney(12345678); // $12,345,678.00_x000D_
_x000D_
// European formatting (custom symbol and separators), can also use options object as second parameter:_x000D_
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99_x000D_
_x000D_
// Negative values can be formatted nicely:_x000D_
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000_x000D_
_x000D_
// Simple `format` string allows control of symbol position (%v = value, %s = symbol):_x000D_
accounting.formatMoney(5318008, { symbol: "GBP", format: "%v %s" }); // 5,318,008.00 GBP_x000D_
_x000D_
// Euro currency symbol to the right_x000D_
accounting.formatMoney(5318008, {symbol: "€", precision: 2, thousand: ".", decimal : ",", format: "%v%s"}); // 1.008,00€
_x000D_
@tggagne is correct. My solution below is not good due to float rounding. And the toLocaleString function lacks some browser support. I'll leave the below comments for archival purposes of what NOT to do. :)
(Old Solution) Use Patrick Desjardins solution instead.
This is a terse solution that uses toLocaleString(), which has been supported since Javascript version 1.0. This example designates the currency to U.S. Dollars, but could be switched to pounds by using 'GBP' instead of 'USD'.
var formatMoney = function (value) {
// Convert the value to a floating point number in case it arrives as a string.
var numeric = parseFloat(value);
// Specify the local currency.
return numeric.toLocaleString('USD', { style: 'currency', currency: "USD", minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
See https://marcoscaceres.github.io/jsi18n/#localize_currency for additional details.
Taking a few of the best rated answers, I combined and made an ES6 function that passes eslinter.
export const formatMoney = (
amount,
decimalCount = 2,
decimal = '.',
thousands = ',',
currencySymbol = '$',
) => {
if (typeof Intl === 'object') {
return new Intl.NumberFormat('en-AU', {
style: 'currency',
currency: 'AUD',
}).format(amount);
}
// fallback if Intl is not present.
try {
const negativeSign = amount < 0 ? '-' : '';
const amountNumber = Math.abs(Number(amount) || 0).toFixed(decimalCount);
const i = parseInt(amountNumber, 10).toString();
const j = i.length > 3 ? i.length % 3 : 0;
return (
currencySymbol +
negativeSign +
(j ? i.substr(0, j) + thousands : '') +
i.substr(j).replace(/(\d{3})(?=\d)/g, `$1${thousands}`) +
(decimalCount
? decimal +
Math.abs(amountNumber - i)
.toFixed(decimalCount)
.slice(2)
: '')
);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
return amount;
};
If amount is a number, say -123
, then
amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
will produce the string "-$123.00"
.
Here's a complete working example.
Here's the best JavaScript money formatter I've seen:
Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator) {
var n = this,
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
decSeparator = decSeparator == undefined ? "." : decSeparator,
thouSeparator = thouSeparator == undefined ? "," : thouSeparator,
sign = n < 0 ? "-" : "",
i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "",
j = (j = i.length) > 3 ? j % 3 : 0;
return sign + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};
It was re-formatted and borrowed from here: https://stackoverflow.com/a/149099/751484
You'll have to supply your own currency designator (you used $ above).
Call it like this (although note that the args default to 2, comma, & period, so you don't need to supply any args if that's your preference):
var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
accounting.js is a tiny JavaScript library for number, money and currency formatting.
This solution is compatible with every single major browser:
const profits = 2489.8237;
profits.toFixed(3) //returns 2489.824 (rounds up)
profits.toFixed(2) //returns 2489.82
profits.toFixed(7) //returns 2489.8237000 (pads the decimals)
All you need is to add the currency symbol (e.g. "$" + profits.toFixed(2)
) and you will have your amount in dollars.
If you require the use of ,
between each digit, you can use this function:
function formatMoney(number, decPlaces, decSep, thouSep) {_x000D_
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,_x000D_
decSep = typeof decSep === "undefined" ? "." : decSep;_x000D_
thouSep = typeof thouSep === "undefined" ? "," : thouSep;_x000D_
var sign = number < 0 ? "-" : "";_x000D_
var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces)));_x000D_
var j = (j = i.length) > 3 ? j % 3 : 0;_x000D_
_x000D_
return sign +_x000D_
(j ? i.substr(0, j) + thouSep : "") +_x000D_
i.substr(j).replace(/(\decSep{3})(?=\decSep)/g, "$1" + thouSep) +_x000D_
(decPlaces ? decSep + Math.abs(number - i).toFixed(decPlaces).slice(2) : "");_x000D_
}_x000D_
_x000D_
document.getElementById("b").addEventListener("click", event => {_x000D_
document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);_x000D_
});
_x000D_
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>_x000D_
<br />_x000D_
<button id="b">Get Output</button>_x000D_
<p id="x">(press button to get output)</p>
_x000D_
Use it like so:
(123456789.12345).formatMoney(2, ".", ",");
If you're always going to use '.' and ',', you can leave them off your method call, and the method will default them for you.
(123456789.12345).formatMoney(2);
If your culture has the two symbols flipped (i.e. Europeans) and you would like to use the defaults, just paste over the following two lines in the formatMoney
method:
d = d == undefined ? "," : d,
t = t == undefined ? "." : t,
If you can use modern ECMAScript syntax (i.e. through Babel), you can use this simpler function instead:
function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {_x000D_
try {_x000D_
decimalCount = Math.abs(decimalCount);_x000D_
decimalCount = isNaN(decimalCount) ? 2 : decimalCount;_x000D_
_x000D_
const negativeSign = amount < 0 ? "-" : "";_x000D_
_x000D_
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();_x000D_
let j = (i.length > 3) ? i.length % 3 : 0;_x000D_
_x000D_
return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");_x000D_
} catch (e) {_x000D_
console.log(e)_x000D_
}_x000D_
};_x000D_
document.getElementById("b").addEventListener("click", event => {_x000D_
document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);_x000D_
});
_x000D_
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>_x000D_
<br />_x000D_
<button id="b">Get Output</button>_x000D_
<p id="x">(press button to get output)</p>
_x000D_
toLocaleString is good, but doesn't work on all browsers. I usually use currencyFormatter.js (https://osrec.github.io/currencyFormatter.js/). It's pretty lightweight, and contains all the currency and locale definitions right out of the box. It's also good at formatting unusually formatted currencies, such as the INR (which groups numbers in lakhs and crores etc). Also no dependencies!
OSREC.CurrencyFormatter.format(2534234, { currency: 'INR' });
// Returns ? 25,34,234.00
OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR' });
// Returns 2.534.234,00 €
OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR', locale: 'fr' });
// Returns 2 534 234,00 €
function CurrencyFormatted(amount)
{
var i = parseFloat(amount);
if(isNaN(i)) { i = 0.00; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if(s.indexOf('.') < 0) { s += '.00'; }
if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
s = minus + s;
return s;
}
From WillMaster.
We can also use numeraljs
Numbers can be formatted to look like currency, percentages, times, or even plain old numbers with decimal places, thousands, and abbreviations. And you can always create a custom format.
var string = numeral(1000).format('0,0');
// '1,000'
This might be a little late, but here's a method I just worked up for a coworker to add a locale-aware .toCurrencyString()
function to all numbers. The internalization is for number grouping only, NOT the currency sign - if you're outputting dollars, use "$"
as supplied, because $123 4567
in Japan or China is the same number of USD as $1,234,567
is here in the US. If you're outputting euro/etc., then change the currency sign from "$"
.
Declare this anywhere in your HEAD or wherever necessary, just before you need to use it:
Number.prototype.toCurrencyString = function(prefix, suffix) {
if (typeof prefix === 'undefined') { prefix = '$'; }
if (typeof suffix === 'undefined') { suffix = ''; }
var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/\./, '\\.') + "$");
return prefix + (~~this).toLocaleString().replace(_localeBug, '') + (this % 1).toFixed(2).toLocaleString().replace(/^[+-]?0+/,'') + suffix;
}
Then you're done! Use (number).toCurrencyString()
anywhere you need to output the number as currency.
var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
A quiker way with regexp ?
Number.prototype.toMonetaryString=function(){var n=this.toFixed(2),m;
// var=this.toFixed(2).replace(/\./,','); for comma separator
// with a space for thousands separator
while ((m=n.replace(/(\d)(\d\d\d)\b/g,'$1 $2'))!=n) n=m;
return m;
}
String.prototype.fromMonetaryToNumber=function(s){
return this.replace(/[^\d-]+/g,'')/100;
}
I had a hard time finding a simple library to work with date and currency, so I created mine: https://github.com/dericeira/slimFormatter.js
Simple as that:
var number = slimFormatter.currency(2000.54);
here is a quick way by using regexp and replace.
function formatCurrency( number, dp, ts ) {
var num = parseFloat( number ); //convert to float
var pw; //for IE
dp = parseInt( dp, 10 ); //decimal point
dp = isNaN( dp ) ? 2 : dp; //default 2 decimal point
ts = ts || ','; //thousands separator
return num != number ?
false : //return false for NaN
( ( 0.9 ).toFixed( 0 ) == '1' ? //for cater IE toFixed bug
num.toFixed( dp ) : //format to fix n decimal point with round up
( Math.round( num * ( pw = Math.pow( 10, dp ) || 1 ) ) / pw ).toFixed( dp ) //for fix ie toFixed bug on round up value like 0.9 in toFixed
).replace( /^(-?\d{1,3})((\d{3})*)(\.\d+)?$/, function( all, first, subsequence, dmp, dec ) { //separate string into different parts
return ( first || '' ) + subsequence.replace( /(\d{3})/g, ts + '$1' ) + ( dec || '' ); //add thousands seperator and re-join all parts
} );
}
I want to contribute with this:
function toMoney(amount) {
neg = amount.charAt(0);
amount= amount.replace(/\D/g, '');
amount= amount.replace(/\./g , '');
amount= amount.replace(/\-/g, '');
var numAmount = new Number(amount);
amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "." + c : c;
});
if(neg == '-')
return neg+amount;
else
return amount;
}
This allows you to convert numbers in a text box where you only supose to put numbers (consider this scenario)
This is going to clean a textbox where only supose to be numbers even if you paste a string with numbers and letters or any character
<html>
<head>
<script language=="Javascript">
function isNumber(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
if (key.length == 0) return;
var regex = /^[0-9\-\b]+$/;
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) theEvent.preventDefault();
}
}
function toMoney(amount) {
neg = amount.charAt(0);
amount= amount.replace(/\D/g, '');
amount= amount.replace(/\./g , '');
amount= amount.replace(/\-/g, '');
var numAmount = new Number(amount);
amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "." + c : c;
});
if(neg == '-')
return neg+amount;
else
return amount;
}
function clearText(inTxt, newTxt, outTxt) {
inTxt = inTxt.trim();
newTxt = newTxt.trim();
if(inTxt == '' || inTxt == newTxt)
return outTxt;
return inTxt;
}
function fillText(inTxt, outTxt) {
inTxt = inTxt.trim();
if(inTxt != '')
outTxt = inTxt;
return outTxt;
}
</script>
</head>
<body>
$ <input name=reca2 id=reca2 type=text value="0" onFocus="this.value = clearText(this.value, '0', '');" onblur="this.value = fillText(this.value, '0'); this.value = toMoney(this.value);" onKeyPress="isNumber(event);" style="width:80px;" />
</body>
</html>
function getMoney(A){
var a = new Number(A);
var b = a.toFixed(2); //get 12345678.90
a = parseInt(a); // get 12345678
b = (b-a).toPrecision(2); //get 0.90
b = parseFloat(b).toFixed(2); //in case we get 0.0, we pad it out to 0.00
a = a.toLocaleString();//put in commas - IE also puts in .00, so we'll get 12,345,678.00
//if IE (our number ends in .00)
if(a < 1 && a.lastIndexOf('.00') == (a.length - 3))
{
a=a.substr(0, a.length-3); //delete the .00
}
return a+b.substr(1);//remove the 0 from b, then return a + b = 12,345,678.90
}
alert(getMoney(12345678.9));
This works in FF and IE
Please find in the below code what I have developed to support internationalization. May help someone. It formats the given numeric value to language specific format. In the given example I have used ‘en’ while have tested for ‘es’, ‘fr’ and other countries where in the format varies. It not only stops user from keying characters but formats the value on tab out. Have created components for Number as well as for Decimal format. Apart from this have created parseNumber(value, locale) and parseDecimal(value, locale) functions which will parse the formatted data for any other business purposes. The said function will accept the formatted data and will return the non-formatted value. I have used JQuery validator plugin in the below shared code.
HTML:
<tr>
<td>
<label class="control-label">
Number Field:
</label>
<div class="inner-addon right-addon">
<input type="text" id="numberField"
name="numberField"
class="form-control"
autocomplete="off"
maxlength="17"
data-rule-required="true"
data-msg-required="Cannot be blank."
data-msg-maxlength="Exceeding the maximum limit of 13 digits. Example: 1234567890123"
data-rule-numberExceedsMaxLimit="en"
data-msg-numberExceedsMaxLimit="Exceeding the maximum limit of 13 digits. Example: 1234567890123"
onkeydown="return isNumber(event, 'en')"
onkeyup="return updateField(this)"
onblur="numberFormatter(this,
'en',
'Invalid character(s) found. Please enter valid characters.')">
</div>
</td>
</tr>
<tr>
<td>
<label class="control-label">
Decimal Field:
</label>
<div class="inner-addon right-addon">
<input type="text" id="decimalField"
name="decimalField"
class="form-control"
autocomplete="off"
maxlength="20"
data-rule-required="true"
data-msg-required="Cannot be blank."
data-msg-maxlength="Exceeding the maximum limit of 16 digits. Example: 1234567890123.00"
data-rule-decimalExceedsMaxLimit="en"
data-msg-decimalExceedsMaxLimit="Exceeding the maximum limit of 16 digits. Example: 1234567890123.00"
onkeydown="return isDecimal(event, 'en')"
onkeyup="return updateField(this)"
onblur="decimalFormatter(this,
'en',
'Invalid character(s) found. Please enter valid characters.')">
</div>
</td>
</tr>
JavaScript:
/*
* @author: dinesh.lomte
*/
/* Holds the maximum limit of digits to be entered in number field. */
var numericMaxLimit = 13;
/* Holds the maximum limit of digits to be entered in decimal field. */
var decimalMaxLimit = 16;
/**
*
* @param {type} value
* @param {type} locale
* @returns {Boolean}
*/
parseDecimal = function(value, locale) {
value = value.trim();
if (isNull(value)) {
return 0.00;
}
if (isNull(locale)) {
return value;
}
if (getNumberFormat(locale)[0] === '.') {
value = value.replace(/\./g, '');
} else {
value = value.replace(
new RegExp(getNumberFormat(locale)[0], 'g'), '');
}
if (getNumberFormat(locale)[1] === ',') {
value = value.replace(
new RegExp(getNumberFormat(locale)[1], 'g'), '.');
}
return value;
};
/**
*
* @param {type} element
* @param {type} locale
* @param {type} nanMessage
* @returns {Boolean}
*/
decimalFormatter = function (element, locale, nanMessage) {
showErrorMessage(element.id, false, null);
if (isNull(element.id) || isNull(element.value) || isNull(locale)) {
return true;
}
var value = element.value.trim();
value = value.replace(/\s/g, '');
value = parseDecimal(value, locale);
var numberFormatObj = new Intl.NumberFormat(locale,
{ minimumFractionDigits: 2,
maximumFractionDigits: 2
}
);
if (numberFormatObj.format(value) === 'NaN') {
showErrorMessage(element.id, true, nanMessage);
setFocus(element.id);
return false;
}
element.value =
numberFormatObj.format(value);
return true;
};
/**
*
* @param {type} element
* @param {type} locale
* @param {type} nanMessage
* @returns {Boolean}
*/
numberFormatter = function (element, locale, nanMessage) {
showErrorMessage(element.id, false, null);
if (isNull(element.id) || isNull(element.value) || isNull(locale)) {
return true;
}
var value = element.value.trim();
var format = getNumberFormat(locale);
if (hasDecimal(value, format[1])) {
showErrorMessage(element.id, true, nanMessage);
setFocus(element.id);
return false;
}
value = value.replace(/\s/g, '');
value = parseNumber(value, locale);
var numberFormatObj = new Intl.NumberFormat(locale,
{ minimumFractionDigits: 0,
maximumFractionDigits: 0
}
);
if (numberFormatObj.format(value) === 'NaN') {
showErrorMessage(element.id, true, nanMessage);
setFocus(element.id);
return false;
}
element.value =
numberFormatObj.format(value);
return true;
};
/**
*
* @param {type} id
* @param {type} flag
* @param {type} message
* @returns {undefined}
*/
showErrorMessage = function(id, flag, message) {
if (flag) {
// only add if not added
if ($('#'+id).parent().next('.app-error-message').length === 0) {
var errorTag = '<div class=\'app-error-message\'>' + message + '</div>';
$('#'+id).parent().after(errorTag);
}
} else {
// remove it
$('#'+id).parent().next(".app-error-message").remove();
}
};
/**
*
* @param {type} id
* @returns
*/
setFocus = function(id) {
id = id.trim();
if (isNull(id)) {
return;
}
setTimeout(function() {
document.getElementById(id).focus();
}, 10);
};
/**
*
* @param {type} value
* @param {type} locale
* @returns {Array}
*/
parseNumber = function(value, locale) {
value = value.trim();
if (isNull(value)) {
return 0;
}
if (isNull(locale)) {
return value;
}
if (getNumberFormat(locale)[0] === '.') {
return value.replace(/\./g, '');
}
return value.replace(
new RegExp(getNumberFormat(locale)[0], 'g'), '');
};
/**
*
* @param {type} locale
* @returns {Array}
*/
getNumberFormat = function(locale) {
var format = [];
var numberFormatObj = new Intl.NumberFormat(locale,
{ minimumFractionDigits: 2,
maximumFractionDigits: 2
}
);
var value = numberFormatObj.format('132617.07');
format[0] = value.charAt(3);
format[1] = value.charAt(7);
return format;
};
/**
*
* @param {type} value
* @param {type} fractionFormat
* @returns {Boolean}
*/
hasDecimal = function(value, fractionFormat) {
value = value.trim();
if (isNull(value) || isNull(fractionFormat)) {
return false;
}
if (value.indexOf(fractionFormat) >= 1) {
return true;
}
};
/**
*
* @param {type} event
* @param {type} locale
* @returns {Boolean}
*/
isNumber = function(event, locale) {
var keyCode = event.which ? event.which : event.keyCode;
// Validating if user has pressed shift character
if (keyCode === 16) {
return false;
}
if (isNumberKey(keyCode)) {
return true;
}
var numberFormatter = [32, 110, 188, 190];
if (keyCode === 32
&& isNull(getNumberFormat(locale)[0]) === isNull(getFormat(keyCode))) {
return true;
}
if (numberFormatter.indexOf(keyCode) >= 0
&& getNumberFormat(locale)[0] === getFormat(keyCode)) {
return true;
}
return false;
};
/**
*
* @param {type} event
* @param {type} locale
* @returns {Boolean}
*/
isDecimal = function(event, locale) {
var keyCode = event.which ? event.which : event.keyCode;
// Validating if user has pressed shift character
if (keyCode === 16) {
return false;
}
if (isNumberKey(keyCode)) {
return true;
}
var numberFormatter = [32, 110, 188, 190];
if (keyCode === 32
&& isNull(getNumberFormat(locale)[0]) === isNull(getFormat(keyCode))) {
return true;
}
if (numberFormatter.indexOf(keyCode) >= 0
&& (getNumberFormat(locale)[0] === getFormat(keyCode)
|| getNumberFormat(locale)[1] === getFormat(keyCode))) {
return true;
}
return false;
};
/**
*
* @param {type} keyCode
* @returns {Boolean}
*/
isNumberKey = function(keyCode) {
if ((keyCode >= 48 && keyCode <= 57)
|| (keyCode >= 96 && keyCode <= 105)) {
return true;
}
var keys = [8, 9, 13, 35, 36, 37, 39, 45, 46, 109, 144, 173, 189];
if (keys.indexOf(keyCode) !== -1) {
return true;
}
return false;
};
/**
*
* @param {type} keyCode
* @returns {JSON@call;parse.numberFormatter.value|String}
*/
getFormat = function(keyCode) {
var jsonString = '{"numberFormatter" : [{"key":"32", "value":" ", "description":"space"}, {"key":"188", "value":",", "description":"comma"}, {"key":"190", "value":".", "description":"dot"}, {"key":"110", "value":".", "description":"dot"}]}';
var jsonObject = JSON.parse(jsonString);
for (var key in jsonObject.numberFormatter) {
if (jsonObject.numberFormatter.hasOwnProperty(key)
&& keyCode === parseInt(jsonObject.numberFormatter[key].key)) {
return jsonObject.numberFormatter[key].value;
}
}
return '';
};
/**
*
* @type String
*/
var jsonString = '{"shiftCharacterNumberMap" : [{"char":")", "number":"0"}, {"char":"!", "number":"1"}, {"char":"@", "number":"2"}, {"char":"#", "number":"3"}, {"char":"$", "number":"4"}, {"char":"%", "number":"5"}, {"char":"^", "number":"6"}, {"char":"&", "number":"7"}, {"char":"*", "number":"8"}, {"char":"(", "number":"9"}]}';
/**
*
* @param {type} value
* @returns {JSON@call;parse.shiftCharacterNumberMap.number|String}
*/
getShiftCharSpecificNumber = function(value) {
var jsonObject = JSON.parse(jsonString);
for (var key in jsonObject.shiftCharacterNumberMap) {
if (jsonObject.shiftCharacterNumberMap.hasOwnProperty(key)
&& value === jsonObject.shiftCharacterNumberMap[key].char) {
return jsonObject.shiftCharacterNumberMap[key].number;
}
}
return '';
};
/**
*
* @param {type} value
* @returns {Boolean}
*/
isShiftSpecificChar = function(value) {
var jsonObject = JSON.parse(jsonString);
for (var key in jsonObject.shiftCharacterNumberMap) {
if (jsonObject.shiftCharacterNumberMap.hasOwnProperty(key)
&& value === jsonObject.shiftCharacterNumberMap[key].char) {
return true;
}
}
return false;
};
/**
*
* @param {type} element
* @returns {undefined}
*/
updateField = function(element) {
var value = element.value;
for (var index = 0; index < value.length; index++) {
if (!isShiftSpecificChar(value.charAt(index))) {
continue;
}
element.value = value.replace(
value.charAt(index),
getShiftCharSpecificNumber(value.charAt(index)));
}
};
/**
*
* @param {type} value
* @param {type} element
* @param {type} params
*/
jQuery.validator.addMethod('numberExceedsMaxLimit', function(value, element, params) {
value = parseInt(parseNumber(value, params));
if (value.toString().length > numericMaxLimit) {
showErrorMessage(element.id, false, null);
setFocus(element.id);
return false;
}
return true;
}, 'Exceeding the maximum limit of 13 digits. Example: 1234567890123.');
/**
*
* @param {type} value
* @param {type} element
* @param {type} params
*/
jQuery.validator.addMethod('decimalExceedsMaxLimit', function(value, element, params) {
value = parseFloat(parseDecimal(value, params)).toFixed(2);
if (value.toString().substring(
0, value.toString().lastIndexOf('.')).length > numericMaxLimit
|| value.toString().length > decimalMaxLimit) {
showErrorMessage(element.id, false, null);
setFocus(element.id);
return false;
}
return true;
}, 'Exceeding the maximum limit of 16 digits. Example: 1234567890123.00.');
/**
* @param {type} id
* @param {type} locale
* @returns {boolean}
*/
isNumberExceedMaxLimit = function(id, locale) {
var value = parseInt(parseNumber(
document.getElementById(id).value, locale));
if (value.toString().length > numericMaxLimit) {
setFocus(id);
return true;
}
return false;
};
/**
* @param {type} id
* @param {type} locale
* @returns {boolean}
*/
isDecimalExceedsMaxLimit = function(id, locale) {
var value = parseFloat(parseDecimal(
document.getElementById(id).value, locale)).toFixed(2);
if (value.toString().substring(
0, value.toString().lastIndexOf('.')).length > numericMaxLimit
|| value.toString().length > decimalMaxLimit) {
setFocus(id);
return true;
}
return false;
};
Patrick Desjardins' answer looks good, but I prefer my javascript simple. Here's a function I just wrote to take a number in and return it in currency format (minus the dollar sign)
// Format numbers to two decimals with commas
function formatDollar(num) {
var p = num.toFixed(2).split(".");
var chars = p[0].split("").reverse();
var newstr = '';
var count = 0;
for (x in chars) {
count++;
if(count%3 == 1 && count != 1) {
newstr = chars[x] + ',' + newstr;
} else {
newstr = chars[x] + newstr;
}
}
return newstr + "." + p[1];
}
Below is the Patrick Desjardins (alias Daok) code with a bit of comments added and some minor changes:
/*
decimal_sep: character used as decimal separator, it defaults to '.' when omitted
thousands_sep: char used as thousands separator, it defaults to ',' when omitted
*/
Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep)
{
var n = this,
c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal
d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator)
/*
according to [https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function]
the fastest way to check for not defined parameter is to use typeof value === 'undefined'
rather than doing value === undefined.
*/
t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value
sign = (n < 0) ? '-' : '',
//extracting the absolute value of the integer part of the number and converting to string
i = parseInt(n = Math.abs(n).toFixed(c)) + '',
j = ((j = i.length) > 3) ? j % 3 : 0;
return sign + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : '');
}
and here some tests:
//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert(123456789.67392.toMoney() + '\n' + 123456789.67392.toMoney(3) + '\n' + 123456789.67392.toMoney(0) + '\n' + (123456).toMoney() + '\n' + (123456).toMoney(0) + '\n' + 89.67392.toMoney() + '\n' + (89).toMoney());
//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert((-123456789.67392).toMoney() + '\n' + (-123456789.67392).toMoney(-3));
The minor changes are:
moved a bit the Math.abs(decimals)
to be done only when is not NaN
.
decimal_sep
can not be empty string anymore (a some sort of decimal separator is a MUST)
we use typeof thousands_sep === 'undefined'
as suggested in How best to determine if an argument is not sent to the JavaScript function
(+n || 0)
is not needed because this
is a Number
object
A simple option for proper comma placement by reversing the string first and basic regexp.
String.prototype.reverse = function() {
return this.split('').reverse().join('');
};
Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) {
// format decimal or round to nearest integer
var n = this.toFixed( round_decimal ? 0 : 2 );
// convert to a string, add commas every 3 digits from left to right
// by reversing string
return (n + '').reverse().replace( /(\d{3})(?=\d)/g, '$1,' ).reverse();
};
Haven't seen anything like this. It's concise, easy to understand & doesn't rely on any overly complicated regular expressions.
function moneyFormat(price, sign = '$') {
const pieces = parseFloat(price).toFixed(2).split('')
let ii = pieces.length - 3
while ((ii-=3) > 0) {
pieces.splice(ii, 0, ',')
}
return sign + pieces.join('')
}
console.log(
moneyFormat(100),
moneyFormat(1000),
moneyFormat(10000.00),
moneyFormat(1000000000000000000)
)
_x000D_
Here is a version with more options in the final output to allow formatting different currencies in different locality formats.
// higher order function that takes options then a price and will return the formatted price
const makeMoneyFormatter = ({
sign = '$',
delimiter = ',',
decimal = '.',
append = false,
precision = 2,
round = true,
custom
} = {}) => value => {
const e = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
value = round
? (Math.round(value * e[precision]) / e[precision])
: parseFloat(value)
const pieces = value
.toFixed(precision)
.replace('.', decimal)
.split('')
let ii = pieces.length - (precision ? precision + 1 : 0)
while ((ii-=3) > 0) {
pieces.splice(ii, 0, delimiter)
}
if (typeof custom === 'function') {
return custom({
sign,
float: value,
value: pieces.join('')
})
}
return append
? pieces.join('') + sign
: sign + pieces.join('')
}
// create currency converters with the correct formatting options
const formatDollar = makeMoneyFormatter()
const formatPound = makeMoneyFormatter({
sign: '£',
precision: 0
})
const formatEuro = makeMoneyFormatter({
sign: '€',
delimiter: '.',
decimal: ',',
append: true
})
const customFormat = makeMoneyFormatter({
round: false,
custom: ({ value, float, sign }) => `SALE:$${value}USD`
})
console.log(
formatPound(1000),
formatDollar(10000.0066),
formatEuro(100000.001),
customFormat(999999.555)
)
_x000D_
Because every problem deserves a one line solution:
Number.prototype.formatCurrency = function() { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1,') : t + '.' + c; }, '$'); }
This is easy enough to change for different locales, just change the '$1,' to '$1.' and '.' to ',' to swap , and . in numbers, and the currency symbol can be changed by changing the '$' at the end.
Or, if you have ES6, you can just declare the function with default values:
Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = '$') { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1' + thou) : t + dec + c; }, sym); }
console.log((4215.57).formatCurrency())
$4,215.57
console.log((4216635.57).formatCurrency('.', ','))
$4.216.635,57
console.log((4216635.57).formatCurrency('.', ',', "\u20AC"))
€4.216.635,57
Oh and it works for negative numbers too:
console.log((-6635.574).formatCurrency('.', ',', "\u20AC"))
-€6.635,57
console.log((-1066.507).formatCurrency())
-$1,066.51
And of course you don't have to have a currency symbol
console.log((1234.586).formatCurrency(',','.',''))
1,234.59
console.log((-7890123.456).formatCurrency(',','.',''))
-7,890,123.46
console.log((1237890.456).formatCurrency('.',',',''))
1.237.890,46
The YUI codebase uses the following formmating:
format: function(nData, oConfig) {
oConfig = oConfig || {};
if(!YAHOO.lang.isNumber(nData)) {
nData *= 1;
}
if(YAHOO.lang.isNumber(nData)) {
var sOutput = nData + "";
var sDecimalSeparator = (oConfig.decimalSeparator) ? oConfig.decimalSeparator : ".";
var nDotIndex;
// Manage decimals
if(YAHOO.lang.isNumber(oConfig.decimalPlaces)) {
// Round to the correct decimal place
var nDecimalPlaces = oConfig.decimalPlaces;
var nDecimal = Math.pow(10, nDecimalPlaces);
sOutput = Math.round(nData*nDecimal)/nDecimal + "";
nDotIndex = sOutput.lastIndexOf(".");
if(nDecimalPlaces > 0) {
// Add the decimal separator
if(nDotIndex < 0) {
sOutput += sDecimalSeparator;
nDotIndex = sOutput.length-1;
}
// Replace the "."
else if(sDecimalSeparator !== "."){
sOutput = sOutput.replace(".",sDecimalSeparator);
}
// Add missing zeros
while((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) {
sOutput += "0";
}
}
}
// Add the thousands separator
if(oConfig.thousandsSeparator) {
var sThousandsSeparator = oConfig.thousandsSeparator;
nDotIndex = sOutput.lastIndexOf(sDecimalSeparator);
nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length;
var sNewOutput = sOutput.substring(nDotIndex);
var nCount = -1;
for (var i=nDotIndex; i>0; i--) {
nCount++;
if ((nCount%3 === 0) && (i !== nDotIndex)) {
sNewOutput = sThousandsSeparator + sNewOutput;
}
sNewOutput = sOutput.charAt(i-1) + sNewOutput;
}
sOutput = sNewOutput;
}
// Prepend prefix
sOutput = (oConfig.prefix) ? oConfig.prefix + sOutput : sOutput;
// Append suffix
sOutput = (oConfig.suffix) ? sOutput + oConfig.suffix : sOutput;
return sOutput;
}
// Still not a Number, just return unaltered
else {
return nData;
}
}
it would need editing as the YUI library is configurable, like replacing oConfig.decimalSeparator with "."
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat Example: Using locales
This example shows some of the variations in localized number formats. In order to get the format of the language used in the user interface of your application, make sure to specify that language (and possibly some fallback languages) using the locales argument:
var number = 123456.789;
// German uses comma as decimal separator and period for thousands console.log(new Intl.NumberFormat('de-DE').format(number)); // ? 123.456,789
// Arabic in most Arabic speaking countries uses real Arabic digits console.log(new Intl.NumberFormat('ar-EG').format(number)); // ? ??????????
// India uses thousands/lakh/crore separators console.log(new Intl.NumberFormat('en-IN').format(number));
I suggest the NumberFormat class from Google Visualization API.
You can do something like this:
var formatter = new google.visualization.NumberFormat({
prefix: '$',
pattern: '#,###,###.##'
});
formatter.formatValue(1000000); // $ 1,000,000
I hope it helps.
Here's mine...
function thousandCommas(num) {
num = num.toString().split('.');
var ints = num[0].split('').reverse();
for (var out=[],len=ints.length,i=0; i < len; i++) {
if (i > 0 && (i % 3) === 0) out.push(',');
out.push(ints[i]);
}
out = out.reverse() && out.join('');
if (num.length === 2) out += '.' + num[1];
return out;
}
Here is the short and best one to convert numbers into currency format:
function toCurrency(amount){
return amount.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
}
// usage: toCurrency(3939920.3030);
Cheers! Anunay
Because why not add another answer. I based this heavily on the answer from VisioN.
function format (val) {
val = (+val).toLocaleString();
val = (+val).toFixed(2);
val += "";
return val.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1" + format.thousands);
}
(function (isUS) {
format.decimal = isUS ? "." : ",";
format.thousands = isUS ? "," : ".";
}(("" + (+(0.00).toLocaleString()).toFixed(2)).indexOf(".") > 0));
I tested with inputs:
[ ""
, "1"
, "12"
, "123"
, "1234"
, "12345"
, "123456"
, "1234567"
, "12345678"
, "123456789"
, "1234567890"
, ".12"
, "1.12"
, "12.12"
, "123.12"
, "1234.12"
, "12345.12"
, "123456.12"
, "1234567.12"
, "12345678.12"
, "123456789.12"
, "1234567890.12"
, "1234567890.123"
, "1234567890.125"
].forEach(function (item) {
console.log(format(item));
});
And got these results:
0.00
1.00
12.00
123.00
1,234.00
12,345.00
123,456.00
1,234,567.00
12,345,678.00
123,456,789.00
1,234,567,890.00
0.12
1.12
12.12
123.12
1,234.12
12,345.12
123,456.12
1,234,567.12
12,345,678.12
123,456,789.12
1,234,567,890.12
1,234,567,890.12
1,234,567,890.13
Just for fun.
many of the answers had helpful ideas, but none of them could fit my needs. So I used all the ideas and build this example:
function Format_Numb( fmt){
var decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
if(typeof decSgn==="undefined") decSgn = ".";
if(typeof kommaSgn==="undefined") kommaSgn= ",";
var s3digits=/(\d{1,3}(?=(\d{3})+(?=[.]|$))|(?:[.]\d*))/g;
var dflt_nk="00000000".substring(0,decimals);
//--------------------------------
// handler for pattern: "%m"
var _f_money= function( v_in){
var v=v_in.toFixed(decimals);
var add_nk=",00";
var arr= v.split(".");
return arr[0].toString().replace(s3digits, function ($0) {
return ($0.charAt(0)==".")
? ((add_nk=""),(kommaSgn + $0.substring(1)))
: ($0 + decSgn);
})
+ ( (decimals > 0)
? ( kommaSgn
+ (
(arr.length > 1)
? arr[1]
: dflt_nk
)
)
: ""
);
}
// handler for pattern: "%<len>[.<prec>]f"
var _f_flt= function( v_in,l,prec){
var v=(typeof prec !== "undefined") ? v_in.toFixed(prec):v_in;
return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
?(Array(l+1).join(" ") + v)
:v;
}
// handler for pattern: "%<len>x"
var _f_hex= function( v_in,l,flUpper){
var v= Math.round(v_in).toString(16);
if(flUpper) v=v.toUpperCase();
return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
?(Array(l+1).join("0") + v)
:v;
}
//...can be extended..., just add the function, f.e.: var _f_octal= function( v_in,...){
//--------------------------------
if( typeof(fmt)!=="undefined"){
//...can be extended..., just add the char,f.e."O": MFX -> MFXO
var rpatt=/(?:%([^%"MFX]*)([MFX]))|(?:"([^"]*)")|("|%%)/gi;
var _qu= "\"";
var _mask_qu= "\\\"";
var str= fmt.toString().replace( rpatt,function($0,$1,$2,$3,$4){
var f;
if(typeof $1 !== "undefined"){
switch($2.toUpperCase()){
case "M": f= "_f_money(v)"; break;
case "F": var n_dig0,n_dig1;
var re_flt=/^(?:(\d))*(?:[.](\d))*$/;
$1.replace(re_flt,function($0,$1,$2){
n_dig0=$1;
n_dig1=$2;
});
f= "_f_flt(v," + n_dig0 + "," + n_dig1 + ")"; break;
case "X": var n_dig="undefined";
var re_flt=/^(\d*)$/;
$1.replace(re_flt,function($0){
if($0!="")n_dig=$0;
});
f= "_f_hex(v," + n_dig + "," + ($2=="X") + ")"; break;
//...can be extended..., f.e.: case "O":
}
return "\"+"+f+"+\"";
} else if(typeof $3 !== "undefined"){
return _mask_qu + $3 + _mask_qu;
} else {
return ($4==_qu)?_mask_qu:$4.charAt(0);
}
});
var cmd= "return function(v){"
+ "if(typeof v === \"undefined\")return \"\";" //null returned as empty string
+ "if(!v.toFixed)return v.toString();" //not numb returned as string
+ "return \"" + str + "\";"
+ "}";
//...can be extended..., just add the function name in the 2 places:
return new Function( "_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
}
}
First, I needed a C-style format-string-definition that should be flexible, but very easy to use and I defined it in following way; patterns:
%[<len>][.<prec>]f float, example "%f", "%8.2d", "%.3f"
%m money
%[<len>]x hexadecimal lower case, example "%x", "%8x"
%[<len>]X hexadecimal upper case, example "%X", "%8X"
because there is no need to format others then to Euro for me, I implemented only "%m". But it's easy to extend this... Like in C the format string is a string containing the patterns, f.e. for Euro: "%m €" (returns strings like "8.129,33 €")
Beside the flexibility I needed a very fast solution for processing tables. That means, that when processing thousands of cells the processing of format string must not be done more than once. A call like "format( value, fmt)" is not acceptable for me, but this must be splitted in two steps:
// var formatter = Format_Numb( "%m €");
//simple example for Euro...
// but we use a complex example:
var formatter = Format_Numb("a%%%3mxx \"zz\"%8.2f°\" >0x%8X<");
// formatter is now a function, which can be used more than once (this is an example, that can be tested:)
var v1= formatter( 1897654.8198344);
var v2= formatter( 4.2);
... (and thousands of rows)
Also for performance, _f_money enclosures the regexp;
Third, a call like "format( value, fmt)" is not acceptable because: Although it should be possible to format different collections of objects (f.e. cells of a column) with different masks, I don't want to have something to handle format strings at the point of processing. At this point I only want TO USE formatting, like in
for( var cell in cells){ do_something( cell.col.formatter( cell.value)); }
What format - maybe it's defined in an ini, in a xml for each column or somewhere else ..., but analyzing and setting formats or dealing with internationalizaton is processed in totally another place, and there I want to assign the formatter to the collection without thinking about performance issues:
col.formatter = Format_Numb( _getFormatForColumn(...) );
Fourth, I wanted an "tolerant" solution, so passing f.e. a string instead of a number should return simply the string, but "null" should return en empty string.
(Also formatting "%4.2f" must not cut something if the value is too big.)
And last but not least - it should be readable and easy extendable, WITHOUT having any effects in performance... For example, if somebody needs "octal values", please refer to lines with "...can be extended..." - I think that should be a very easy task.
My overall focus lay on performance. Each "processing routine" (f.e. _f_money) can be encapsulated optimized or exchanged with other ideas in this or other threads without change of the "prepare routines" (analyze format strings and creation of the functions), which must only processed once and in that sense are not so performance critical like the conversion calls of thousands of numbers.
For all, who prefer methods of numbers:
Number.prototype.format_euro=( function(formatter){
return function(){ return formatter(this); }})
(Format_Numb( "%m €"));
var v_euro= (8192.3282).format_euro(); //results: 8.192,33 €
Number.prototype.format_hex= (function(formatter){
return function(){ return formatter(this); }})
(Format_Numb( "%4x"));
var v_hex= (4.3282).format_hex();
Although I tested something there may be a lot of bugs in the code. So it's not a ready module, but just an idea and a starting point for non-js-experts like me. The code contains many and little modified ideas from a lot of stackoverflow-posts; sorry I can't reference all of them, but thanks to all the experts.
+1 to Jonathan M for providing the original method. Since this is explicitly a currency formatter, I went ahead and added the currency symbol (defaults to '$') to the output, and added a default comma as the thousands separator. If you don't actually want a currency symbol (or thousands separator), just use "" (empty string) as your argument for it.
Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) {
// check the args and supply defaults:
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
decSeparator = decSeparator == undefined ? "." : decSeparator;
thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
currencySymbol = currencySymbol == undefined ? "$" : currencySymbol;
var n = this,
sign = n < 0 ? "-" : "",
i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "",
j = (j = i.length) > 3 ? j % 3 : 0;
return sign + currencySymbol + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};
This might work:
function format_currency(v, number_of_decimals, decimal_separator, currency_sign){
return (isNaN(v)? v : currency_sign + parseInt(v||0).toLocaleString() + decimal_separator + (v*1).toFixed(number_of_decimals).slice(-number_of_decimals));
}
No loops, no regexes, no arrays, no exotic conditionals.
Here are some solutions, all pass the test suite, test suite and benchmark included, if you want copy and paste to test, try This Gist.
Base on https://stackoverflow.com/a/14428340/1877620, but fix if there is no decimal point.
if (typeof Number.prototype.format === 'undefined') {
Number.prototype.format = function (precision) {
if (!isFinite(this)) {
return this.toString();
}
var a = this.toFixed(precision).split('.');
a[0] = a[0].replace(/\d(?=(\d{3})+$)/g, '$&,');
return a.join('.');
}
}
if (typeof Number.prototype.format === 'undefined') {
Number.prototype.format = function (precision) {
if (!isFinite(this)) {
return this.toString();
}
var a = this.toFixed(precision).split('.'),
// skip the '-' sign
head = Number(this < 0);
// skip the digits that's before the first thousands separator
head += (a[0].length - head) % 3 || 3;
a[0] = a[0].slice(0, head) + a[0].slice(head).replace(/\d{3}/g, ',$&');
return a.join('.');
};
}
if (typeof Number.prototype.format === 'undefined') {
Number.prototype.format = function (precision) {
if (!isFinite(this)) {
return this.toString();
}
var a = this.toFixed(precision).split('.');
a[0] = a[0]
.split('').reverse().join('')
.replace(/\d{3}(?=\d)/g, '$&,')
.split('').reverse().join('');
return a.join('.');
};
}
if (typeof Number.prototype.format === 'undefined') {
Number.prototype.format = function (precision) {
if (!isFinite(this)) {
return this.toString();
}
var a = this.toFixed(precision).split('');
a.push('.');
var i = a.indexOf('.') - 3;
while (i > 0 && a[i-1] !== '-') {
a.splice(i, 0, ',');
i -= 3;
}
a.pop();
return a.join('');
};
}
console.log('======== Demo ========')
console.log(
(1234567).format(0),
(1234.56).format(2),
(-1234.56).format(0)
);
var n = 0;
for (var i=1; i<20; i++) {
n = (n * 10) + (i % 10)/100;
console.log(n.format(2), (-n).format(2));
}
If we want custom thousands separator or decimal separator, use replace()
:
123456.78.format(2).replace(',', ' ').replace('.', ' ');
function assertEqual(a, b) {
if (a !== b) {
throw a + ' !== ' + b;
}
}
function test(format_function) {
console.log(format_function);
assertEqual('NaN', format_function.call(NaN, 0))
assertEqual('Infinity', format_function.call(Infinity, 0))
assertEqual('-Infinity', format_function.call(-Infinity, 0))
assertEqual('0', format_function.call(0, 0))
assertEqual('0.00', format_function.call(0, 2))
assertEqual('1', format_function.call(1, 0))
assertEqual('-1', format_function.call(-1, 0))
// decimal padding
assertEqual('1.00', format_function.call(1, 2))
assertEqual('-1.00', format_function.call(-1, 2))
// decimal rounding
assertEqual('0.12', format_function.call(0.123456, 2))
assertEqual('0.1235', format_function.call(0.123456, 4))
assertEqual('-0.12', format_function.call(-0.123456, 2))
assertEqual('-0.1235', format_function.call(-0.123456, 4))
// thousands separator
assertEqual('1,234', format_function.call(1234.123456, 0))
assertEqual('12,345', format_function.call(12345.123456, 0))
assertEqual('123,456', format_function.call(123456.123456, 0))
assertEqual('1,234,567', format_function.call(1234567.123456, 0))
assertEqual('12,345,678', format_function.call(12345678.123456, 0))
assertEqual('123,456,789', format_function.call(123456789.123456, 0))
assertEqual('-1,234', format_function.call(-1234.123456, 0))
assertEqual('-12,345', format_function.call(-12345.123456, 0))
assertEqual('-123,456', format_function.call(-123456.123456, 0))
assertEqual('-1,234,567', format_function.call(-1234567.123456, 0))
assertEqual('-12,345,678', format_function.call(-12345678.123456, 0))
assertEqual('-123,456,789', format_function.call(-123456789.123456, 0))
// thousands separator and decimal
assertEqual('1,234.12', format_function.call(1234.123456, 2))
assertEqual('12,345.12', format_function.call(12345.123456, 2))
assertEqual('123,456.12', format_function.call(123456.123456, 2))
assertEqual('1,234,567.12', format_function.call(1234567.123456, 2))
assertEqual('12,345,678.12', format_function.call(12345678.123456, 2))
assertEqual('123,456,789.12', format_function.call(123456789.123456, 2))
assertEqual('-1,234.12', format_function.call(-1234.123456, 2))
assertEqual('-12,345.12', format_function.call(-12345.123456, 2))
assertEqual('-123,456.12', format_function.call(-123456.123456, 2))
assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2))
assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2))
assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2))
}
console.log('======== Testing ========');
test(Number.prototype.format);
test(Number.prototype.format1);
test(Number.prototype.format2);
test(Number.prototype.format3);
function benchmark(f) {
var start = new Date().getTime();
f();
return new Date().getTime() - start;
}
function benchmark_format(f) {
console.log(f);
time = benchmark(function () {
for (var i = 0; i < 100000; i++) {
f.call(123456789, 0);
f.call(123456789, 2);
}
});
console.log(time.format(0) + 'ms');
}
// if not using async, browser will stop responding while running.
// this will create a new thread to benchmark
async = [];
function next() {
setTimeout(function () {
f = async.shift();
f && f();
next();
}, 10);
}
console.log('======== Benchmark ========');
async.push(function () { benchmark_format(Number.prototype.format); });
next();
You can use Intl
natively like this:
// value: 11.07
Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value)
// result: R$ 11,07
documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
hope this helps! ;)
(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); // 12,345.67
The idea behind this solution is replacing matched sections with first match and comma, i.e. '$&,'
. The matching is done using lookahead approach. You may read the expression as "match a number if it is followed by a sequence of three number sets (one or more) and a dot".
TESTS:
1 --> "1.00"
12 --> "12.00"
123 --> "123.00"
1234 --> "1,234.00"
12345 --> "12,345.00"
123456 --> "123,456.00"
1234567 --> "1,234,567.00"
12345.67 --> "12,345.67"
DEMO: http://jsfiddle.net/hAfMM/9571/
You can also extend the prototype of Number
object to add additional support of any number of decimals [0 .. n]
and the size of number groups [0 .. x]
:
/**
* Number.prototype.format(n, x)
*
* @param integer n: length of decimal
* @param integer x: length of sections
*/
Number.prototype.format = function(n, x) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
};
1234..format(); // "1,234"
12345..format(2); // "12,345.00"
123456.7.format(3, 2); // "12,34,56.700"
123456.789.format(2, 4); // "12,3456.79"
DEMO / TESTS: http://jsfiddle.net/hAfMM/435/
In this super extended version you may set different delimiter types:
/**
* Number.prototype.format(n, x, s, c)
*
* @param integer n: length of decimal
* @param integer x: length of whole part
* @param mixed s: sections delimiter
* @param mixed c: decimal delimiter
*/
Number.prototype.format = function(n, x, s, c) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
num = this.toFixed(Math.max(0, ~~n));
return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
};
12345678.9.format(2, 3, '.', ','); // "12.345.678,90"
123456.789.format(4, 4, ' ', ':'); // "12 3456:7890"
12345678.9.format(0, 3, '-'); // "12-345-679"
DEMO / TESTS: http://jsfiddle.net/hAfMM/612/
var number = 3500;
alert(new Intl.NumberFormat().format(number));
// ? "3,500" if in US English locale
I like it simple:
function formatPriceUSD(price) {
var strPrice = price.toFixed(2).toString();
var a = strPrice.split('');
if (price > 1000000000)
a.splice(a.length - 12, 0, ',');
if (price > 1000000)
a.splice(a.length - 9, 0, ',');
if (price > 1000)
a.splice(a.length - 6, 0, ',');
return '$' + a.join("");
}
Numeral.js - a js library for easy number formatting by @adamwdraper
numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
Here's a straightforward formatter in vanilla JS:
function numberFormatter (num) {
console.log(num)
var wholeAndDecimal = String(num.toFixed(2)).split(".");
console.log(wholeAndDecimal)
var reversedWholeNumber = Array.from(wholeAndDecimal[0]).reverse();
var formattedOutput = [];
reversedWholeNumber.forEach( (digit, index) => {
formattedOutput.push(digit);
if ((index + 1) % 3 === 0 && index < reversedWholeNumber.length - 1) {
formattedOutput.push(",");
}
})
formattedOutput = formattedOutput.reverse().join('') + "." + wholeAndDecimal[1];
return formattedOutput;
}
There are already good answers. Here's simple attempt for fun:
function currencyFormat(no) {
var ar = (+no).toFixed(2).split('.');
return [
numberFormat(ar[0]|0),
'.',
ar[1]
].join('');
}
function numberFormat(no) {
var str = no + '';
var ar = [];
var i = str.length -1;
while( i >= 0 ) {
ar.push( (str[i-2]||'') + (str[i-1]|| '')+ (str[i]|| ''));
i= i-3;
}
return ar.reverse().join(',');
}
The run some examples
console.log(
currencyFormat(1),
currencyFormat(1200),
currencyFormat(123),
currencyFormat(9870000),
currencyFormat(12345),
currencyFormat(123456.232)
)
55 answers clearly begs for another one
function centsToDollaString(x){
var cents = x + ""
while(cents.length < 4){
cents = "0" + cents;
}
var dollars = cents.substr(0,cents.length - 2)
var decimal = cents.substr(cents.length - 2, 2)
while(dollars.length % 3 != 0){
dollars = "0" + dollars;
}
str = dollars.replace(/(\d{3})(?=\d)/g, "$1" + ",").replace(/^0*(?=.)/,"");
return "$" + str + "." + decimal;
}
As usually, there are multiple ways of doing the same thing but I would avoid using Number.prototype.toLocaleString
since it can return different values based on the user settings.
I also don't recommend extending the Number.prototype
- extending native objects prototypes is a bad practice since it can cause conflicts with other people code (e.g. libraries/frameworks/plugins) and may not be compatible with future JavaScript implementations/versions.
I believe that Regular Expressions are the best approach for the problem, here is my implementation:
/**
* Converts number into currency format
* @param {number} number Number that should be converted.
* @param {string} [decimalSeparator] Decimal separator, defaults to '.'.
* @param {string} [thousandsSeparator] Thousands separator, defaults to ','.
* @param {int} [nDecimalDigits] Number of decimal digits, defaults to `2`.
* @return {string} Formatted string (e.g. numberToCurrency(12345.67) returns '12,345.67')
*/
function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){
//default values
decimalSeparator = decimalSeparator || '.';
thousandsSeparator = thousandsSeparator || ',';
nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits;
var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits
parts = new RegExp('^(-?\\d{1,3})((?:\\d{3})+)(\\.(\\d{'+ nDecimalDigits +'}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4]
if(parts){ //number >= 1000 || number <= -1000
return parts[1] + parts[2].replace(/\d{3}/g, thousandsSeparator + '$&') + (parts[4] ? decimalSeparator + parts[4] : '');
}else{
return fixed.replace('.', decimalSeparator);
}
}
edited on 2010/08/30: added option to set number of decimal digits. edited on 2011/08/23: added option to set number of decimal digits to zero.
JavaScript has a number formatter (part of the Internationalization API).
// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
// These options are needed to round to whole numbers if that's what you want.
//minimumFractionDigits: 0, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
//maximumFractionDigits: 0, // (causes 2500.99 to be printed as $2,501)
});
formatter.format(2500); /* $2,500.00 */
Use undefined
in place of the first argument ('en-US'
in the example) to use the system locale (the user locale in case the code is running in a browser). Further explanation of the locale code.
Here's a list of the currency codes.
A final note comparing this to the older .toLocaleString
. They both offer essentially the same functionality. However, toLocaleString in its older incarnations (pre-Intl) does not actually support locales: it uses the system locale. So when debugging old browsers, be sure that you're using the correct version (MDN suggests to check for the existence of Intl
). No need to worry about this at all if you don't care about old browsers or just use the shim.
Also, the performance of both is the same for a single item, but if you have a lot of numbers to format, using Intl.NumberFormat
is ~70 times faster. Therefore, it's usually best to use Intl.NumberFormat
and instantiate only 1 per page load. Anyway, here's the equivalent usage of toLocaleString
:
(2500).toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
}); /* $2,500.00 */
There is a javascript port of the PHP function "number_format".
I find it very usefull as it is easy to use and recognisable for PHP developers.
function number_format (number, decimals, dec_point, thousands_sep) {
var n = number, prec = decimals;
var toFixedFix = function (n,prec) {
var k = Math.pow(10,prec);
return (Math.round(n*k)/k).toString();
};
n = !isFinite(+n) ? 0 : +n;
prec = !isFinite(+prec) ? 0 : Math.abs(prec);
var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep;
var dec = (typeof dec_point === 'undefined') ? '.' : dec_point;
var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec);
//fix for IE parseFloat(0.55).toFixed(0) = 0;
var abs = toFixedFix(Math.abs(n), prec);
var _, i;
if (abs >= 1000) {
_ = abs.split(/\D/);
i = _[0].length % 3 || 3;
_[0] = s.slice(0,i + (n < 0)) +
_[0].slice(i).replace(/(\d{3})/g, sep+'$1');
s = _.join(dec);
} else {
s = s.replace('.', dec);
}
var decPos = s.indexOf(dec);
if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec) {
s += new Array(prec-(s.length-decPos-1)).join(0)+'0';
}
else if (prec >= 1 && decPos === -1) {
s += dec+new Array(prec).join(0)+'0';
}
return s;
}
(Comment block from the original, included below for examples & credit where due)
// Formats a number with grouped thousands
//
// version: 906.1806
// discuss at: http://phpjs.org/functions/number_format
// + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfix by: Michael White (http://getsprink.com)
// + bugfix by: Benjamin Lupton
// + bugfix by: Allan Jensen (http://www.winternet.no)
// + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// + bugfix by: Howard Yeend
// + revised by: Luke Smith (http://lucassmith.name)
// + bugfix by: Diogo Resende
// + bugfix by: Rival
// + input by: Kheang Hok Chin (http://www.distantia.ca/)
// + improved by: davook
// + improved by: Brett Zamir (http://brett-zamir.me)
// + input by: Jay Klehr
// + improved by: Brett Zamir (http://brett-zamir.me)
// + input by: Amir Habibi (http://www.residence-mixte.com/)
// + bugfix by: Brett Zamir (http://brett-zamir.me)
// * example 1: number_format(1234.56);
// * returns 1: '1,235'
// * example 2: number_format(1234.56, 2, ',', ' ');
// * returns 2: '1 234,56'
// * example 3: number_format(1234.5678, 2, '.', '');
// * returns 3: '1234.57'
// * example 4: number_format(67, 2, ',', '.');
// * returns 4: '67,00'
// * example 5: number_format(1000);
// * returns 5: '1,000'
// * example 6: number_format(67.311, 2);
// * returns 6: '67.31'
// * example 7: number_format(1000.55, 1);
// * returns 7: '1,000.6'
// * example 8: number_format(67000, 5, ',', '.');
// * returns 8: '67.000,00000'
// * example 9: number_format(0.9, 0);
// * returns 9: '1'
// * example 10: number_format('1.20', 2);
// * returns 10: '1.20'
// * example 11: number_format('1.20', 4);
// * returns 11: '1.2000'
// * example 12: number_format('1.2000', 3);
// * returns 12: '1.200'
There is a built-in function
toFixed in javascript
var num = new Number(349);
document.write("$" + num.toFixed(2));
Works for all current browsers
Use toLocaleString
to format a currency in it's language-sensitive representation (using ISO 4217 currency codes).
(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2})
Example South African Rand code snippets for @avenmore
console.log((2500).toLocaleString("en-ZA", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))_x000D_
// -> R 2 500,00_x000D_
console.log((2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))_x000D_
// -> ZAR 2,500.00
_x000D_
Number(value)_x000D_
.toFixed(2)_x000D_
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
_x000D_
String.prototype.toPrice = function () {
var v;
if (/^\d+(,\d+)$/.test(this))
v = this.replace(/,/, '.');
else if (/^\d+((,\d{3})*(\.\d+)?)?$/.test(this))
v = this.replace(/,/g, "");
else if (/^\d+((.\d{3})*(,\d+)?)?$/.test(this))
v = this.replace(/\./g, "").replace(/,/, ".");
var x = parseFloat(v).toFixed(2).toString().split("."),
x1 = x[0],
x2 = ((x.length == 2) ? "." + x[1] : ".00"),
exp = /^([0-9]+)(\d{3})/;
while (exp.test(x1))
x1 = x1.replace(exp, "$1" + "," + "$2");
return x1 + x2;
}
alert("123123".toPrice()); //123,123.00
alert("123123,316".toPrice()); //123,123.32
alert("12,312,313.33213".toPrice()); //12,312,313.33
alert("123.312.321,32132".toPrice()); //123,312,321.32
I use the library Globalize (from Microsoft):
It's a great project to localize numbers, currencies and dates and to have them automatically formatted the right way according to the user locale! ...and despite it should be a jQuery extension, it's currently a 100% independent library. I suggest you all to try it out! :)
Minimalistic approach that just meets the original requirements:
function formatMoney(n) {
return "$ " + (Math.round(n * 100) / 100).toLocaleString();
}
@Daniel Magliola: You're right, the above was a hasty, incomplete implementation. Here's the corrected implementation:
function formatMoney(n) {
return "$ " + n.toLocaleString().split(".")[0] + "."
+ n.toFixed(2).split(".")[1];
}
Coffeescript for Patrick's popular answer above:
Number::formatMoney = (decimalPlaces, decimalChar, thousandsChar) ->
n = this
c = decimalPlaces
d = decimalChar
t = thousandsChar
c = (if isNaN(c = Math.abs(c)) then 2 else c)
d = (if d is undefined then "." else d)
t = (if t is undefined then "," else t)
s = (if n < 0 then "-" else "")
i = parseInt(n = Math.abs(+n or 0).toFixed(c)) + ""
j = (if (j = i.length) > 3 then j % 3 else 0)
s + (if j then i.substr(0, j) + t else "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (if c then d + Math.abs(n - i).toFixed(c).slice(2) else "")
There is no equivalent of "formatNumber" in JavaScript. You can write it yourself or find a library that already does this.
Take a look at the JavaScript Number object and see if it can help you.
toLocaleString()
will format a number using location specific thousands separator. toFixed()
will round the number to a specific number of decimal places.To use these at the same time the value must have its type changed back to a number because they both output a string.
Example:
Number((someNumber).toFixed(1)).toLocaleString()
This answer meets the following criteria:
This code is built on concepts from other answers. It's execution speed should be among the better posted here if that's a concern.
var decimalCharacter = Number("1.1").toLocaleString().substr(1,1);
var defaultCurrencyMarker = "$";
function formatCurrency(number, currencyMarker) {
if (typeof number != "number")
number = parseFloat(number, 10);
// if NaN is passed in or comes from the parseFloat, set it to 0.
if (isNaN(number))
number = 0;
var sign = number < 0 ? "-" : "";
number = Math.abs(number); // so our signage goes before the $ symbol.
var integral = Math.floor(number);
var formattedIntegral = integral.toLocaleString();
// IE returns "##.00" while others return "##"
formattedIntegral = formattedIntegral.split(decimalCharacter)[0];
var decimal = Math.round((number - integral) * 100);
return sign + (currencyMarker || defaultCurrencyMarker) +
formattedIntegral +
decimalCharacter +
decimal.toString() + (decimal < 10 ? "0" : "");
}
These tests only work on a US locale machine. This decision was made for simplicity and because this could cause of crappy input (bad auto-localization) allowing for crappy output issues.
var tests = [
// [ input, expected result ]
[123123, "$123,123.00"], // no decimal
[123123.123, "$123,123.12"], // decimal rounded down
[123123.126, "$123,123.13"], // decimal rounded up
[123123.4, "$123,123.40"], // single decimal
["123123", "$123,123.00"], // repeat subset of the above using string input.
["123123.123", "$123,123.12"],
["123123.126", "$123,123.13"],
[-123, "-$123.00"] // negatives
];
for (var testIndex=0; testIndex < tests.length; testIndex++) {
var test = tests[testIndex];
var formatted = formatCurrency(test[0]);
if (formatted == test[1]) {
console.log("Test passed, \"" + test[0] + "\" resulted in \"" + formatted + "\"");
} else {
console.error("Test failed. Expected \"" + test[1] + "\", got \"" + formatted + "\"");
}
}
javascript-number-formatter (formerly at Google Code)
#,##0.00
or with negation -000.####
.# ##0,00
, #,###.##
, #'###.##
or any type of non-numbering symbol.#,##,#0.000
or #,###0.##
are all valid.##,###,##.#
or 0#,#00#.###0#
are all OK.format( "0.0000", 3.141592)
.(excerpt from its README)
I wanted a vanilla javascript solution that automatically returned the decimal portion.
function formatDollar(amount) {
var dollar = Number(amount).toLocaleString("us", "currency");
//decimals
var arrAmount = dollar.split(".");
if (arrAmount.length==2) {
var decimal = arrAmount[1];
if (decimal.length==1) {
arrAmount[1] += "0";
}
}
if (arrAmount.length==1) {
arrAmount.push("00");
}
return "$" + arrAmount.join(".");
}
console.log(formatDollar("1812.2");
Here is a mootools 1.2 implementation from the code provided by XMLilley...
Number.implement('format', function(decPlaces, thouSeparator, decSeparator){
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
decSeparator = decSeparator === undefined ? '.' : decSeparator;
thouSeparator = thouSeparator === undefined ? ',' : thouSeparator;
var num = this,
sign = num < 0 ? '-' : '',
i = parseInt(num = Math.abs(+num || 0).toFixed(decPlaces)) + '',
j = (j = i.length) > 3 ? j % 3 : 0;
return sign + (j ? i.substr(0, j) + thouSeparator : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thouSeparator) + (decPlaces ? decSeparator + Math.abs(num - i).toFixed(decPlaces).slice(2) : '');
});
Code from Jonathan M looks to complicated for me so I rewrote it and got about 30% on FF v30 and 60% on Chrome v35 speed boost (http://jsperf.com/number-formating2):
Number.prototype.formatNumber = function(decPlaces, thouSeparator, decSeparator) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
decSeparator = decSeparator == undefined ? "." : decSeparator;
thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
var n = this.toFixed(decPlaces);
if (decPlaces) {
var i = n.substr(0, n.length - (decPlaces + 1));
var j = decSeparator + n.substr(-decPlaces);
} else {
i = n;
j = '';
}
function reverse(str) {
var sr = '';
for (var l = str.length - 1; l >= 0; l--) {
sr += str.charAt(l);
}
return sr;
}
if (parseInt(i)) {
i = reverse(reverse(i).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator));
}
return i+j;
};
Usage:
var sum = 123456789.5698;
var formatted = '$' + sum.formatNumber(2,',','.'); // "$123,456,789.57"
http://code.google.com/p/javascript-number-formatter/ :
UPDATE This is my home grown pp
utilities for most common tasks:
var NumUtil = {};
/**
Petty print 'num' wth exactly 'signif' digits.
pp(123.45, 2) == "120"
pp(0.012343, 3) == "0.0123"
pp(1.2, 3) == "1.20"
*/
NumUtil.pp = function(num, signif) {
if (typeof(num) !== "number")
throw 'NumUtil.pp: num is not a number!';
if (isNaN(num))
throw 'NumUtil.pp: num is NaN!';
if (num < 1e-15 || num > 1e15)
return num;
var r = Math.log(num)/Math.LN10;
var dot = Math.floor(r) - (signif-1);
r = r - Math.floor(r) + (signif-1);
r = Math.round(Math.exp(r * Math.LN10)).toString();
if (dot >= 0) {
for (; dot > 0; dot -= 1)
r += "0";
return r;
} else if (-dot >= r.length) {
var p = "0.";
for (; -dot > r.length; dot += 1) {
p += "0";
}
return p+r;
} else {
return r.substring(0, r.length + dot) + "." + r.substring(r.length + dot);
}
}
/** Append leading zeros up to 2 digits. */
NumUtil.align2 = function(v) {
if (v < 10)
return "0"+v;
return ""+v;
}
/** Append leading zeros up to 3 digits. */
NumUtil.align3 = function(v) {
if (v < 10)
return "00"+v;
else if (v < 100)
return "0"+v;
return ""+v;
}
NumUtil.integer = {};
/** Round to integer and group by 3 digits. */
NumUtil.integer.pp = function(num) {
if (typeof(num) !== "number") {
console.log("%s", new Error().stack);
throw 'NumUtil.integer.pp: num is not a number!';
}
if (isNaN(num))
throw 'NumUtil.integer.pp: num is NaN!';
if (num > 1e15)
return num;
if (num < 0)
throw 'Negative num!';
num = Math.round(num);
var group = num % 1000;
var integ = Math.floor(num / 1000);
if (integ === 0) {
return group;
}
num = NumUtil.align3(group);
while (true) {
group = integ % 1000;
integ = Math.floor(integ / 1000);
if (integ === 0)
return group + " " + num;
num = NumUtil.align3(group) + " " + num;
}
return num;
}
NumUtil.currency = {};
/** Round to coins and group by 3 digits. */
NumUtil.currency.pp = function(amount) {
if (typeof(amount) !== "number")
throw 'NumUtil.currency.pp: amount is not a number!';
if (isNaN(amount))
throw 'NumUtil.currency.pp: amount is NaN!';
if (amount > 1e15)
return amount;
if (amount < 0)
throw 'Negative amount!';
if (amount < 1e-2)
return 0;
var v = Math.round(amount*100);
var integ = Math.floor(v / 100);
var frac = NumUtil.align2(v % 100);
var group = integ % 1000;
integ = Math.floor(integ / 1000);
if (integ === 0) {
return group + "." + frac;
}
amount = NumUtil.align3(group);
while (true) {
group = integ % 1000;
integ = Math.floor(integ / 1000);
if (integ === 0)
return group + " " + amount + "." + frac;
amount = NumUtil.align3(group) + " " + amount;
}
return amount;
}
I think what you want is f.nettotal.value = "$" + showValue.toFixed(2);
I like the shortest answer by VisionN except when I need to modify it for a number without decimal point ($123 instead of $123.00) it does not work, so instead of quick copy/paste I need to decipher arcane syntax of the JavaScript regex.
Here is the original solution
n.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
I'll make it a bit longer:
var re = /\d(?=(\d{3})+\.)/g;
var subst = '$&,';
n.toFixed(2).replace(re, subst);
Re
part here (search part in string replace) means
\d
)?=
...) (lookahead)(
...)+
\d{3}
)\.
)g
)Subst
part here means
$&
) followed by a comma.As we use string.replace
all other text in the string remains the same and only found digits (those that are followed by 3,6,9,etc other digits) get an additional comma.
So in a number 1234567.89 digits 1 and 4 meet the condition (1234567.89) and are replaced with "1," and "4," resulting in 1,234,567.89.
If we don't need the decimal point in dollar amount at all (i.e. $123 instead of $123.00), we may change the regex like this:
var re2 = /\d(?=(\d{3})+$)/g;
It relies on the end of line ($
) instead of a dot (\.
) and the final expression will be (notice also toFixed(0)
):
n.toFixed(0).replace(/\d(?=(\d{3})+$)/g, '$&,');
This expression will give
1234567.89 -> 1,234,567
Also instead of end of line ($
) in the regex above you may opt for a word boundary as well (\b
).
My apology in advance if I misinterpreted any part of regex handling.
The main part is inserting the thousand-separators, that could be done like this:
<script type="text/javascript">
function ins1000Sep(val){
val = val.split(".");
val[0] = val[0].split("").reverse().join("");
val[0] = val[0].replace(/(\d{3})/g,"$1,");
val[0] = val[0].split("").reverse().join("");
val[0] = val[0].indexOf(",")==0?val[0].substring(1):val[0];
return val.join(".");
}
function rem1000Sep(val){
return val.replace(/,/g,"");
}
function formatNum(val){
val = Math.round(val*100)/100;
val = (""+val).indexOf(".")>-1 ? val + "00" : val + ".00";
var dec = val.indexOf(".");
return dec == val.length-3 || dec == 0 ? val : val.substring(0,dec+3);
}
</script>
<button onclick="alert(ins1000Sep(formatNum(12313231)));">
There are already some great answers here. Here's another attempt, just for fun:
function formatDollar(num) {
var p = num.toFixed(2).split(".");
return "$" + p[0].split("").reverse().reduce(function(acc, num, i, orig) {
return num=="-" ? acc : num + (i && !(i % 3) ? "," : "") + acc;
}, "") + "." + p[1];
}
And some tests:
formatDollar(45664544.23423) // "$45,664,544.23"
formatDollar(45) // "$45.00"
formatDollar(123) // "$123.00"
formatDollar(7824) // "$7,824.00"
formatDollar(1) // "$1.00"
Edited: now it will handle negative numbers as well
Patrick Desjardins (ex Daok)'s example worked well for me. I ported over to coffeescript if anyone is interested.
Number.prototype.toMoney = (decimals = 2, decimal_separator = ".", thousands_separator = ",") ->
n = this
c = if isNaN(decimals) then 2 else Math.abs decimals
sign = if n < 0 then "-" else ""
i = parseInt(n = Math.abs(n).toFixed(c)) + ''
j = if (j = i.length) > 3 then j % 3 else 0
x = if j then i.substr(0, j) + thousands_separator else ''
y = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_separator)
z = if c then decimal_separator + Math.abs(n - i).toFixed(c).slice(2) else ''
sign + x + y + z
Source: Stackoverflow.com