我想用JavaScript格式化价格。我想要一个函数,它将浮点作为参数,并返回如下格式的字符串:

"$ 2,500.00"

我该怎么做?


当前回答

请在下面的代码中找到我为支持国际化而开发的内容。

它将给定的数值格式化为特定于语言的格式。在给定的示例中,我使用了“en”,同时测试了“es”、“fr”和其他格式不同的国家。它不仅可以阻止用户键入字符,还可以格式化制表符上的值。

我已经为数字和十进制格式创建了组件。除此之外,我还创建了parseNumber(value,locale)和parseDecimal(value,locale)函数,这些函数将解析格式化数据以用于任何其他业务目的。所述函数将接受格式化数据并返回非格式化值。我在下面的共享代码中使用了jQuery验证器插件。

HTML格式:

<tr>
    <td>
        <label class="control-label">
            Number Field:
        </label>
        <div class="inner-addon right-addon">
            <input type="text" id="numberField"
                   name="numberField"
                   class="form-control"
                   autocomplete="off"
                   maxlength="17"
                   data-rule-required="true"
                   data-msg-required="Cannot be blank."
                   data-msg-maxlength="Exceeding the maximum limit of 13 digits. Example: 1234567890123"
                   data-rule-numberExceedsMaxLimit="en"
                   data-msg-numberExceedsMaxLimit="Exceeding the maximum limit of 13 digits. Example: 1234567890123"
                   onkeydown="return isNumber(event, 'en')"
                   onkeyup="return updateField(this)"
                   onblur="numberFormatter(this,
                               'en',
                               'Invalid character(s) found. Please enter valid characters.')">
        </div>
    </td>
</tr>

<tr>
    <td>
        <label class="control-label">
            Decimal Field:
        </label>
        <div class="inner-addon right-addon">
            <input type="text" id="decimalField"
                   name="decimalField"
                   class="form-control"
                   autocomplete="off"
                   maxlength="20"
                   data-rule-required="true"
                   data-msg-required="Cannot be blank."
                   data-msg-maxlength="Exceeding the maximum limit of 16 digits. Example: 1234567890123.00"
                   data-rule-decimalExceedsMaxLimit="en"
                   data-msg-decimalExceedsMaxLimit="Exceeding the maximum limit of 16 digits. Example: 1234567890123.00"
                   onkeydown="return isDecimal(event, 'en')"
                   onkeyup="return updateField(this)"
                   onblur="decimalFormatter(this,
                       'en',
                       'Invalid character(s) found. Please enter valid characters.')">
        </div>
    </td>
</tr>

JavaScript:

/*
 * @author: dinesh.lomte
 */
/* Holds the maximum limit of digits to be entered in number field. */
var numericMaxLimit = 13;
/* Holds the maximum limit of digits to be entered in decimal field. */
var decimalMaxLimit = 16;

/**
 *
 * @param {type} value
 * @param {type} locale
 * @returns {Boolean}
 */
parseDecimal = function(value, locale) {

    value = value.trim();
    if (isNull(value)) {
        return 0.00;
    }
    if (isNull(locale)) {
        return value;
    }
    if (getNumberFormat(locale)[0] === '.') {
        value = value.replace(/\./g, '');
    } else {
        value = value.replace(
                    new RegExp(getNumberFormat(locale)[0], 'g'), '');
    }
    if (getNumberFormat(locale)[1] === ',') {
        value = value.replace(
                    new RegExp(getNumberFormat(locale)[1], 'g'), '.');
    }
    return value;
};

/**
 *
 * @param {type} element
 * @param {type} locale
 * @param {type} nanMessage
 * @returns {Boolean}
 */
decimalFormatter = function (element, locale, nanMessage) {

    showErrorMessage(element.id, false, null);
    if (isNull(element.id) || isNull(element.value) || isNull(locale)) {
        return true;
    }
    var value = element.value.trim();
    value = value.replace(/\s/g, '');
    value = parseDecimal(value, locale);
    var numberFormatObj = new Intl.NumberFormat(locale,
            {   minimumFractionDigits: 2,
                maximumFractionDigits: 2
            }
    );
    if (numberFormatObj.format(value) === 'NaN') {
        showErrorMessage(element.id, true, nanMessage);
        setFocus(element.id);
        return false;
    }
    element.value = numberFormatObj.format(value);
    return true;
};

/**
 *
 * @param {type} element
 * @param {type} locale
 * @param {type} nanMessage
 * @returns {Boolean}
 */
numberFormatter = function (element, locale, nanMessage) {

    showErrorMessage(element.id, false, null);
    if (isNull(element.id) || isNull(element.value) || isNull(locale)) {
        return true;
    }
    var value = element.value.trim();
    var format = getNumberFormat(locale);
    if (hasDecimal(value, format[1])) {
        showErrorMessage(element.id, true, nanMessage);
        setFocus(element.id);
        return false;
    }
    value = value.replace(/\s/g, '');
    value = parseNumber(value, locale);
    var numberFormatObj = new Intl.NumberFormat(locale,
            {   minimumFractionDigits: 0,
                maximumFractionDigits: 0
            }
    );
    if (numberFormatObj.format(value) === 'NaN') {
        showErrorMessage(element.id, true, nanMessage);
        setFocus(element.id);
        return false;
    }
    element.value =
            numberFormatObj.format(value);
    return true;
};

