30

I have a field:

<input type='number' />

I'd like to punch in 0.50 without it “correcting it” to 0.5, so it would display 0.50.

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
Tarang
  • 75,157
  • 39
  • 215
  • 276

2 Answers2

13

I attached an on('change') event to the input you want to have trailing 0's

$('.number-input').on('change', function(){
    $(this).val(parseFloat($(this).val()).toFixed(2));
});

It just takes the value, casts it to a float, renders it to a string to the number of decimal places, and puts it back in as the value.

Jacob Valenta
  • 6,659
  • 8
  • 31
  • 42
12

I've had a little play around with this and looked at the spec. It says that it must be a valid floating point number. There's one sentence in the definition of a valid floating point number it gives which caught my attention:

The best representation of the number n as a floating point number is the string obtained from applying the JavaScript operator ToString to n.

This means that the format will always be consistent with assessing what the number is, then using JavaScript's toString on that number. So no trailing 0s then.

So, you're going to have to resort to JavaScript. This isn't straightforward because document.getElementById('numInput').value = '0.50'; still gets corrected to 0.5, so the validation isn't triggered at onchange where the default action can be prevented, it's triggered internally.

This is the best solution I could come up with... it's a bit of a hack, and will need a bit of tweaking for robustness, but hopefully it'll do what you want:

var numInput = document.getElementById('numInput');
numInput.addEventListener('keypress', function () {
    this.setAttribute('type', 'text');
});
numInput.addEventListener('click', function () {
    this.setAttribute('type', 'number');
});

So if the user wants to enter the number by typing, it switches the input type to text, but when they click it, it converts it back to a number.

If you always want the trailing 0s no matter what the user types, then you could do it something like this:

var numInput = document.getElementById('numInput');
numInput.addEventListener('blur', function () {
    if (this.value === '') {
        return;
    }
    this.setAttribute('type', 'text');
    if (this.value.indexOf('.') === -1) {
        this.value = this.value + '.00';
    }
    while (this.value.indexOf('.') > this.value.length - 3) {
        this.value = this.value + '0';
    }
});
numInput.addEventListener('focus', function () {
    this.setAttribute('type', 'number');
});

Edit: I think the second solution is more inline with what the user might expect, but it means that if the user types 0.5 it will be coerced to 0.50, so it depends if that's what you want.

Nathan MacInnes
  • 11,033
  • 4
  • 35
  • 50
  • Thats a very smart way to solve it by correcting the decimals and switching between text and number fields. Thanks! – Tarang Oct 17 '11 at 13:46
  • 3
    Glad you like it. This is IMO a shortcoming in the HTML5 spec, so hopefully someone will realise this and fix it at some point in the future. – Nathan MacInnes Oct 17 '11 at 21:24
  • Good solution. I expanded it a little bit to only affect specified inputs, and also used the 'change' event to make it retain the trailing zeroes even as you press the input buttons. Don't know why it didn't work with plain JS 'onchange', so I did it in JQuery. Tested on Chrome only: `$('input.float').each(function(index) { $(this).change(function(event) { if (this.value === '') { return; } if (this.value.indexOf('.') === -1) { this.value = this.value + '.00'; } while (this.value.indexOf('.') > this.value.length - 3) { this.value = this.value + '0'; } }); });` – YOMorales Mar 22 '13 at 20:17
  • 2
    This doesn't work (in FF 50 at least) because changing the "type" attribute triggers a blur. So in your code, the focus changes the type to number, which triggers a blur, which changes the type to text, which triggers another blur - and you can never focus on the element. – Coder Jan 19 '17 at 10:33
  • @Coder It worked in Chrome and Firefox in whatever versions they were at when I wrote it. I guess we keep hunting for a good solution until someone decides to implement a `format` attribute or similar. – Nathan MacInnes Jan 30 '17 at 19:46