146

Is there's any way to format an input[type='number'] value to always show 2 decimal places?

Example: I want to see 0.00 instead of 0.

Dale K
  • 25,246
  • 15
  • 42
  • 71
Gui Ferreira
  • 4,367
  • 6
  • 28
  • 41

14 Answers14

86

You can't really do this just with HTML, but you a halfway step might be:

<input type='number' step='0.01' value='0.00' placeholder='0.00' />
Rich Bradshaw
  • 71,795
  • 44
  • 182
  • 241
  • 19
    This does not work in Chrome 55.0.2883.75. If I create a form element, place the markup above inside, type '1200' into the input and hit tab away from the element, the text displayed is still '1200' and not '1200.00'. – Rick Glos Dec 05 '16 at 19:47
  • 11
    all this seems to do is control what the step arrows do. setting a value of 1/3 will not limit the result to 2 decimals – Sonic Soul Jul 21 '17 at 16:16
  • It doesn't work for Chrome Version 78.0.3904.108 (Official Build) (64-bit) – Fasco Dec 04 '19 at 12:57
  • `step` is not supposed to work like this. Please read the documentation: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/step – mhombach Apr 07 '22 at 08:54
86

Solved following the suggestions and adding a piece of jQuery to force the format on integers:

parseFloat($(this).val()).toFixed(2)
Dale K
  • 25,246
  • 15
  • 42
  • 71
Gui Ferreira
  • 4,367
  • 6
  • 28
  • 41
17

Using the step attribute will enable it. It not only determines how much it's supposed to cycle, but the allowable numbers, as well. Using step="0.01" should do the trick but this may depend on how the browser adheres to the standard.

<input type='number' step='0.01' value='5.00'>
The Head Rush
  • 3,157
  • 2
  • 25
  • 45
Dissident Rage
  • 2,610
  • 1
  • 27
  • 33
  • 13
    doesn't work for me. If I click up to 5.01 and then down it says 5 not 5.00 in Chrome 72 – gman Mar 09 '19 at 14:20
  • If you're looking for a strictly numeric interpretation this is the correct behavior, "5.00" is a string. – Dissident Rage Apr 16 '20 at 21:05
  • 14
    irrelevant. The question is looking to always show 2 decimal places and this answer doesn't do that. – gman Apr 17 '20 at 02:15
  • Then they're looking for `input[type="text"]` with all of the native bells and whistles that come with `input[type="number"]` thoroughly reimplimented for it, or swapping out this field for another to display the value depending on element state. – Dissident Rage Apr 20 '20 at 14:39
  • 1
    This does not actually work. All step does is change how the increment/decrement buttons on a number field work. It doesn't force the value to appear a certain way on load. – Andrew Gray Dec 08 '21 at 20:50
11

The solutions which use input="number" step="0.01" work great for me in Chrome, however do not work in some browsers, specifically Frontmotion Firefox 35 in my case.. which I must support.

My solution was to jQuery with Igor Escobar's jQuery Mask plugin, as follows:

$(document).ready(function () {
  $('.usd_input').mask('00000.00', { reverse: true });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js" integrity="sha512-pHVGpX7F/27yZ0ISY+VVjyULApbDlD0/X0rgGbTqCE7WFW5MezNTWG/dnhtbBuICzsd0WQPgpE4REBLv+UqChw==" crossorigin="anonymous"></script>

<input type="text" autocomplete="off" class="usd_input" name="dollar_amt">

This works well, of course one should check the submitted value afterward :) NOTE, if I did not have to do this for browser compatibility I would use the above answer by @Rich Bradshaw.

Sastrija
  • 3,284
  • 6
  • 47
  • 64
little_birdie
  • 5,600
  • 3
  • 23
  • 28
  • 2
    Not sure why this was downvoted.. much to my surprise. As I said in my answer, this is an alternate solution only for those who (like me) are stuck supporting browsers in which the other answer does not work. And I know it works because it is currently in production and working! – little_birdie Jul 14 '16 at 19:18
  • Javascript in this case should be a fallback, not default behavior. If the functionality doesn't exist, then hooking Javascript to it is appropriate. You can check this by testing if the input's `type` attribute is `number` or `text`. If it returns `text` even though the HTML is written as `number` then the browser doesn't support that type, and hooking this behavior to it is an appropriate action. – Dissident Rage Aug 04 '16 at 16:12
  • If you had indicated that in a comment I would have amended my answer to include that functionality. Most applications these days either don't work at all without js.. or barely work.. so it is becoming moot. But I agree that putting in a check would improve the answer. I am currently travelling.. I will amend it when I get back. – little_birdie Aug 05 '16 at 22:31
10

Based on this answer from @Guilherme Ferreira you can trigger the parseFloat method every time the field changes. Therefore the value always shows two decimal places, even if a user changes the value by manual typing a number.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        $(".floatNumberField").change(function() {
            $(this).val(parseFloat($(this).val()).toFixed(2));
        });
    });
