Я предполагаю, что вердикт: я не могу программно однозначно идентифицировать компьютер, который посещает мой веб-сайт.
У меня есть следующий вопрос. Когда я использую машину, которая никогда не посещала мой веб-сайт онлайн-банкинга, меня спрашивают о дополнительной аутентификации. то, если я вернусь во второй раз на сайт онлайн-банкинга, я не получаю дополнительную аутентификацию. прочитав ответы на мой вопрос, я решил, что это должен быть куки-файл. поэтому я удалил все куки в IE и перешел на мой сайт онлайн-банкинга, полностью ожидая, что вас снова зададут вопросы аутентификации. к моему удивлению, я не спросил. разве это не приводит к тому, что банк верит, что банк делает какую-то маркировку для ПК, которая не включает в себя куки?
далее, после многоголоса сегодня я нашел следующую компанию, которая утверждает, что продает решение, которое однозначно идентифицирует машины, которые посетите веб-сайт. http://www.the41.com/products.asp .
Я ценю всю полезную информацию, если вы могли бы уточнить эту противоречивую информацию, которую я нашел, я был бы очень благодарен ей.
Вот лучший форматер js money, который я видел:
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) : "");
};
Он был переформатирован и заимствован здесь: https://stackoverflow.com/a/149099/751484
Вам нужно будет указать свой собственный обозначение валюты (вы использовали $ выше).
Назовите это так (хотя обратите внимание, что для args по умолчанию задано значение 2, запятая и точка, поэтому вам не нужно указывать аргументы, если вы предпочитаете):
var myMoney=3543.75873;
var formattedMoney = ' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
Numeral.js - библиотека js для простого форматирования чисел с помощью @adamwdraper
numeral(23456.789).format('[110],0.00'); // = "$23,456.79"
Я думаю, что вы хотите, чтобы f.nettotal.value = "$" + showValue.toFixed(2);
toLocaleString хорош, но не работает во всех браузерах. Я обычно использую currencyFormatter.js ( https://osrec.github.io/currencyFormatter.js/ ). Это довольно легкий и содержит все определения валюты и локали прямо из коробки. Это также хорошо для форматирования необычно отформатированных валют, таких как INR (который группирует числа в lakhs и crores и т. Д.). Также нет зависимостей!
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 €
Я использую библиотеку Глобализация (от Microsoft):
Это отличный проект для локализации чисел, валют и дат и их автоматического форматирования в соответствии с языком пользователя. ! ... и, несмотря на то, что это должно быть расширение jQuery, в настоящее время это 100% независимая библиотека. Я предлагаю всем вам попробовать! :)
Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
В кодовой базе YUI используется следующее форматирование:
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;
}
}
потребуется редактирование, поскольку библиотека YUI настраивается, например, замена oConfig.decimalSeparator на «.»
Мне нравится это просто:
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("");
}
Существует порт javascript для функции PHP «number_format».
Я нахожу это очень полезным, так как он прост в использовании и узнаваем для разработчиков PHP.
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;
}
(Блок комментариев из оригинала , включенный ниже для примеров и кредитов, причитающихся)
// 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'
accounting.js - это крошечная библиотека JavaScript для форматирования чисел, денег и валюты.
Вот быстрый способ использования регулярных выражений и замены.
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
} );
}
Более короткий метод (для вставки пробела, запятой или точки) с регулярным выражением?
Number.prototype.toCurrencyString=function(){
return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
}
n=12345678.9;
alert(n.toCurrencyString());
Patrick Desjardins 'ответ выглядит неплохо, но я предпочитаю свой простой javascript. Вот функция, которую я только что написал, чтобы взять число и вернуть его в формате валюты (без знака доллара)
// 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];
}
В javascript
var num = new Number(349);
document.write("$" + num.toFixed(2));
встроено исправление function
для . Основная часть вставляет разделители тысяч, что можно сделать так:
<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)));">
Поскольку каждая проблема заслуживает однострочного решения:
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; }, ' Это достаточно легко изменить для разных локалей, просто измените «$ 1» на «$ 1». а также '.' на ',' чтобы поменять местами, и. в цифрах, и символ валюты можно изменить, изменив «$» в конце.
Или, если у вас ES6, вы можете просто объявить функцию со значениями по умолчанию:
Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = ' Да, и она работает и для отрицательных чисел:
console.log((-6635.574).formatCurrency('.', ',', "\u20AC"))
-€6.635,57
console.log((-1066.507).formatCurrency())
-$1,066.51
И, конечно, вам не нужно иметь символ валюты
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
) { 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
Да, и она работает и для отрицательных чисел:
console.log((-6635.574).formatCurrency('.', ',', "\u20AC"))
-€6.635,57
console.log((-1066.507).formatCurrency())
-$1,066.51
И, конечно, вам не нужно иметь символ валюты
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
); }
Это достаточно легко изменить для разных локалей, просто измените «$ 1» на «$ 1». а также '.' на ',' чтобы поменять местами, и. в цифрах, и символ валюты можно изменить, изменив «$» в конце.
Или, если у вас ES6, вы можете просто объявить функцию со значениями по умолчанию:
Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = ' Да, и она работает и для отрицательных чисел:
console.log((-6635.574).formatCurrency('.', ',', "\u20AC"))
-€6.635,57
console.log((-1066.507).formatCurrency())
-$1,066.51
И, конечно, вам не нужно иметь символ валюты
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
) { 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
Да, и она работает и для отрицательных чисел:
console.log((-6635.574).formatCurrency('.', ',', "\u20AC"))
-€6.635,57
console.log((-1066.507).formatCurrency())
-$1,066.51
И, конечно, вам не нужно иметь символ валюты
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
Я предлагаю класс NumberFormat из API визуализации Google .
Вы можете сделать что-то вроде этого:
var formatter = new google.visualization.NumberFormat({
prefix: ' Надеюсь, это поможет.
,
pattern: '#,###,###.##'
});
formatter.formatValue(1000000); // $ 1,000,000
Надеюсь, это поможет.
Посмотрите на объект JavaScript Number и посмотрите, может ли он вам помочь.
toLocaleString()
отформатирует число с использованием разделителя тысяч, зависящего от местоположения. toFixed()
округляет число до определенного количества десятичных знаков. Чтобы использовать их одновременно, значение должно изменить свой тип обратно на число, потому что они оба выводят строку.
Пример:
Number(someNumber.toFixed(1)).toLocaleString()
Ниже приведен код Патрика Дежарденса (псевдоним Daok) с небольшим количеством добавленных комментариев и некоторыми незначительными изменениями:
/*
decimal_sep: character used as deciaml separtor, 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) : '');
}
и вот некоторые тесты:
//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));
Незначительные изменения:
немного сдвинули Math.abs(decimals)
, чтобы сделать это только тогда, когда нет NaN
.
decimal_sep
больше не может быть пустой строкой (НЕОБХОДИМО использовать какой-то десятичный разделитель)
мы используем typeof thousands_sep === 'undefined'
, как предложено в Как Лучше всего определить, не был ли аргумент передан в функцию JavaScript
(+n || 0)
не требуется, поскольку this
является объектом Number
Не видел этого. Это довольно кратко и легко понять.
function moneyFormat(price, sign = '
Вот версия с большим количеством опций в конечном выводе, позволяющая форматировать разные валюты в разных форматах местности.
// higher order function that takes options then a price and will return the formatted price
const makeMoneyFormatter = ({
sign = '
Вот версия с большим количеством опций в конечном выводе, позволяющая форматировать разные валюты в разных форматах местности.
// higher order function that takes options then a price and will return the formatted price
const makeMoneyFormatter = ({
sign = '
Это может быть немного поздно, но вот метод, который я только что разработал для коллеги, чтобы добавить функцию .toCurrencyString()
с учетом локали ко всем числам. Интернализация предназначена только для группировки чисел, а НЕ для знака валюты - если вы выводите доллары, используйте "$"
в том виде, как он поставляется, потому что $123 4567
в Японии или Китае такое же количество долларов, как $1,234,567
здесь в США. , Если вы выводите евро / и т. Д., Измените знак валюты с "$"
.
Объявите об этом где-нибудь в вашей ГОЛОВКЕ или там, где это необходимо, непосредственно перед тем, как вам нужно будет это использовать:
Number.prototype.toCurrencyString = function(prefix, suffix) {
if (typeof prefix === 'undefined') { prefix = ' Тогда все готово! Используйте (number).toCurrencyString()
везде, где вам нужно вывести число в качестве валюты.
var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
; }
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;
}
Тогда все готово! Используйте (number).toCurrencyString()
везде, где вам нужно вывести число в качестве валюты.
var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
Я хочу внести свой вклад в это:
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;
}
Это позволяет вам преобразовывать числа в текстовое поле, где вы можете только ввести цифры (рассмотрите этот сценарий)
Это очистит текстовое поле, в котором могут быть только цифры, даже если вы вставляете строку с цифрами и буквами или любым символом
<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>
Как обычно, есть несколько способов сделать одно и то же, но я бы не стал использовать Number.prototype.toLocaleString
, поскольку он может возвращать разные значения в зависимости от настроек пользователя.
Я также не рекомендую расширять Number.prototype
- расширение прототипов собственных объектов является плохой практикой, так как это может вызвать конфликты с кодом других людей (например, библиотеки / фреймворки / плагины) и не может быть совместим с будущими реализациями / версиями JavaScript.
Я считаю, что регулярные выражения - лучший способ решения проблемы. Вот моя реализация:
/**
* 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);
}
}
отредактировано 30.08.2010: добавлена опция для установки количества десятичных цифр. отредактировано 23.08.2011: добавлена возможность установить количество десятичных цифр равным нулю.
Я нашел это из: accounting.js . Это очень просто и идеально подходит для моих нужд.
// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00
// European formatting (custom symbol and separators), can also use options object as second parameter:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99
// Negative values can be formatted nicely:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000
// Simple `format` string allows control of symbol position (%v = value, %s = symbol):
accounting.formatMoney(5318008, { symbol: "GBP", format: "%v %s" }); // 5,318,008.00 GBP
// Euro currency symbol to the right
accounting.formatMoney(5318008, {symbol: "€", precision: 2, thousand: ".", decimal : ",", format: "%v%s"}); // 1.008,00€
Вот некоторые решения, все из которых проходят тестовый набор, тестовый набор и тесты включены, если вы хотите скопировать и вставить для тестирования, попробуйте This Gist .
На основе https://stackoverflow.com/a/14428340/1877620 , но исправьте, если не существует десятичной точки.
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, '[110]amp;,');
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, ',[111]amp;');
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, '[112]amp;,')
.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));
}
Если нам нужен пользовательский разделитель тысяч или десятичный разделитель, используйте 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();
Пример Патрика Дежарденса (бывшего Даока) мне помог. Я портировал на coffeescript, если кому-то интересно.
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
Javascript имеет средство форматирования чисел (часть Интернационализации API).
// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
formatter.format(2500); /* $2,500.00 */
Используйте undefined
вместо первого аргумента (в примере 'en-US'
), чтобы использовать системный языковой стандарт (пользовательский языковой стандарт в случае, если код выполняется в браузере).
Последнее замечание, сравнивающее это со старым. toLocaleString
. Они оба предлагают по существу одинаковую функциональность. Однако toLocaleString в его более старых версиях (pre-Intl) фактически не поддерживает локали : он использует системную локаль. Поэтому убедитесь, что вы используете правильную версию ( MDN предлагает проверить наличие Intl
). Кроме того, производительность обоих одинакова для одного элемента , но если у вас много чисел для форматирования, использование Intl.NumberFormat
происходит в ~ 70 раз быстрее. Вот как использовать toLocaleString
:
(2500).toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
}); /* $2,500.00 */
(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '[110]amp;,'); // 12,345.67
Идея этого решения заключается в замене совпавших участков первым соответствием и запятой, т. Е. '[114]amp;,'
. Сопоставление выполняется с использованием подхода , ориентированного на будущее . Вы можете прочитать выражение как «соответствует номеру, если за ним следует последовательность из трех наборов чисел (один или несколько) и точка» .
ИСПЫТАНИЯ:
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"
ДЕМО: http://jsfiddle.net/hAfMM/9571/
< hr> Вы также можете расширить прототип объекта Number
, чтобы добавить дополнительную поддержку любого количества десятичных знаков [0 .. n]
и размера групп чисел [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 ? '\\.' : ' ДЕМО / ИСПЫТАНИЯ: http://jsfiddle.net/hAfMM/435/
<час> Супер расширенное короткое решение
В этой супер расширенной версии вы можете установить различные типы разделителей:
/**
* 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' : ' DEMO / TESTS: http : //jsfiddle.net/hAfMM/612/ [+1124]) + ')',
num = this.toFixed(Math.max(0, ~~n));
return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '[113]amp;' + (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/ [+1124]) + ')';
return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '[112]amp;,');
};
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"
ДЕМО / ИСПЫТАНИЯ: http://jsfiddle.net/hAfMM/435/
<час>В этой супер расширенной версии вы можете установить различные типы разделителей:
/**
* 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' : ' DEMO / TESTS: http : //jsfiddle.net/hAfMM/612/ [+1124]) + ')',
num = this.toFixed(Math.max(0, ~~n));
return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '[113]amp;' + (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/ [+1124]
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;
}
От WillMaster.
Мы можем также использовать , числа numeraljs
могут быть отформатированы для сходства с валютой, процентами, времена или даже простые числа с десятичными разрядами, тысячами и сокращениями. И можно всегда создавать пользовательский формат.
var string = numeral(1000).format('0,0');
// '1,000'