,我想将用户的输入限制为纯数字或小数点后最多 2 位小数的数字。基本上,我要求输入价格。我想避免做正则表达式。有没有办法做到这一点?" /> ,我想将用户的输入限制为纯数字或小数点后最多 2 位小数的数字。基本上,我要求输入价格。我想避免做正则表达式。有没有办法做到这一点?"> ,我想将用户的输入限制为纯数字或小数点后最多 2 位小数的数字。基本上,我要求输入价格。我想避免做正则表达式。有没有办法做到这一点?" />
ChatGPT解决这个技术问题 Extra ChatGPT

Allow 2 decimal places in <input type="number">

I have a <input type="number"> and I want to restrict the input of the users to purely numbers or numbers with decimals up to 2 decimal places.

Basically, I am asking for a price input.

I wanted to avoid doing regex. Is there a way to do it?

<input type="number" required name="price" min="0" value="0" step="any">
type="number" doesn't have wide browser support. It is better to just use a textbox with some javascript to make sure that you get the desired input.
Yeah, but inputs fall back to type="text" anyways, so what does it matter?
/^\d+\.\d{2,2}$/ worked for me to require 0.00

M
Michael Benjamin

Instead of step="any", which allows for any number of decimal places, use step=".01", which allows up to two decimal places.

More details in the spec: https://www.w3.org/TR/html/sec-forms.html#the-step-attribute