</script>

<input type="number" class="floatNumberField" value="0.00" placeholder="0.00" step="0.01" />
mhellmeier
  • 1,982
  • 1
  • 22
  • 35
  • This only works when the element loses focus. if the user would immediately click the submit button after filling the input field, he will not see the corrected value which might be misleading. – Stan Aug 11 '20 at 10:52
  • I am not 100 % sure but I think the `change()` function will be triggered in the small time between the user input and the submit button click. Therefore, this shouldn't be a problem. – mhellmeier Aug 11 '20 at 13:29
  • Yes it does indeed change but the user won't know that so that might lead to confusion since the user won't see the corrected value before it's instantly submitted. Although this might not be a problem for most usecases – Stan Aug 12 '20 at 11:57
  • /* Good for setting initial value to 2 decimals without the user changing the input first */ const initialPrice = 10; $(".floatNumberField").val(parseFloat(initialPrice).toFixed(2)); – LaZza Dec 05 '20 at 18:39
  • Changing from `change` to `input` event like: `$(".floatNumberField").on("input", ...` results in faster response for me on Firefox. – jpa Jan 27 '23 at 14:12
8

If you landed here just wondering how to limit to 2 decimal places I have a native javascript solution:

Javascript:

function limitDecimalPlaces(e, count) {
  if (e.target.value.indexOf('.') == -1) { return; }
  if ((e.target.value.length - e.target.value.indexOf('.')) > count) {
    e.target.value = parseFloat(e.target.value).toFixed(count);
  }
}

HTML:

<input type="number" oninput="limitDecimalPlaces(event, 2)" />

Note that this cannot AFAIK, defend against this chrome bug with the number input.

Stephen Paul
  • 37,253
  • 15
  • 92
  • 74
2

This works to enforce a max of 2 decimal places without automatically rounding to 2 places if the user isn't finished typing.

function naturalRound(e) {

   let dec = e.target.value.indexOf(".")
   let tooLong = e.target.value.length > dec + 3
   let invalidNum = isNaN(parseFloat(e.target.value))

   if ((dec >= 0 && tooLong) || invalidNum) {
     e.target.value = e.target.value.slice(0, -1)
   }
}
SuperCodeBrah
  • 2,874
  • 2
  • 19
  • 33
1

I know this is an old question, but it seems to me that none of these answers seem to answer the question being asked so hopefully this will help someone in the future.

Yes you can always show 2 decimal places, but unfortunately it can't be done with the element attributes alone, you have to use JavaScript.

I should point out this isn't ideal for large numbers as it will always force the trailing zeros, so the user will have to move the cursor back instead of deleting characters to set a value greater than 9.99

