Reputation: 12027
I have a simple input field with type set to number. This will be used to enter input in [0,255] range (for RGB).
<input type="number" id="inputBox" min="0" max="255" step="1" />
In its current form, this input field will accept the following values:
012 // zero prefixed numbers
1.0 // floating-point
.1 // floating-point
-5 // range underflow
300 // range overflow
I want it to accept only the integers in the range of [0,255]. So, no zero prefix, no floating-point numbers.
I've solved the range problem using input
event:
inputBox.addEventListener("input", function () {
if (this.validity.rangeUnderflow) {
this.value = this.min;
}
else if (this.validity.rangeOverflow) {
this.value = this.max;
}
});
and floating-point problem using keydown
event (by not allowing .
):
inputBox.addEventListener("keydown", function (e) {
if (!isFloat(this.step)) {
if (e.key == ".") {
e.preventDefault();
}
}
});
function isFloat(f) {
var f = parseFloat(f);
var floor = Math.floor(f);
var fraction = f - floor;
if (fraction > 0) {
return true;
}
return false;
}
I'm stuck at solving the zero prefixed numbers problem. I can use the following line of code in the input
event to remove zero prefix
this.value = this.valueAsNumber; // or parseInt(this.value, 10)
which is working fine, but this kind of breaks the input field's functionality. I can't enter values with E
notation. In my case, I don't need to, but I might somewhere else. As soon as I enter 1e
, it evaluates to NaN
, and is assigned back to input field.
Is there a way to make these both work?
Upvotes: 2
Views: 2129
Reputation: 62466
You can use a regular expression such as:
<input type="text" pattern="0|[1-9]\d*">
this will gives you a string representation of a positive whole number without prefixed zeros. You then have to test with JavaScript if the value is less than or equals 255.
Here is a JSFiddle. String with only multiple zeros are not accepted.
Upvotes: 1
Reputation: 654
I just worked on a problem like this. It's super easy to do:
inputBox.addEventListener("keydown", function (e) {
if (!isFloat(this.step)) {
if (e.key == ".") {
e.preventDefault();
}
}
while ( this.value.toString()[0] === "0" && this.value.length > 0){
this.value = this.value.toString().slice(1);
}
});
Note that the value of the field might change in ways other than keydown
events, suck as paste
. So I would put these checks in a function, validationCheck
, and run that function for each relevant event, including the catchall- onchange
.
Upvotes: 1