Restrict to 2 decimal places in keypress of a text box?
Consider leveraging HTML5's Constraint Validation API. It doesn't necessarily prevent typing invalid values, but the field is marked invalid and it halts submission of the <form>
(by default). I added the <output>
to illustrate why the browser considers e.g. "1.100" a valid value (it sees the numeric value as "1.1").
<input id="n" type="number" step=".01">
var
n = document.getElementById('n'),
o = document.getElementById('o'),
didInputN = function(e) {
o.value = n.valueAsNumber;
};
n.addEventListener('input', didInputN);
input:invalid {
color: white;
background-color: red;
}
<input id="n" type="number" step=".01">
<output id="o" for="n"></output>
Philosophically, you might consider this a more usable approach as it allows the user to paste an invalid entry and edit it directly in the field.
You were almost there. Just check that there are no more than 2 characters after the decimal.
UPDATE 1 - check carat position to allow character insertion before the decimal.
UPDATE 2 - correct issue pointed out by ddlab's comment and only allow one dot.
function validateFloatKeyPress(el, evt) {
var charCode = (evt.which) ? evt.which : event.keyCode;
var number = el.value.split('.');
if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
//just one dot (thanks ddlab)
if(number.length>1 && charCode == 46){
return false;
}
//get the carat position
var caratPos = getSelectionStart(el);
var dotPos = el.value.indexOf(".");
if( caratPos > dotPos && dotPos>-1 && (number[1].length > 1)){
return false;
}
return true;
}
//thanks: http://javascript.nwbox.com/cursor_position/
function getSelectionStart(o) {
if (o.createTextRange) {
var r = document.selection.createRange().duplicate()
r.moveEnd('character', o.value.length)
if (r.text == '') return o.value.length
return o.value.lastIndexOf(r.text)
} else return o.selectionStart
}
http://jsfiddle.net/S9G8C/1/
http://jsfiddle.net/S9G8C/203/
You can do it by another way with onchange event, to not restrict to user to type, rather just convert number after typing, to make uniform, like this,
function validateFloatKeyPress(el) {
var v = parseFloat(el.value);
el.value = (isNaN(v)) ? '' : v.toFixed(2);
}
<input id="aninput" type="text" onchange="validateFloatKeyPress(this);" />
45.846
should be 45.85
but in your code user needed to convert their-self and then they will type 45.85
directly