在<input type="number" />中设置货币值

81
我正在尝试使用JavaScript将用户输入的数字格式化为货币。这在 <input type="text" /> 上很好用。但是,在 <input type="number" /> 上,我似乎无法将值设置为包含非数字值的任何东西。下面的fiddle展示了我的问题。
这里有我的问题:http://jsfiddle.net/2wEe6/72/ 是否有办法让我将值设置为类似于$125.00的内容?
我想使用<input type="number" />,这样移动设备会自动弹出数字输入键盘。

8
你能否在控件前面显示美元符号?或者你想让用户控制他们想要输入的货币吗?如果是后者,我恐怕只有 type="text" 符合要求。 - Mr Lister
@MrLister 那是一个非常好的观点。那可能是我最终会做的事情。 - Danny
如果您想让用户更改货币类型,但仍使用"type = number",您可以使用下拉框来选择不同的货币符号。请注意,许多国家将货币符号放在数字之后而不是之前。 - RoboticRenaissance
链接 - HTML5货币/货币输入 - vsync
7个回答

94

<input type="number" /> 参数添加 step="0.01"

<input type="number" min="0.01" step="0.01" max="2500" value="25.67" />

演示:http://jsfiddle.net/uzbjve2u/

但是美元符号必须留在文本框外面,任何非数字或分隔符字符都将自动剪裁。

否则,您可以使用传统的文本框,如此描述


8
并不是OP所要求的...如果value="25.6",那么它就会显示为"25.6",但它应该显示为"25.60"。 - patrick
1
HTML5规范/实现有缺陷。@patrick您想要的除了hackish、依赖浏览器的解决方案外不可能实现,而这些解决方案在Firefox上无法运行。我已经编辑了fiddle,因为Globalize.format函数在FF中现在完全破坏了它,所以我想我应该感谢您的反馈:) - Andrea Ligios
1
@AndreaLigios,你所描述的链接就是我在为文本框格式化货币时正在寻找的。虽然我需要进行一些修改,但这是一个很好的起点。 - Jester
1
这里的“min”没有意义。我可以轻松地设置负值。 - Green
2
@Green 我正在使用Firefox浏览器,但我无法做到。然而,这是特定于浏览器实现的,最终,我相信你理解客户端验证和服务器端验证之间的区别。我不确定负评实际上是关于什么的,但感谢您的反馈。 - Andrea Ligios

27
最后,我编写了一个jQuery插件,用于适当地格式化。我还注意到在某些移动设备上,min和max属性实际上并不能阻止输入低于或高于指定数字的值,因此该插件也会进行处理。以下是代码和示例:

(function($) {
  $.fn.currencyInput = function() {
    this.each(function() {
      var wrapper = $("<div class='currency-input' />");
      $(this).wrap(wrapper);
      $(this).before("<span class='currency-symbol'>$</span>");
      $(this).change(function() {
        var min = parseFloat($(this).attr("min"));
        var max = parseFloat($(this).attr("max"));
        var value = this.valueAsNumber;
        if(value < min)
          value = min;
        else if(value > max)
          value = max;
        $(this).val(value.toFixed(2)); 
      });
    });
  };
})(jQuery);

$(document).ready(function() {
  $('input.currency').currencyInput();
});
.currency {
  padding-left:12px;
}

