in Code

Format and un-format money/currency in JavaScript

Here’s a couple of simple JavaScript money-formattin’ snippets I use all the time where currencies are handled.

The code in this post has been expanded into accounting.js, a tiny JS library with some handy methods for number, money and currency formatting. Check it out!

Also: need to do real-time currency conversion in your apps and sites? Take a look at the Open Exchange Rates API!

The first is a function to format money/currency in JavaScript, turning an integer or float into a formatted string (with customisable decimal precision, currency symbol, decimal- and thousands-separators).

The second is a regular expression that removes currency formatting, so that parseInt / parseFloat can be used to extract the value from a currency-formatted string.

JavaScript Money Format

This extends the native Number object, so that all new numbers (integers/floats) can have the moneyformat() method called on them. If you prefer not to extend JavaScript’s native Number object for any reason, this also works fine as a standalone function or a library method (examples below.)

// Extend the default Number object with a formatMoney() method:
// usage: someVar.formatMoney(decimalPlaces, symbol, thousandsSeparator, decimalSeparator)
// defaults: (2, "$", ",", ".")
Number.prototype.formatMoney = function(places, symbol, thousand, decimal) {
	places = !isNaN(places = Math.abs(places)) ? places : 2;
	symbol = symbol !== undefined ? symbol : "$";
	thousand = thousand || ",";
	decimal = decimal || ".";
	var number = this, 
	    negative = number < 0 ? "-" : "",
	    i = parseInt(number = Math.abs(+number || 0).toFixed(places), 10) + "",
	    j = (j = i.length) > 3 ? j % 3 : 0;
	return symbol + negative + (j ? i.substr(0, j) + thousand : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousand) + (places ? decimal + Math.abs(number - i).toFixed(places).slice(2) : "");
};

NB: minified version below.

Some JS currency-formatting examples:

// Default usage and custom precision/symbol :
var revenue = 12345678;
console.log(revenue.formatMoney()); // $12,345,678.00
console.log(revenue.formatMoney(0, "HK$ ")); // HK$ 12,345,678

// European formatting:
var price = 4999.99;
console.log(price.formatMoney(2, "€", ".", ",")); // €4.999,99

// It works for negative values, too:
console.log( (-500000).formatMoney(0, "£ ") ); // £ -500,000

Currency to number – removing money formatting:

Say you have a currency-formatted string, eg. "HK$ -100,000.50" and you want to get the value from that, removing all currency formatting and thousand-separators. Default methods won’t get you very far: parseInt and parseFloat both return NaN (“not a number”, as the string had non-numeric characters in it.)

No problemo. A simple regex will take care of this:

var price = (12345.99).formatMoney(); // "$12,345.99"

// Remove non-numeric chars (except decimal point/minus sign):
priceVal = parseFloat(price.replace(/[^0-9-.]/g, '')); // 12345.99

NB: This only works where the decimal separator is a point (.) – if the separator is a comma (,), put a comma in the regex instead of a point, eg: /[^0-9-,]/g

Hope somebody finds this useful!

Non-Number.prototype version:

// To set it up as a global function:
function formatMoney(number, places, symbol, thousand, decimal) {
	number = number || 0;
	places = !isNaN(places = Math.abs(places)) ? places : 2;
	symbol = symbol !== undefined ? symbol : "$";
	thousand = thousand || ",";
	decimal = decimal || ".";
	var negative = number < 0 ? "-" : "",
	    i = parseInt(number = Math.abs(+number || 0).toFixed(places), 10) + "",
	    j = (j = i.length) > 3 ? j % 3 : 0;
	return symbol + negative + (j ? i.substr(0, j) + thousand : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousand) + (places ? decimal + Math.abs(number - i).toFixed(places).slice(2) : "");
}

// To create it as a library method:
myLibrary.formatMoney = function(number, places, symbol, thousand, decimal) {
	/* as above */
}

// Example usage:
formatMoney(54321); // $54,321
myLibrary.formatMoney(12345, 0, "£ "); // £ 12,345

