I have a text box that will have a currency string in it that I then need to convert that string to a double to perform some operations on it.
"$1,100.00" → 1100.00
This needs to occur all client side. I have no choice but to leave the currency string as a currency string as input but need to cast/convert it to a double to allow some mathematical operations.
Remove all non dot / digits:
var currency = "-$4,400.50";
var number = Number(currency.replace(/[^0-9.-]+/g,""));
accounting.js is the way to go. I used it at a project and had very good experience using it.
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99
accounting.unformat("€ 1.000.000,00", ","); // 1000000
You can find it at GitHub
Use a regex to remove the formating (dollar and comma), and use parseFloat to convert the string to a floating point number.`
var currency = "$1,100.00";
currency.replace(/[$,]+/g,"");
var result = parseFloat(currency) + .05;
I know this is an old question but wanted to give an additional option.
The jQuery Globalize gives the ability to parse a culture specific format to a float.
https://github.com/jquery/globalize
Given a string "$13,042.00", and Globalize set to en-US:
Globalize.culture("en-US");
You can parse the float value out like so:
var result = Globalize.parseFloat(Globalize.format("$13,042.00", "c"));
This will give you:
13042.00
And allows you to work with other cultures.
I know this is an old question, but CMS's answer seems to have one tiny little flaw: it only works if currency format uses "." as decimal separator.
For example, if you need to work with russian rubles, the string will look like this:
"1 000,00 rub."
My solution is far less elegant than CMS's, but it should do the trick.
var currency = "1 000,00 rub."; //it works for US-style currency strings as well
var cur_re = /\D*(\d+|\d.*?\d)(?:\D+(\d{2}))?\D*$/;
var parts = cur_re.exec(currency);
var number = parseFloat(parts[1].replace(/\D/,'')+'.'+(parts[2]?parts[2]:'00'));
console.log(number.toFixed(2));
Assumptions:
currency value uses decimal notation
there are no digits in the string that are not a part of the currency value
currency value contains either 0 or 2 digits in its fractional part *
The regexp can even handle something like "1,999 dollars and 99 cents", though it isn't an intended feature and it should not be relied upon.
Hope this will help someone.
This example run ok
var currency = "$1,123,456.00";
var number = Number(currency.replace(/[^0-9\.]+/g,""));
console.log(number);
For anyone looking for a solution in 2021 you can use Currency.js.
After much research this was the most reliable method I found for production, I didn't have any issues so far. In addition it's very active on Github.
currency(123); // 123.00
currency(1.23); // 1.23
currency("1.23") // 1.23
currency("$12.30") // 12.30
var value = currency("123.45");
currency(value); // 123.45
typescript
import currency from "currency.js";
currency("$12.30").value; // 12.30
This is my function. Works with all currencies..
function toFloat(num) {
dotPos = num.indexOf('.');
commaPos = num.indexOf(',');
if (dotPos < 0)
dotPos = 0;
if (commaPos < 0)
commaPos = 0;
if ((dotPos > commaPos) && dotPos)
sep = dotPos;
else {
if ((commaPos > dotPos) && commaPos)
sep = commaPos;
else
sep = false;
}
if (sep == false)
return parseFloat(num.replace(/[^\d]/g, ""));
return parseFloat(
num.substr(0, sep).replace(/[^\d]/g, "") + '.' +
num.substr(sep+1, num.length).replace(/[^0-9]/, "")
);
}
Usage : toFloat("$1,100.00") or toFloat("1,100.00$")
// "10.000.500,61 TL" price_to_number => 10000500.61
// "10000500.62" number_to_price => 10.000.500,62
JS FIDDLE: https://jsfiddle.net/Limitlessisa/oxhgd32c/
var price="10.000.500,61 TL";
document.getElementById("demo1").innerHTML = price_to_number(price);
var numberPrice="10000500.62";
document.getElementById("demo2").innerHTML = number_to_price(numberPrice);
function price_to_number(v){
if(!v){return 0;}
v=v.split('.').join('');
v=v.split(',').join('.');
return Number(v.replace(/[^0-9.]/g, ""));
}
function number_to_price(v){
if(v==0){return '0,00';}
v=parseFloat(v);
v=v.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
v=v.split('.').join('*').split(',').join('.').split('*').join(',');
return v;
}
You can try this
var str = "$1,112.12";
str = str.replace(",", "");
str = str.replace("$", "");
console.log(parseFloat(str));
let thousands_seps = '.';
let decimal_sep = ',';
let sanitizeValue = "R$ 2.530,55".replace(thousands_seps,'')
.replace(decimal_sep,'.')
.replace(/[^0-9.-]+/, '');
// Converting to float
// Result 2530.55
let stringToFloat = parseFloat(sanitizeValue);
// Formatting for currency: "R$ 2.530,55"
// BRL in this case
let floatTocurrency = Number(stringToFloat).toLocaleString('pt-BR', {style: 'currency', currency: 'BRL'});
// Output
console.log(stringToFloat, floatTocurrency);
I know you've found a solution to your question, I just wanted to recommend that maybe you look at the following more extensive jQuery plugin for International Number Formats:
International Number Formatter
How about simply
Number(currency.replace(/[^0-9-]+/g,""))/100;
Works with all currencies and locales. replaces all non-numeric chars (you can have €50.000,00 or $50,000.00) input must have 2 decimal places
jQuery.preferCulture("en-IN");
var price = jQuery.format(39.00, "c");
output is: Rs. 39.00
use jquery.glob.js,
jQuery.glob.all.js
Here's a simple function -
function getNumberFromCurrency(currency) {
return Number(currency.replace(/[$,]/g,''))
}
console.log(getNumberFromCurrency('$1,000,000.99')) // 1000000.99
For currencies that use the ',' separator mentioned by Quethzel Diaz
Currency is in Brazilian.
var currency_br = "R$ 1.343,45";
currency_br = currency_br.replace('.', "").replace(',', '.');
var number_formated = Number(currency_br.replace(/[^0-9.-]+/g,""));
var parseCurrency = function (e) {
if (typeof (e) === 'number') return e;
if (typeof (e) === 'string') {
var str = e.trim();
var value = Number(e.replace(/[^0-9.-]+/g, ""));
return str.startsWith('(') && str.endsWith(')') ? -value: value;
}
return e;
}
This worked for me and covers most edge cases :)
function toFloat(num) {
const cleanStr = String(num).replace(/[^0-9.,]/g, '');
let dotPos = cleanStr.indexOf('.');
let commaPos = cleanStr.indexOf(',');
if (dotPos < 0) dotPos = 0;
if (commaPos < 0) commaPos = 0;
const dotSplit = cleanStr.split('.');
const commaSplit = cleanStr.split(',');
const isDecimalDot = dotPos
&& (
(commaPos && dotPos > commaPos)
|| (!commaPos && dotSplit[dotSplit.length - 1].length === 2)
);
const isDecimalComma = commaPos
&& (
(dotPos && dotPos < commaPos)
|| (!dotPos && commaSplit[commaSplit.length - 1].length === 2)
);
let integerPart = cleanStr;
let decimalPart = '0';
if (isDecimalComma) {
integerPart = commaSplit[0];
decimalPart = commaSplit[1];
}
if (isDecimalDot) {
integerPart = dotSplit[0];
decimalPart = dotSplit[1];
}
return parseFloat(
`${integerPart.replace(/[^0-9]/g, '')}.${decimalPart.replace(/[^0-9]/g, '')}`,
);
}
toFloat('USD 1,500.00'); // 1500
toFloat('USD 1,500'); // 1500
toFloat('USD 500.00'); // 500
toFloat('USD 500'); // 500
toFloat('EUR 1.500,00'); // 1500
toFloat('EUR 1.500'); // 1500
toFloat('EUR 500,00'); // 500
toFloat('EUR 500'); // 500
Such a headache and so less consideration to other cultures for nothing...
here it is folks:
let floatPrice = parseFloat(price.replace(/(,|\.)([0-9]{3})/g,'$2').replace(/(,|\.)/,'.'));
as simple as that.
$ 150.00
Fr. 150.00
€ 689.00
I have tested for above three currency symbols .You can do it for others also.
var price = Fr. 150.00;
var priceFloat = price.replace(/[^\d\.]/g, '');
Above regular expression will remove everything that is not a digit or a period.So You can get the string without currency symbol but in case of " Fr. 150.00 " if you console for output then you will get price as
console.log('priceFloat : '+priceFloat);
output will be like priceFloat : .150.00
which is wrong so you check the index of "." then split that and get the proper result.
if (priceFloat.indexOf('.') == 0) {
priceFloat = parseFloat(priceFloat.split('.')[1]);
}else{
priceFloat = parseFloat(priceFloat);
}
function NumberConvertToDecimal (number) {
if (number == 0) {
return '0.00';
}
number = parseFloat(number);
number = number.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1");
number = number.split('.').join('*').split('*').join('.');
return number;
}
This function should work whichever the locale and currency settings :
function getNumPrice(price, decimalpoint) {
var p = price.split(decimalpoint);
for (var i=0;i<p.length;i++) p[i] = p[i].replace(/\D/g,'');
return p.join('.');
}
This assumes you know the decimal point character (in my case the locale is set from PHP, so I get it with <?php echo cms_function_to_get_decimal_point(); ?>).
You should be able to handle this using vanilla JS. The Internationalization API is part of JS core: ECMAScript Internationalization API
https://www.w3.org/International/wiki/JavaScriptInternationalization
This answer worked for me: How to format numbers as currency strings
I have this code in one vue method and I want to optimize it. I will get some information from a WP database and these informations contains also some text that I don't need.
I don't like the regex I've used, since I will need to create the data using template literal. The information passed to the method with the prodInfo variable looks like this 2,5kg meal or 500g cookie
Is there a better way to do the calculations and to get the needed information?
extractTotal(prodInfo, prodPrice, code){
let val = prodInfo.match(/[0-9]/g)
let multiplier
if( val.length > 2 ){
multiplier = `${val[0]}${val[1]}${val[2]}`
} else if( val.length === 1 ) {
multiplier = val[0]
} else {
multipier = `${val[0]}.${val[1]}`
}
if( multiplier === '500' ){
return (parseFloat(prodPrice) * this.q[code] / 2)
} else if( multiplier === '1' ) {
return (parseFloat(prodPrice) * this.q[code] * 1)
} else {
return (parseFloat(prodPrice) * this.q[code] * multiplier)
}
}
Use this regex: /[0-9]+\,?[0-9]*/g
Then you can convert the , chars to .
// Example
const input = '2,5kg meal 500g cookie'
const floats = input
.match(/[0-9]+\,?[0-9]*/g)
.map(a => parseFloat(
a.replace(',','.')
)
)
// floats => [2.5, 500]
I'm trying to make a text field so that if there's a number 153.254, that becomes 153.25. And if the field contains 154.2, an extra 0 is added to fill two spots after decimal; 154.20.
toFixed() works great but I don't want the number rounded. Also came across other solutions where if I'm typing in 1.40, then if I move the cursor back after 1, I can't type anything in unless I clear the field and start over.
Is there a simple jQuery way to limit two characters after a decimal, and then if there's only one character after the decimal, add a zero to fill the two character limit?
(The field may receive value from database that's why the second part is required)
Solution Update: For those interested, I put this together to achieve what I wanted (Thanks to answers below and also other questions here on stackoverflow)
$('.number').each(function(){
this.value = parseFloat(this.value).toFixed(3).slice(0, -1);
});
$('.number').keyup(function(){
if($(this).val().indexOf('.')!=-1){
if($(this).val().split(".")[1].length > 2){
if( isNaN( parseFloat( this.value ) ) ) return;
this.value = parseFloat(this.value).toFixed(3).slice(0, -1);
}
}
return this; //for chaining
});
you could do myNumber.toFixed(3).slice(0, -1)
try this:
var num = 153.2
function wacky_round(number, places) {
var h = number.toFixed(2);
var r = number.toFixed(4) * 100;
var r2 = Math.floor(r);
var r3 = r2 / 100;
var r4 = r3.toFixed(2);
var hDiff = number - h;
var r4Diff = number - r3;
var obj = {};
obj[hDiff] = h;
obj[r4Diff] = r4;
if (r4Diff < 0) {
return h;
}
if (hDiff < 0) {
return r4;
}
var ret = Math.min(hDiff, r4Diff);
return obj[ret];
}
alert(wacky_round(num, 2))
How about
function doStuff(num){
var n = Math.floor(num * 100) / 100,
s = n.toString();
// if it's one decimal place, add a trailing zero:
return s.split('.')[1].length === 1 ? (s + '0') : n;
}
console.log(doStuff(1.1), doStuff(1.111)); // 1.10, 1.11
http://jsfiddle.net/NYnS8/
I got everything almost where I want it. My only problem is that for some reason I can't get the bctf1 to add right. Say if bctf = 10, the result with the code would be 100.59 instead of 10.59. Say if bctf = 25, the result with the code would be $251.03 instead of 26.03.
// BUY TOTAL
<script type="text/javascript">
function buytot(){
var bctf = document.getElementById('buyctf').value;
if(bctf.charAt(0) == "0" || bctf.charAt(0) == "" || bctf.charAt(0) == " "){
bctf2 = "0.00";
} else {
pcbctf = bctf*.029;
pcplusc = pcbctf+.30;
bctf1 = bctf+pcplusc;
bctf2 = Math.round(bctf1*100)/100;
}
document.getElementById('buyctotal').innerHTML = bctf2;
}
</script>
Here's the HTML with JS -> http://jsfiddle.net/hhWDe/5/
Force a data type on this:
var bctf = parseFloat(document.getElementById('buyctf').value);
You need to convert the String values returned by the element value properties into numbers. Something like this:
var bctf = Number(document.getElementById('buyctf').value);
// OR
var bctf = parseFloat(document.getElementById('buyctf').value, 10);
Also, consider using the "toFixed" number method to get the ".00 decimal places for whole dollar amounts:
var oneDollar = 1;
oneDollar; // => 1
oneDollar.toFixed(2); // => "1.00"
You can add "+" to convert a value to an integer (or float).
It will take any string and convert it, if the string cannot be converted, it will return NaN:
So your script would look like the following:
var bcft = +document.getElementByID('buyctf').value;
Thank You all :) This is the working code. I add bctf0 = Number(document.getElementById('buyctf').value); after the else and everything worked fine.
// BUY TOTAL
function buytot(){
var bctf = document.getElementById('buyctf').value;
if(bctf.charAt(0) == "0" || bctf.charAt(0) == "" || bctf.charAt(0) == " "){ bctf2 = "0.00";
} else {
bctf0 = Number(document.getElementById('buyctf').value);
pcbctf = bctf0*.029;
pcplusc = pcbctf+.30;
bctf1 = bctf0+pcplusc;
bctf2 = Math.round(bctf1*100)/100;
}
document.getElementById('buyctotal').innerHTML = bctf2;
}