如何用每千个点和每个十进制数的逗号来格式化数字?

how to format numbers with dots for every thousand and comma for every decimal number?

提问人:Sofie Hilge Thygesen 提问时间:11/17/2023 更新时间:11/19/2023 访问量:38

问:

我正在制作一个货币转换器,我需要它根据欧洲标准用逗号和句点显示数字,如下所示:

1.543.456,50 欧元,所以一百万、五十万等。

现在这个数字显示如下 1543456.50 €

我遇到了另一个问题,不允许我在输入字段中输入任何逗号或句点。我需要让它 type=text,因为我希望用户能够输入想要的号码。

这是我的代码:

import React, { useId, useState } from "react";

function InputBox({
  label,
  amount,
  onAmountChange,
  onCurrencyChange,
  currencyOptions = [],
  selectedCurrency = "eur",
  amountDisabled = false,
  currencyDisabled = false,
  className = "",
}) {
  const id = useId();
  const [amountValue, setAmountValue] = useState("");

  const isEuropeanCurrency = (currency) => {
    const europeanCurrencies = [
      "eur", // Euro
      "gbp", // British Pound
      "chf", // Swiss Franc
      "sek", // Swedish Krona
      "nok", // Norwegian Krone
      "dkk", // Danish Krone
      "pln", // Polish Złoty
      "czk", // Czech Koruna
      "huf", // Hungarian Forint
      "ron", // Romanian Leu
      "bgn", // Bulgarian Lev
      "hrk", // Croatian Kuna
      "try", // Turkish Lira
      "isk", // Icelandic Króna
    ];
    return europeanCurrencies.includes(currency.toLowerCase());
  };

  const isCryptoCurrency = (currency) => {
    const cryptoCurrencies = [
      "btc", // Bitcoin
      "eth", // Ethereum
      "ltc", // Litecoin
      "xrp", // Ripple
      "bch", // Bitcoin Cash
      "ada", // Cardano
      "xlm", // Stellar
      "dot", // Polkadot
      "link", // Chainlink
      "bnb", // Binance Coin
    ];
    return cryptoCurrencies.includes(currency.toLowerCase());
  };

  const handleKeyDown = (e) => {
    //Allow only numeric and specific control keys
    const isAllowedKey =
      e.key === "," || // Allow comma
      e.key === "." || // Allow dot
      (e.key >= "0" && e.key <= "9") ||
      e.key === "Backspace" ||
      e.key === "Delete" ||
      e.key === "ArrowLeft" ||
      e.key === "ArrowRight" ||
      e.key === "Home" ||
      e.key === "End";
    if (!isAllowedKey) {
      e.preventDefault();
    }
  };

  const handleInputClick = () => {
    setAmountValue("");
  };

  return (
    <div className={`bg-white p-3 rounded-lg text-sm flex ${className}`}>
      <div className="w-1-2">
        <label htmlFor={id} className="text-black/40 mb-2 inline-block">
          {label}
        </label>
        <input
          id={id}
          type="text"
          className="outline-none w-full bg-transparent py-1.5"
          placeholder="Amount"
          disabled={amountDisabled}
          value={amount}
          onChange={(e) => {
            // Allow only numbers, commas, and dots
            const numericValue = e.target.value.replace(/[^0-9,.]/g, "");

            // Attempt to convert the numeric value to a number
            const parsedValue = Number(numericValue);

            // Check if the conversion is successful
            if (!isNaN(parsedValue)) {
              // Update the state with the parsed numeric value
              onAmountChange && onAmountChange(parsedValue);
            } else {
              // If the conversion fails, set an empty string or the original value
              setAmountValue(e.target.value);
            }
          }}
          onClick={handleInputClick} // Handle click event to reset the value
        />
      </div>
      <div className="w-1/2 flex flex-wrap justify-end text-right">
        <p className="text-black/40 mb-2 w-full">Currency Type</p>
        <select
          className="rounded-lg px-1 py-1 bg-gray-100 cursor-pointer outline-none"
          value={selectedCurrency}
          onChange={(e) => {
            onCurrencyChange && onCurrencyChange(e.target.value);
          }}
          disabled={currencyDisabled}
        >
          {currencyOptions
            .filter(
              (currency) =>
                isEuropeanCurrency(currency) || isCryptoCurrency(currency)
            )
            .map((currency) => (
              <option key={currency} value={currency}>
                {currency}
              </option>
            ))}
        </select>
      </div>
    </div>
  );
}

export default InputBox;

我尝试为 React 导入 Numeral,但它没有为欧洲标准提供解决方案,而只提供美国句号和逗号符号。

正如您在我的代码中看到的那样,我还尝试使它与 javascript 代码一起使用,但是它没有应用于浏览器。

非常感谢您的任何帮助或建议!

reactjs 数字 周期格式化程序

评论

0赞 cyberbrain 11/17/2023
我认为这不是特定于 React,而是应该在普通 JavaScript 中有一个简单开箱即用的解决方案
0赞 Sofie Hilge Thygesen 11/18/2023
是的,我是这么认为的。我觉得我已经尝试过了,但也许是我的代码中的错误阻止了它的应用。我再次用谷歌搜索,找到了这篇文章,我稍后会尝试应用于代码: byby.dev/js-format-numbers-commas

答:

0赞 SJai 11/19/2023 #1

let num = 10000500.2;
let formattedNum = num.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
console.log(formattedNum);

评论

0赞 Sofie Hilge Thygesen 11/20/2023
嗨,SJai,是的,我让它工作,我的问题是我需要它符合spansih/欧洲标准,所以这个数字应该是10.000.500,20