Minified version of prototype method

Number.prototype.formatMoney=function(d,g,h,a){d=!isNaN(d=Math.abs(d))?d:2;g=g!==undefined?g:"$";h=h||",";a=a||".";var f=this,c=f3?b%3:0;return g+c+(b?e.substr(0,b)+h:"")+e.substr(b).replace(/(\d{3})(?=\d)/g,"$1"+h)+(d?a+Math.abs(f-e).toFixed(d).slice(2):"");};

Have any improvements, or spot any bugs? Comments appreciated!

Write a Comment

Comment

13 Comments

  1. Great snippets that are helping me a bunch! Thanks.

    Quick question from a javascript beginner:
    Why are you using once the following:
    symbol = symbol !== undefined ? symbol : "$";
    and once:
    thousand = thousand || ",";

    Is there any significant difference between the two?

    • Hey! Yeah that’s an interesting one.

      symbol = symbol !== undefined ? symbol : "$";

      This one says: If symbol is anything except undefined, use it; if not, use the default of "$". The !== check is strict and checks the variable type (which means that symbol can be an empty string, "", but needs to be explicitly defined as such.)

      thousand = thousand || ",";

      This one says: Use thousand if it’s truthy, or anything that coerces to a boolean true (not falsey, which would include null, undefined, "" and 0) – otherwise, use ",". Logically this makes sure that thousands are always separated, otherwise there’d be no sense using this method, but you can separate them with space or point (" " or ".")

      Check out this fantastic primer on truthy and falsey values if you’re interested in how the mechanics work.

      Also – check out accounting.js which is more up-to-date and easy to use!

  2. Looks like you have missed out the middle bit of your minified prototype. should be (this works anyway):

    Number.prototype.formatMoney = function (d, g, h, a) { d = !isNaN(d = Math.abs(d)) ? d : 2; g = g !== undefined ? g : “$”; h = h || “,”; a = a || “.”; var f = this, c = f 3 ? j % 3 : 0; return g + c + (b ? e.substr(0, b) + h : “”) + e.substr(b).replace(/(\d{3})(?=\d)/g, “$1” + h) + (d ? a + Math.abs(f – e).toFixed(d).slice(2) : “”); };

  3. ahhhh… the less than is the issue in your snippet and my comment…

    Number.prototype.formatMoney = function (d, g, h, a) { d = !isNaN(d = Math.abs(d)) ? d : 2; g = g !== undefined ? g : "$"; h = h || ","; a = a || "."; var f = this, c = f < 0 ? "-" : "", e = parseInt(f = Math.abs( f || 0).toFixed(d), 10) "", b = (b = e.length) > 3 ? j % 3 : 0; return g c (b ? e.substr(0, b) h : "") e.substr(b).replace(/(\d{3})(?=\d)/g, "$1" h) (d ? a Math.abs(f – e).toFixed(d).slice(2) : ""); };

  4. On your minified prototype method version, which I tested in the console of Google Chrome, it emits the error “Reference Error: f3 not found.” Would be awesome if it worked, however.

  5. can you tell me if this has the capability as well of extracting only the symbol (in plaintext or as a symbol ie GBP or the actual symbol) as well as whether its at the beginning or end of the string? If so please advise how, I didn’t see that capability here.

    Thanks in advance!

  6. $(function () {
    $(“#paraId”).on(“change”, function (e) {

    var num = $(‘#paraId’).val();
    num = num.toString().replace(/\$|\,/g, ”);
    if (isNaN(num))
    num = “0”;
    sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10)
    cents = "0" + cents;
    for (var i = 0; i < Math.floor((num.length – (1 + i)) / 3) ; i++)
    num = num.substring(0, num.length – (4 * i + 3)) + '.' +
    num.substring(num.length – (4 * i + 3));
    document.getElementById("paraId").value = (((sign) ? '' : '-') + num + ',' + cents);

    });
    });

  7. Kudos to you man!!!
    Seldom one comes across such a work of art!!
    An artist you are indeed; I must say in more than one way!