/**
 *
 * @param {type} id
 * @param {type} flag
 * @param {type} message
 * @returns {undefined}
 */
showErrorMessage = function(id, flag, message) {

    if (flag) {
        // only add if not added
        if ($('#'+id).parent().next('.app-error-message').length === 0) {
            var errorTag = '<div class=\'app-error-message\'>' + message + '</div>';
            $('#'+id).parent().after(errorTag);
        }
    } else {
        // remove it
        $('#'+id).parent().next(".app-error-message").remove();
    }
};

/**
 *
 * @param {type} id
 * @returns
 */
setFocus = function(id) {

    id = id.trim();
    if (isNull(id)) {
        return;
    }
    setTimeout(function() {
        document.getElementById(id).focus();
    }, 10);
};

/**
 *
 * @param {type} value
 * @param {type} locale
 * @returns {Array}
 */
parseNumber = function(value, locale) {

    value = value.trim();
    if (isNull(value)) {
        return 0;
    }
    if (isNull(locale)) {
        return value;
    }
    if (getNumberFormat(locale)[0] === '.') {
        return value.replace(/\./g, '');
    }
    return value.replace(
        new RegExp(getNumberFormat(locale)[0], 'g'), '');
};

/**
 *
 * @param {type} locale
 * @returns {Array}
 */
getNumberFormat = function(locale) {

    var format = [];
    var numberFormatObj = new Intl.NumberFormat(locale,
            {   minimumFractionDigits: 2,
                maximumFractionDigits: 2
            }
    );
    var value = numberFormatObj.format('132617.07');
    format[0] = value.charAt(3);
    format[1] = value.charAt(7);
    return format;
};

/**
 *
 * @param {type} value
 * @param {type} fractionFormat
 * @returns {Boolean}
 */
hasDecimal = function(value, fractionFormat) {

    value = value.trim();
    if (isNull(value) || isNull(fractionFormat)) {
        return false;
    }
    if (value.indexOf(fractionFormat) >= 1) {
        return true;
    }
};

/**
 *
 * @param {type} event
 * @param {type} locale
 * @returns {Boolean}
 */
isNumber = function(event, locale) {

    var keyCode = event.which ? event.which : event.keyCode;
    // Validating if user has pressed shift character
    if (keyCode === 16) {
        return false;
    }
    if (isNumberKey(keyCode)) {
        return true;
    }
    var numberFormatter = [32, 110, 188, 190];
    if (keyCode === 32
            && isNull(getNumberFormat(locale)[0]) === isNull(getFormat(keyCode))) {
        return true;
    }
    if (numberFormatter.indexOf(keyCode) >= 0
            && getNumberFormat(locale)[0] === getFormat(keyCode)) {
        return true;
    }
    return false;
};

/**
 *
 * @param {type} event
 * @param {type} locale
 * @returns {Boolean}
 */
isDecimal = function(event, locale) {

    var keyCode = event.which ? event.which : event.keyCode;
    // Validating if user has pressed shift character
    if (keyCode === 16) {
        return false;
    }
    if (isNumberKey(keyCode)) {
        return true;
    }
    var numberFormatter = [32, 110, 188, 190];
    if (keyCode === 32
            && isNull(getNumberFormat(locale)[0]) === isNull(getFormat(keyCode))) {
        return true;
    }
    if (numberFormatter.indexOf(keyCode) >= 0
            && (getNumberFormat(locale)[0] === getFormat(keyCode)
                || getNumberFormat(locale)[1] === getFormat(keyCode))) {
        return true;
    }
    return false;
};

/**
 *
 * @param {type} keyCode
 * @returns {Boolean}
 */
isNumberKey = function(keyCode) {

    if ((keyCode >= 48 && keyCode <= 57) ||
        (keyCode >= 96 && keyCode <= 105)) {
        return true;
    }
    var keys = [8, 9, 13, 35, 36, 37, 39, 45, 46, 109, 144, 173, 189];
    if (keys.indexOf(keyCode) !== -1) {
        return true;
    }
    return false;
};

/**
 *
 * @param {type} keyCode
 * @returns {JSON@call;parse.numberFormatter.value|String}
 */
getFormat = function(keyCode) {

    var jsonString = '{"numberFormatter" : [{"key":"32", "value":" ", "description":"space"}, {"key":"188", "value":",", "description":"comma"}, {"key":"190", "value":".", "description":"dot"}, {"key":"110", "value":".", "description":"dot"}]}';
    var jsonObject = JSON.parse(jsonString);
    for (var key in jsonObject.numberFormatter) {
        if (jsonObject.numberFormatter.hasOwnProperty(key)
                && keyCode === parseInt(jsonObject.numberFormatter[key].key)) {
            return jsonObject.numberFormatter[key].value;
        }
    }
    return '';
};

/**
 *
 * @type String
 */
