I have decided to completely rewrite example I did in 2009. Please check diff if interested in older version. In order to achieve functionality like previous answer, I have extracted a part of the Money
library I am working on.
I also don't remember why I have recreated toFixed
last time as that method was already present. This time it is not included.
Instead of messing with String
and Number
objects in javascript, like last time, I am creating new, Money
, object.
(function() {
window.Money = (function() {
Money.prototype.amount = 0.0;
Money.prototype.fraction_count = 2;
Money.prototype.fraction_separator = ",";
Money.prototype.separate_thousands = true;
Money.prototype.symbol = "€";
Money.prototype.symbol_position = "front";
Money.prototype.symbol_spacing = false;
Money.prototype.thousands_separator = ".";
function Money(amount, options) {
var o;
if (options == null) {
options = {};
}
for (o in options) {
this[o] = options[o];
}
amount = parseFloat(amount);
if (!isNaN(amount)) {
this.amount = amount;
}
this.format();
}
Money.prototype.format = function() {
this.string_amount = this.amount.toFixed(this.fraction_count);
if (this.separate_thousands) {
this.string_amount = this.separateThousands();
}
return this.string = this.addSymbol();
};
Money.prototype.separateThousands = function() {
var after_dot, before_dot, pattern, _ref;
_ref = this.string_amount.split("."), before_dot = _ref[0], after_dot = _ref[1];
pattern = /(-?d+)(d{3})/;
while (pattern.test(before_dot)) {
before_dot = before_dot.replace(pattern, "$1" + this.thousands_separator + "$2");
}
return [before_dot, after_dot].join(this.fraction_separator);
};
Money.prototype.addSymbol = function() {
var string;
string = [this.string_amount];
string.splice((this.symbol_position === "front" ? 0 : 1), 0, this.symbol);
return string.join(this.symbol_spacing ? " " : "");
};
return Money;
})();
Now, I do need to modify Number
and/or String
objects slightly and add toMoney
method.
Number.prototype.toMoney = function(options) {
return new Money(this, options);
};
String.prototype.toMoney = function(options) {
return new Money(this, options);
};
So, finally, we can convert String
and/or Number
to Money
and write it out as String
again.
x = "1234567890.0987654321".toMoney();
y = 1234567890.0987654321.toMoney({fraction_count: 5, symbol: "$", symbol_position: "back"});
console.log(x);
// Money {amount: 1234567890.0987654, string_amount: "1.234.567.890,10", string: "€1.234.567.890,10"}
console.log(x.string)
// €1.234.567.890,10
console.log(y);
// Money {fraction_count: 5, symbol: "$", symbol_position: "back", amount: 1234567890.0987654, string_amount: "1.234.567.890,09877"…}
console.log(y.string)
// 1.234.567.890,09877$
I think this solution is much better than the last one I wrote. For working example check jsFiddle.