JavaScript: Outputting a Number in Traditional Currency Format

The requirements I will describe in this article are to have JavaScript format user-input numbers as traditional currency. This means to show two decimal places (with or without automatic rounding), commas as thousands separators, and with or without a preceding currency symbol like:

$ 12,345.67

or without the currency sign as:

12,345.67

There are two ways of getting the currency formatting you need. You can do this by setting the style and the options of the JavaScript toLocalString function.

Treating the Number as Currency:

The first way of automatically getting rounded currency formatted numbers is as follows:

controlToCheck.value = Number(enteredNumber).toLocaleString('en-US', { style: 'currency', currency: 'USD' });

This will give you a rounded result that looks like this:

$#,###.##

You can set the locale to anything you like and JavaScript will add the appropriate currency symbol.

The down side here is that you get default rounding and cannot specify how many digits to show. Also, you get the currency symbol, which is not always desirable.

Using the Decimal Style with Default Rounding:

The Decimal style gives you a lot more control over the formatting of the number you are showing.

By default the toLocaleString function shows no decimals if none were provided by the user… it will just show a whole number… or just a single decimal if one place was provided. This makes for some messy output.

So what you need to do is to set two options: the maximumFractionDigits and the minimumFractionDigits. When you set both of these to 2, then the toLocaleString function will always show two decimal places (but will round user entered data if they have entered more than two decimal places).

To explain in more detail: the maximumFractionDigits will set how many decimal places to show (very important!), and the minimumFractionDigits will force your JavaScript to put in as many zeros as necessary to fill in the maximumFractionDigits. These two options work hand in hand.

Summing up the maximumFractionDigits option:

If you were to only set the maximumFractionDigits, then the JavaScript would accept user input decimals up to the maximum specified. However anything less and the JavaScript would only show that number of decimals, so if the user entered 1.2 then instead of 1.20, the JavaScript would show exactly 1.2

Summing up the minimumFractionDigits option:

Likewise if you only set the minimumFractionDigits, then you won’t see quite what you want. If the user enters more decimal places than they should, the JavaScript will then show you a truncated decimal result of the minimumFractionDigits plus 1. So, if the user entered 1.2334 then instead of showing 1.23, the JavaScript would show 1.233

So as you can see, it is important to set both the maximumFractionDigits and the minimumFractionDigits when you are outputting money values.

Here is an example of how to output rounded currency formatted numbers using the decimal option with the toLocaleString function:

var outNumber = (Number(enteredNumber) ).toLocaleString('en-US', { style: 'decimal', maximumFractionDigits : 2, minimumFractionDigits : 2 });

This behaves exactly like the currency option, but the decimal option comes with the benefit that it does not include the currency symbol as output, and that you can control exactly the number of decimal places that you want to show.

Micromanaging the Handling of the Number as a Decimal:

Sometimes it pays to micromanage your functions. It’s likely that you don’t really want or need some of the non-overridable options that the currency option of toLocalString offers. Also, you may not like the default rounding included with setting both the maximumFractionDigits and the minimumFractionDigits with a decimal.

In that case, you will need to manually handle truncating the output that gets shown to the user. In short, you can do this by using a decimal and then setting the the maximumFractionDigits and the minimumFractionDigits to a larger decimal value than you need. At that point you will have a string result that you can use a substring function on the number to truncate it to your desired length of two decimal places.

Mind you, this is very situational, and it is likely that most of what you need will be covered either by the currency option, or by setting a minimum and maximum fraction value.

Here in several lines of code is what your code might look like if you use the decimal option of toLocalString:

var outNumber = (Number(enteredNumber) ).toLocaleString('en-US', { style: 'decimal', maximumFractionDigits : 8, minimumFractionDigits : 8 });
outNumber = outNumber.substring(0,(outNumber.indexOf('.') + 3));
controlToCheck.value = outNumber;

The obvious added bonus of getting control over the decimal places is that you can show however many you want without getting rounded results. I really do wonder why there is no option to ignore rounding by default.

In the case of the code above, the substring ranges from 0 to the character instance of the period decimal separator plus the two following decimal places. Programmatically, this reads as:

outNumber.substring(0,(outNumber.indexOf('.') + 3));

The plus three part means to include the . decimal separator and the two following decimal places, and there you go: an unrounded result to the number of decimal places that you need.

The toLocalString decimal style gives you a lot more control over the format of your number than the currency style does.

In Summary:

I hope the information here will be of some use. Let me know if you know of any other ways to accomplish number formatting tricks in JavaScript.

If you are looking for more information on the options that you can use with teh toLocaleString function, have a look at this reference at Developer.Mozilla.org

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString

Example Code to Test:

Below is an example page that you can test the different types of number formatting out on. Just uncomment the block that you’d like to try out (and obviously comment out the block that you don’t want to test):

<!DOCTYPE html>
<html>
<head runat="server">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

<title>Test Page</title>
<script>
function toFinalNumberFormat(controlToCheck){
var enteredNumber = '' + controlToCheck.value;
enteredNumber = enteredNumber.replace(/[^0-9\.]+/g, ''); // remove any non-numeric, non-period character

// ******** Dollar Sign preceeding rounded, two decimal places number ********
// controlToCheck.value = Number(enteredNumber).toLocaleString('en-US', { style: 'currency', currency: 'USD' });

// ******** Non- Rounded, truncated Two Decimal Digits ********
// var outNumber = (Number(enteredNumber) ).toLocaleString('en-US', { style: 'decimal', maximumFractionDigits : 8, minimumFractionDigits : 8 });
// outNumber = outNumber.substring(0,(outNumber.indexOf('.') + 3));

// ******** Rounded Decimal Range ********
var outNumber = (Number(enteredNumber) ).toLocaleString('en-US', { style: 'decimal', maximumFractionDigits : 2, minimumFractionDigits : 2 });
controlToCheck.value = outNumber;
// Number(enteredNumber).toLocaleString('en'); // enteredNumber.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
}
</script>
</head>
<body>
<table>
<!-- Row #1: Enter some Numeric Text Here -->
<tr>
<td>Enter your Number here </td><td>&nbsp;</td>
<td class="input-group"><i class="input-group-addon glyphicon glyphicon-usd"></i>
<input type="text" id="txtExampleBoxOne" class="form-control" onBlur="toFinalNumberFormat(this);" placeholder="$#,###.00" ></td>
</tr>

<!-- Row #2: Add some More Numeric Text -->
<tr>
<td>Enter another number </td><td>&nbsp;</td>
<td class="input-group"><i class="input-group-addon glyphicon glyphicon-usd"></i>
<input type="text" id="txtExampleBoxTwo" class="form-control" onBlur="toFinalNumberFormat(this);" placeholder="$#,###.00" ></td>
</tr>
</table>
</body>
</html>
Advertisements

2 thoughts on “JavaScript: Outputting a Number in Traditional Currency Format

  1. One of the issues with toLocaleString() is simply that it isn’t supported in all browsers. I currently prefer currencyFormatter.js (https://osrec.github.io/currencyFormatter.js/) as it works on all browsers and is pretty light-weight. It’ll also add the currency symbols for you, and can format according to a specified locale:

    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 €

    1. Thanks for the info about currencyFormatter.js, it seems very useful. I think the only browser that doesn’t support the toLocaleString() function is Opera. I wonder why Opera specifically hasn’t included support for it yet. Anyhow, thanks again for the link to the currencyFormatter.js library, have a great day!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s