This is not the correct answer. step only governs what happens when you click or press up and it does not restrict anything.
@Michael_B the user is not prevented from typing out a number such as 500.12345 in any of the inputs, perhaps our understanding of the requirements is different.
It should be noted that, while the user may type any number of digits after the decimal place, most browsers will not allow the submission of the form with an invalid value and the CSS selectors :valid and :invalid are applied as expected.
@Ini According to the linked spec (and MDN's docs), the step="" attribute is used for both the up/down arrows but also for built-in client-side validation (the orange exclamation mark popup that was added to Chrome a couple of years ago, Firefox also supports attribute-based (scriptless) client-side validation).
This is the correct answer because step="0.01" not only validates the decimal precision but also allows the user to insert decimal values in place of default integer
W
Weston Ganger

If case anyone is looking for a regex that allows only numbers with an optional 2 decimal places

^\d*(\.\d{0,2})?$

For an example, I have found solution below to be fairly reliable

HTML:

<input name="my_field" pattern="^\d*(\.\d{0,2})?$" />

JS / JQuery:

$(document).on('keydown', 'input[pattern]', function(e){
  var input = $(this);
  var oldVal = input.val();
  var regex = new RegExp(input.attr('pattern'), 'g');

  setTimeout(function(){
    var newVal = input.val();
    if(!regex.test(newVal)){
      input.val(oldVal); 
    }
  }, 1);
});

What's the purpose of having the setTimeout()?
@Derek. I assume it's so the regex.test doesn't block the DOM. Lookup this: developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
@Derek I can only assume the setTimeout() is to wait for the keydown event to complete before setting the newVal (otherwise it'll be the same as the oldVal). However, with a timeout of 0, it's pointless and doesn't work as both values are often the same (in Firefox). If you set it to 1, for instance, it works fine.
The ^\d*(\.\d{0,2})?$ regex would allow an input that ends with a dot like this: 122. A slightly better regex would be this: ^\d*(\.\d{1,2})?$
try magical setTimeout(function(){....},1); instead
W
Weston Ganger

For currency, I'd suggest:

<div><label>Amount $
    <input type="number" placeholder="0.00" required name="price" min="0" value="0" step="0.01" title="Currency" pattern="^\d+(?:\.\d{1,2})?$" onblur="
this.parentNode.parentNode.style.backgroundColor=/^\d+(?:\.\d{1,2})?$/.test(this.value)?'inherit':'red'
"></label></div>

See http://jsfiddle.net/vx3axsk5/1/

The HTML5 properties "step", "min" and "pattern" will be validated when the form is submit, not onblur. You don't need the step if you have a pattern and you don't need a pattern if you have a step. So you could revert back to step="any" with my code since the pattern will validate it anyways.

If you'd like to validate onblur, I believe giving the user a visual cue is also helpful like coloring the background red. If the user's browser doesn't support type="number" it will fallback to type="text". If the user's browser doesn't support the HTML5 pattern validation, my JavaScript snippet doesn't prevent the form from submitting, but it gives a visual cue. So for people with poor HTML5 support, and people trying to hack into the database with JavaScript disabled or forging HTTP Requests, you need to validate on the server again anyways. The point with validation on the front-end is for a better user experience. So as long as most of your users have a good experience, it's fine to rely on HTML5 features provided the code will still works and you can validate on the back-end.


According to MDN, pattern doesn't work for input type=number: <input type="number"> elements do not support use of the pattern attribute for making entered values conform to a specific regex pattern. The rationale for this is that number inputs can't contain anything except numbers, and you can constrain the minimum and maximum number of valid digits using the min and max attributes, as explained above.
@izogfif Good note. Also note I actually noted you don't need both and provided three ways: Step, pattern, and onblur. My rationale at the time was if a browser chokes on one for some reason it has the other. Probably safe to rely on step these days for frontend validation.
R
Robbie JW

Step 1: Hook your HTML number input box to an onchange event

myHTMLNumberInput.onchange = setTwoNumberDecimal;

or in the HTML code

<input type="number" onchange="setTwoNumberDecimal" min="0" max="10" step="0.25" value="0.00" />

Step 2: Write the setTwoDecimalPlace method

function setTwoNumberDecimal(event) {
    this.value = parseFloat(this.value).toFixed(2);
}

You can alter the number of decimal places by varying the value passed into the toFixed() method. See MDN docs.

toFixed(2); // 2 decimal places
toFixed(4); // 4 decimal places
toFixed(0); // integer

parseFloat(parseFloat(this.value).toFixed(2)); If you want decimal or number type you can wrap whole thing in parseFloat() as by default toFixed() method returns string.
Only thing approaching a working solution (that isn't ugly with regexps). Surprised this isn't built into HTML 🧐
How is this not built into HTML?
N
Nilesh Gajare

Try this for allowing only 2 decimal in input type

<input type="number" step="0.01" class="form-control"  />

Or Use jQuery as suggested by @SamohtVII

$( "#ELEMENTID" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});

This does not limit decimals to 2 places in Chrome 57
This is not correct. step only governs what happens when you click or press up and it does not restrict anything.
step also prevents number like 1.000 from being entered.
S
SamohtVII

I found using jQuery was my best solution.

$( "#my_number_field" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});

A
Abhilash Augustine

I had the same requirement but after checking all these answers I realized there is no inbuilt support to block users from typing a particular number of decimal points. step="0.01" is useful when validating the input for a decimal number but still it will not block users from typing any decimal. In my case, I wanted a solution which will prevent user from entering invalid decimal. So I created my own custom JavaScript function which will enforce user any decimal rule. There is a slight performance issue but for my scenario it is okay to have a very small delay to make sure that user is not typing invalid decimal places. It might be useful for someone who wanted to prevent user from typing invalid decimal value on the input.

You can use this solution with step="0.01" if you want. You can use the below function on your element oninput event. If performance is critical for you, then think to use this on onchange event rather than oninput. And please specify maximum number of decimal places allowed in the input in data-decimal attribute. it can have values from 0 to any number.

function enforceNumberValidation(ele) { if ($(ele).data('decimal') != null) { // found valid rule for decimal var decimal = parseInt($(ele).data('decimal')) || 0; var val = $(ele).val(); if (decimal > 0) { var splitVal = val.split('.'); if (splitVal.length == 2 && splitVal[1].length > decimal) { // user entered invalid input $(ele).val(splitVal[0] + '.' + splitVal[1].substr(0, decimal)); } } else if (decimal == 0) { // do not allow decimal place var splitVal = val.split('.'); if (splitVal.length > 1) { // user entered invalid input $(ele).val(splitVal[0]); // always trim everything after '.' } } } }

I might use RegExp to identify invalid value but I have to revert the change in the input as well. So I decided to not use RegExp.


T
TreeAndLeaf

I had a strange editing experience with some of these solutions. This seems to work pretty well from a user's perspective (only intervene when necessary):

function handleNumberChanged (e) {
    const fixed = parseFloat(e.target.value).toFixed(2).toString()
    if (fixed.length < parseFloat(e.target.value).toString().length)
      e.target.value = fixed
}

Saved my life :)
O
Obaidul Haque

Use this code

<input type="number" step="0.01" name="amount" placeholder="0.00">

By default Step value for HTML5 Input elements is step="1".


S
Suhaib Janjua

Only 3 decimal point input value in textbox using Javascript.

<input type="text" class="form-control" onkeypress='return AllowOnlyAmountAndDot(this,event,true);/>

function AllowOnlyAmountAndDot(id, e, decimalbool) {    
    if(decimalbool == true) {   
        var t = id.value;
        var arr = t.split(".");
        var lastVal = arr.pop();
        var arr2 = lastVal.split('');
        if (arr2.length > '2') {
            e.preventDefault();
        } 
    }
}

H
Hussain
  <input type="number" class="form-control" id="price" oninput="validate(this)" placeholder="Enter price" name="price" style="width:50%;">

  var validate = function(e) {
      var t = e.value;
      e.value = (t.indexOf(".") >= 0) ? (t.substr(0, t.indexOf(".")) + t.substr(t.indexOf("."), 3)) : t;
  }

u
user19499670

On Input:

<input type="number" name="price" id="price" required>

On script:

$('#price').on('change', function() {
    var get_price = document.getElementById('price').value;
    var set_price = parseFloat(get_price).toFixed(2);
    $('input[name=price').val(set_price);
})

a
aditya gathania

You can use this. react hooks


i
illustray king

just write

<input type="number" step="0.1" lang="nb">

lang='nb" let you write your decimal numbers with comma or period


"lang='nb' let you write your decimal numbers with comma or period" Can't speak for anything else, but that doesn't work in Chrome for me.
D
DJMcMayhem

On input:

step="any"
class="two-decimals"

On script:

$(".two-decimals").change(function(){
  this.value = parseFloat(this.value).toFixed(2);
});

Please avoid using slurs in your post. And remember to be nice