//Use keyup to capture user input & mouse up to catch when user is changing the value with the arrows
    $('.trailing-decimal-input').on('keyup mouseup', function (e) {

        // on keyup check for backspace & delete, to allow user to clear the input as required
        var key = e.keyCode || e.charCode;
        if (key == 8 || key == 46) {
            return false;
        };

        // get the current input value
        let correctValue = $(this).val().toString();

         //if there is no decimal places add trailing zeros
        if (correctValue.indexOf('.') === -1) {
            correctValue += '.00';
        }

        else {

            //if there is only one number after the decimal add a trailing zero
            if (correctValue.toString().split(".")[1].length === 1) {
                correctValue += '0'
            }

            //if there is more than 2 decimal places round backdown to 2
            if (correctValue.toString().split(".")[1].length > 2) {
                correctValue = parseFloat($(this).val()).toFixed(2).toString();
            }
        }

        //update the value of the input with our conditions
        $(this).val(correctValue);
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="my-number-input" class="form-control trailing-decimal-input" type="number" min="0.01" step="0.01" value="0.00" />
Verno
  • 428
  • 1
  • 5
  • 20
  • `parseFloat($(this).val()).toFixed(2).toString()` is reundant as `parseFloat($(this).val()).toFixed(2)` already returns the value as a string – Michael McCauley Sep 17 '21 at 17:15
1

This is a quick formatter in JQuery using the .toFixed(2) function for two decimal places.

<input class="my_class_selector" type='number' value='33'/>


// if this first call is in $(document).ready() it will run
// after the page is loaded and format any of these inputs

$(".my_class_selector").each(format_2_dec);
function format_2_dec() {
    var curr_val = parseFloat($(this).val());
    $(this).val(curr_val.toFixed(2));
}

Cons: you have to call this every time the input number is changed to reformat it.

// listener for input being changed
$(".my_class_selector").change(function() {
    // potential code wanted after a change

    // now reformat it to two decimal places
    $(".my_class_selector").each(format_2_dec);
});

Note: for some reason even if an input is of type 'number' the jQuery val() returns a string. Hence the parseFloat().

Dale K
  • 25,246
  • 15
  • 42
  • 71
kblocks
  • 11
  • 2
1

The top answer gave me the solution but I didn't like that the user input was changed immediately so I added delay which in my opinion contributes to a better user experience

var delayTimer;
function input(ele) {
    clearTimeout(delayTimer);
    delayTimer = setTimeout(function() {
       ele.value = parseFloat(ele.value).toFixed(2).toString();
    }, 800); 
}
<input type='number' oninput='input(this)'>

https://jsfiddle.net/908rLhek/1/

Stan
  • 629
  • 7
  • 18
0

My preferred approach, which uses data attributes to hold the state of the number:

const el = document.getElementById('amt');
// react to stepping in UI
el.addEventListener('onchange', ev => ev.target.dataset.val = ev.target.value * 100)

// react to keys
el.addEventListener('onkeyup', ev => {

  // user cleared field
  if (!ev.target.value) ev.target.dataset.val = ''

  // non num input
  if (isNaN(ev.key)) {

    // deleting
    if (ev.keyCode == 8)

      ev.target.dataset.val = ev.target.dataset.val.slice(0, -1)

    // num input
  } else ev.target.dataset.val += ev.key

  ev.target.value = parseFloat(ev.target.dataset.val) / 100

})
<input id="amt" type='number' step='0.01' />
mplungjan
  • 169,008
  • 28
  • 173
  • 236
nikk wong
  • 8,059
  • 6
  • 51
  • 68
  • I made you a snippet to see how it worked. In Chrome, if I type something and then click the spinners, I get 0,01 concatenated to the number typed. That cannot be the usecase here? – mplungjan Sep 08 '21 at 06:24
-3

ui-number-mask for angular, https://github.com/assisrafael/angular-input-masks

only this:

<input ui-number-mask ng-model="valores.irrf" />

If you put value one by one....

need: 120,01

digit per digit

 = 0,01
 = 0,12
 = 1,20
 = 12,00
 = 120,01 final number.
Dale K
  • 25,246
  • 15
  • 42
  • 71
Raphael Vitor
  • 622
  • 6
  • 7
-4

Take a look at this:

 <input type="number" step="0.01" />
Community
  • 1
  • 1
chris
  • 4,827
  • 6
  • 35
  • 53
  • 6
    This is okay for stepping, but not formatting. If you want 2 decimal places and someone enters (or spins to) "0.1" , it will stay "0.1" (instead of what is desired "0.01") in all browsers. Placeholder only works for the empty condition (it's not a format, either) – MC9000 Feb 16 '17 at 20:19
-4

This is the correct answer:

<input type="number" step="0.01" min="-9999999999.99" max="9999999999.99"/>
Flimm
  • 136,138
  • 45
  • 251
  • 267
Alex
  • 1,013
  • 1
  • 13
  • 27
  • 5
    This is a better and more modern approach that many of the other answers but still does not put trailing zeros onto what is entered – pcnate May 10 '17 at 13:51