.currency-symbol {
  position:absolute;
  padding: 2px 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="number" class="currency" min="0.01" max="2500.00" value="25.00" />


10

你们完全正确,数字只能输入到数值字段中。我使用与已列出内容完全相同的东西,只是在一个 span 标签上使用了一些 CSS 样式:

<span>$</span><input type="number" min="0.01" step="0.01" max="2500" value="25.67">

然后添加一些样式魔法:

span{
  position:relative;
  margin-right:-20px
}
input[type='number']{
  padding-left:20px;
  text-align:left;
}

这个看起来很好,很整洁。唯一的问题就是点击货币符号不会聚焦到输入框上。 - Mark W
这是一个简单的JavaScript问题。在span上点击事件以聚焦输入。 - frugalcoder
11
或者您可以使用<label>标签,这也具有语义价值(而且您不需要JS)。 - nils

4
似乎需要两个字段,一个用于选择货币的选项列表,另一个用于数值的数字字段。
在这种情况下常见的技巧是使用 div 或 span 用于显示(表单字段看不见),并在点击时切换到表单元素进行编辑。

这比让用户输入货币要好得多。 - Mr Lister
抱歉,但是这里提供的jQuery示例和Dojo中的CurrencyTextBox比两个字段更提供了更多用户友好的输入和验证方法。除了在移动设备上,因为你必须使用文本键盘。最终的讽刺是,在我的iPad上,type="number"包括了我的区域货币符号,£。HTML真的需要跟上并提供一些可以切换到适当货币键盘的东西。 - Paul Stephen Withers

0

我使用了这个代码片段。这个代码片段可以自动将数字格式化为货币,并在前面加上美元符号。

<div class="main">
  <h1>Auto Formatting Currency</h1>
  
  <form method="post" action="#">
  <label for="currency-field">Enter Amount</label>
  <input type="text" name="currency-field" id="currency-field" pattern="^\$\d{1,3}(,\d{3})*(\.\d+)?$" value="" data-type="currency" placeholder="$1,000,000.00">
  <button type="submit">Submit</button>
</form>

<p>Auto format currency input field with commas and decimals if needed. Text is automatically formated with commas and cursor is placed back where user left off after formatting vs cursor moving to the end of the input. Validation is on KeyUp and a final validation is done on blur.</p>

<p>To use just add the following to an input field:</p>
  
 <pre>data-type="currency"</pre>
  
</div><!-- /main -->

    html {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit;
}


body {
  background: #f5f5f5;
  color: #333;
  font-family: arial, helvetica, sans-serif;
  font-size: 32px;
}

h1 {
  font-size: 32px;
  text-align: center;
}

p {
  font-size: 20px;
  line-height: 1.5;
  margin: 40px auto 0;
  max-width: 640px;
}

pre {
  background: #eee;
  border: 1px solid #ccc;
  font-size: 16px;
  padding: 20px;
}

form {
  margin: 40px auto 0;
}

label {
  display: block;
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 10px;
}

input {
  border: 2px solid #333;
  border-radius: 5px;
  color: #333;
  font-size: 32px;
  margin: 0 0 20px;
  padding: .5rem 1rem;
  width: 100%;

}

button {
  background: #fff;
  border: 2px solid #333;
  border-radius: 5px;
  color: #333;
  font-size: 16px;
  font-weight: bold;
  padding: 1rem;
}

button:hover {
  background: #333;
  border: 2px solid #333;
  color: #fff;
}

.main {
  background: #fff;
  border: 5px solid #ccc;
  border-radius: 10px;
  margin: 40px auto;
  padding: 40px;
  width: 80%;
  max-width: 700px;
}

    // Jquery Dependency

$("input[data-type='currency']").on({
    keyup: function() {
      formatCurrency($(this));
    },
    blur: function() { 
      formatCurrency($(this), "blur");
    }
});


function formatNumber(n) {
  // format number 1000000 to 1,234,567
  return n.replace(/\D/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, ",")
}


function formatCurrency(input, blur) {
  // appends $ to value, validates decimal side
  // and puts cursor back in right position.
  
  // get input value
  var input_val = input.val();
  
  // don't validate empty input
  if (input_val === "") { return; }
  
  // original length
  var original_len = input_val.length;

  // initial caret position 
  var caret_pos = input.prop("selectionStart");
    
  // check for decimal
  if (input_val.indexOf(".") >= 0) {

    // get position of first decimal
    // this prevents multiple decimals from
    // being entered
    var decimal_pos = input_val.indexOf(".");

    // split number by decimal point
    var left_side = input_val.substring(0, decimal_pos);
    var right_side = input_val.substring(decimal_pos);

    // add commas to left side of number
    left_side = formatNumber(left_side);

    // validate right side
    right_side = formatNumber(right_side);
    
    // On blur make sure 2 numbers after decimal
    if (blur === "blur") {
      right_side += "00";
    }
    
    // Limit decimal to only 2 digits
    right_side = right_side.substring(0, 2);

    // join number by .
    input_val = "$" + left_side + "." + right_side;

  } else {
    // no decimal entered
    // add commas to number
    // remove all non-digits
    input_val = formatNumber(input_val);
    input_val = "$" + input_val;
    
    // final formatting
    if (blur === "blur") {
      input_val += ".00";
    }
  }
  
  // send updated string to input
  input.val(input_val);

  // put caret back in the right position
  var updated_len = input_val.length;
  caret_pos = updated_len - original_len + caret_pos;
  input[0].setSelectionRange(caret_pos, caret_pos);
}

https://codepen.io/akalkhair/pen/dyPaozZ


0
我曾经为同一个问题苦苦挣扎了好几十分钟,但最终我决定对此感到满意。 (与Yassir的方式非常相似,只是没有使用jQuery,我想)
  • 没有使用jQuery或其他任何东西,只用原生JS

  • 可以在框内的任何地方点击进行交互

  • 在输入时进行格式化

  • 将文本输入中的数字字符格式化为货币格式

  • 添加美元符号

  • 每3位数字添加一个逗号

  • 对于小数点后2位,添加一个小数点 还会改变文本值的颜色

// Get the input element with the id "inputamount"
const inputAmount = document.getElementById("inputamount");

// Add an event listener to listen for input changes in the input element
inputAmount.addEventListener("input", function () {
    // Call the formatCurrency function when the input value changes, passing the input element and its color element
    formatCurrency(this, inputAmount);
});

// The formatCurrency function takes an input element and an inputColor element
function formatCurrency(input, inputColor) {
    // Remove non-numeric characters from the input value
    let value = input.value.replace(/[^\d]+/g, '');

    // Split the value into whole and decimal parts
    const wholePart = value.slice(0, -2);
    const decimalPart = value.slice(-2);

    // Format the whole part with commas every three digits
    let formattedValue = wholePart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");

    // Add the decimal point and the last two digits
    formattedValue += `.${decimalPart}`; 
    // Update the input value with the formatted value and add $ symbol
    input.value = "$"+formattedValue;

    // Change the color style of the input based on its value
    if (input.value === "") {
        // When the input is empty, set the text color to placeholder color
        inputColor.style.color = "#757575";
    } else {
        // When the input has text, set the text color to whatever you want
        inputColor.style.color = "#14990d";
        // when input has value it is set to bold weight here
        inputColor.style.fontWeight = "bold";
    }
}
.background{background-color: #fff;}

.container {width: 130px;background-color: #1b2327;color: #fff;border: 6px outset #606263;border-radius: 10px;padding: 4px;text-align: center;}

#inputamount {width: 75%;text-align: center;background-color: #283339;color: #606263;border: 2px outset #606263;margin: auto;}

span.subtext {font-size: 11px;font-style: italic;color: #606263;}
<div class="background">
  <div class="container">
    <div class= "Amountbox" id="Expense-Amountbox">
        <label for="expense">Enter Amount</label>
        <input type="text" id="inputamount" placeholder="10,000.00" style="display: block;">
        <span class="subtext">Automatically Formatted</span>
        <br>
        <span class="subtext">1234567 = $12,345.67</span>
    </div>
  </div>
</div>


-1

当类型设置为“number”时,浏览器只允许数字输入。详情请见

您可以使用type="text",并使用JavaScript 如此描述来过滤除数字以外的任何输入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接