最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Convert input value to currency format when user type - Stack Overflow

programmeradmin1浏览0评论

I have failed to convert the input value to currency format. I want to automaticly add thousands and decimal separators when the user types the number (5,000.00; 125,000.00).

Here's my code :

$('input.CurrencyInput').on('blur, focus, keyup',
    function() {
        $(this).val().toLocaleString('en-US', {
            style: 'decimal',
            maximumFractionDigits: 2,
            minimumFractionDigits: 2
        });
    });

I have failed to convert the input value to currency format. I want to automaticly add thousands and decimal separators when the user types the number (5,000.00; 125,000.00).

Here's my code :

$('input.CurrencyInput').on('blur, focus, keyup',
    function() {
        $(this).val().toLocaleString('en-US', {
            style: 'decimal',
            maximumFractionDigits: 2,
            minimumFractionDigits: 2
        });
    });
Share Improve this question edited Jun 6, 2018 at 14:23 AlonsoCT asked Jun 6, 2018 at 14:06 AlonsoCTAlonsoCT 1911 gold badge5 silver badges18 bronze badges 5
  • .val() returns a string, but .toLocaleString is a method of a number. – Tyler Roper Commented Jun 6, 2018 at 14:09
  • Possible duplicate of How can I format numbers as dollars currency string in JavaScript? – admcfajn Commented Jun 6, 2018 at 14:10
  • Also, you're not setting the value anywhere. You're fetching the current value and attempting to manipulate it, but not doing anything with the result. – Tyler Roper Commented Jun 6, 2018 at 14:13
  • You cannot use oninput nor keyup since you do not know what they are planning to type. Would I be able to type 1,123,123.123 and have it formate to 1,123,123.12 or type 1123123.123 (which is a valid float) and have it format to 1,123,123.12 while I type? – mplungjan Commented Jun 6, 2018 at 14:20
  • You may want to take a look at some external libraries/plugins. I've used this one in the past and it works well. (Click on the demo button - there's a currency input there) – Tyler Roper Commented Jun 6, 2018 at 14:35
Add a comment  | 

2 Answers 2

Reset to default 12

There are a couple of problems with your code:

  1. You're using comma when binding multiple event handlers to the input box.
  2. You're not converting the received value to a number before applying toLocaleString on it.
  3. You're not setting the value of the textbox again after conversion.

Correcting these, here is a working demo. For the sake of simplicity, I've removed the other event handlers, except blur, as keyup was causing problems.

$('input.CurrencyInput').on('blur', function() {
  const value = this.value.replace(/,/g, '');
  this.value = parseFloat(value).toLocaleString('en-US', {
    style: 'decimal',
    maximumFractionDigits: 2,
    minimumFractionDigits: 2
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="CurrencyInput">

Parse value to specific Locale Currency

The below function will try to parse any gibberish input value to a specific currency.
Useful if you don't want to force users to input values in a specific locale format.

Caveat:

Since the input can literally be gibberish like 1,2.3.45,5 and still give a valid output (like i.e USD: "12,345.50"), there's a small but user friendly caveat:

// Example: conversion to HRK (Format: n.nnn,nn)
INPUT: "0.575"   OUTPUT: "0,58"      // smart guessed: decimals
INPUT: "1.575"   OUTPUT: "1.575,00"  // smart guessed: separator

Example:

/**
 * Parse value to currency
 * @param {number|string} input
 * @param {string} locale - Desired locale i.e: "en-US" "hr-HR"
 * @param {string} currency - Currency to use "USD" "EUR" "HRK"  
 * @return {object} 
 */
const parse = (input, locale = "en-US", currency = "USD") => {
  let fmt = String(input)
    .replace(/(?<=\d)[.,](?!\d+$)/g, "")
    .replace(",", ".");
  const pts = fmt.split(".");
  if (pts.length > 1) {
    if (+pts[0] === 0) fmt = pts.join(".");
    else if (pts[1].length === 3) fmt = pts.join("");
  }
  const number = Number(fmt);
  const isValid = isFinite(number);
  const string = number.toFixed(2);
  const intlNFOpts = new Intl.NumberFormat(locale, {
    style: "currency",
    currency: currency,
  }).resolvedOptions();
  const output = number.toLocaleString(locale, {
    ...intlNFOpts,
    style: "decimal",
  });
  return {
    input,
    isValid,
    string,
    number,
    currency,
    output,
  };
};

Example test:

/**
 * Parse value to currency
 * @param {number|string} input
 * @param {string} locale - Desired locale i.e: "en-US" "hr-HR"
 * @param {string} currency - Currency to use "USD" "EUR" "HRK"  
 * @return {object} 
 */
const parse = (input, locale = "en-US", currency = "USD") => {
  let fmt = String(input)
    .replace(/(?<=\d)[.,](?!\d+$)/g, "")
    .replace(",", ".");
  const pts = fmt.split(".");
  if (pts.length > 1) {
    if (+pts[0] === 0) fmt = pts.join(".");
    else if (pts[1].length === 3) fmt = pts.join("");
  }
  const number = Number(fmt);
  const isValid = isFinite(number);
  const string = number.toFixed(2);
  const intlNFOpts = new Intl.NumberFormat(locale, {
    style: "currency",
    currency: currency,
  }).resolvedOptions();
  const output = number.toLocaleString(locale, {
    ...intlNFOpts,
    style: "decimal",
  });
  return {
    input,
    isValid,
    string,
    number,
    currency,
    output,
  };
};

// TEST:
[
  // Valid values
  "2e5",
  "1,2.3,10,6",
  "0.575",
  "1.575",
  "2.30",
  "1.000.00",
  "1.000",
  1000,
  1,
  ".4",
  "4.",
  "0.25",
  "0.076",
  "1.076",
  0.3478,
  "0.05",
  "123,123",
  "3.000,333.444,009",
  "123,123.80",
  "23.123,80",
  "23.123,8",
  "23.4",
  
  // Invalid values
  null,
  NaN,
  Infinity,
  "a",
].forEach((val) => {
  const p = parse(val, "hr-HR", "HRK");
  console.log(`INP: ${p.input}\t OUT: ${p.output}`);
});
.as-console-wrapper {min-height: 100vh;}

Documentaion:

  • DateTimeFormat.resolvedOptions
  • Intl.NumberFormat
  • Number.toLocaleString
发布评论

评论列表(0)

  1. 暂无评论