var jsonString = '{"shiftCharacterNumberMap" : [{"char":")", "number":"0"}, {"char":"!", "number":"1"}, {"char":"@", "number":"2"}, {"char":"#", "number":"3"}, {"char":"$", "number":"4"}, {"char":"%", "number":"5"}, {"char":"^", "number":"6"}, {"char":"&", "number":"7"}, {"char":"*", "number":"8"}, {"char":"(", "number":"9"}]}';

/**
 *
 * @param {type} value
 * @returns {JSON@call;parse.shiftCharacterNumberMap.number|String}
 */
getShiftCharSpecificNumber = function(value) {

    var jsonObject = JSON.parse(jsonString);
    for (var key in jsonObject.shiftCharacterNumberMap) {
        if (jsonObject.shiftCharacterNumberMap.hasOwnProperty(key)
                && value === jsonObject.shiftCharacterNumberMap[key].char) {
            return jsonObject.shiftCharacterNumberMap[key].number;
        }
    }
    return '';
};

/**
 *
 * @param {type} value
 * @returns {Boolean}
 */
isShiftSpecificChar = function(value) {

    var jsonObject = JSON.parse(jsonString);
    for (var key in jsonObject.shiftCharacterNumberMap) {
        if (jsonObject.shiftCharacterNumberMap.hasOwnProperty(key)
                && value === jsonObject.shiftCharacterNumberMap[key].char) {
            return true;
        }
    }
    return false;
};

/**
 *
 * @param {type} element
 * @returns {undefined}
 */
updateField = function(element) {

    var value = element.value;

    for (var index = 0; index < value.length; index++) {
        if (!isShiftSpecificChar(value.charAt(index))) {
            continue;
        }
        element.value = value.replace(
                value.charAt(index),
                getShiftCharSpecificNumber(value.charAt(index)));
    }
};

/**
 *
 * @param {type} value
 * @param {type} element
 * @param {type} params
 */
jQuery.validator.addMethod('numberExceedsMaxLimit', function(value, element, params) {

    value = parseInt(parseNumber(value, params));
    if (value.toString().length > numericMaxLimit) {
        showErrorMessage(element.id, false, null);
        setFocus(element.id);
        return false;
    }
    return true;
}, 'Exceeding the maximum limit of 13 digits. Example: 1234567890123.');

/**
 *
 * @param {type} value
 * @param {type} element
 * @param {type} params
 */
jQuery.validator.addMethod('decimalExceedsMaxLimit', function(value, element, params) {

    value = parseFloat(parseDecimal(value, params)).toFixed(2);
    if (value.toString().substring(
            0, value.toString().lastIndexOf('.')).length > numericMaxLimit
            || value.toString().length > decimalMaxLimit) {
        showErrorMessage(element.id, false, null);
        setFocus(element.id);
        return false;
    }
    return true;
}, 'Exceeding the maximum limit of 16 digits. Example: 1234567890123.00.');

/**
 * @param {type} id
 * @param {type} locale
 * @returns {boolean}
 */
isNumberExceedMaxLimit = function(id, locale) {

    var value = parseInt(parseNumber(
            document.getElementById(id).value, locale));
    if (value.toString().length > numericMaxLimit) {
        setFocus(id);
        return true;
    }
    return false;
};

/**
 * @param {type} id
 * @param {type} locale
 * @returns {boolean}
 */
isDecimalExceedsMaxLimit = function(id, locale) {

    var value = parseFloat(parseDecimal(
            document.getElementById(id).value, locale)).toFixed(2);
    if (value.toString().substring(
            0, value.toString().lastIndexOf('.')).length > numericMaxLimit
            || value.toString().length > decimalMaxLimit) {
        setFocus(id);
        return true;
    }
    return false;
};

其他回答

我们也可以使用numeraljs

数字的格式可以像货币、百分比、时间,甚至是带有小数位数、千位和缩写的普通数字。您可以始终创建自定义格式。

var string = numeral(1000).format('0,0');
// '1,000'

这是我的。。。

function thousandCommas(num) {
  num = num.toString().split('.');
  var ints = num[0].split('').reverse();
  for (var out=[],len=ints.length,i=0; i < len; i++) {
    if (i > 0 && (i % 3) === 0) out.push(',');
    out.push(ints[i]);
  }
  out = out.reverse() && out.join('');
  if (num.length === 2) out += '.' + num[1];
  return out;
}

PatrickDesjardins的回答看起来不错,但我更喜欢简单的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];
}

我很难找到一个简单的库来处理日期和货币,所以我创建了自己的:https://github.com/dericeira/slimFormatter.js

简单如下:

var number = slimFormatter.currency(2000.54);

+1向Jonathan M提供原始方法。由于这是一个明确的货币格式化程序,我继续在输出中添加了货币符号(默认为“$”),并添加了一个默认逗号作为千位分隔符。如果您实际上不需要货币符号(或千位分隔符),只需使用“”(空字符串)作为它的参数。

Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) {
    // check the args and supply defaults:
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator == undefined ? "." : decSeparator;
    thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
    currencySymbol = currencySymbol == undefined ? "$" : currencySymbol;

    var n = this,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "",
        j = (j = i.length) > 3 ? j % 3 : 0;

    return sign + currencySymbol + (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) : "");
};