I know that you can use <input type="number">
to restrict a text box to integer only input. However, I was wondering if there is a possibility of range restricting this as well? The limiting factor being without using a javascript function to check it on every keyup
. That seems a little heavy and unnecessary. I would think HTML5 would have something built in to take care of this edge-case, but I haven't been able to find anything.
For example, I have an input box for a deduplication ratio where I want to restrict the user to inputting numbers (integer or float) between 3 and 7.
I have a option-select dropdown currently with whole and half numbers, but this does not provide the level of detail I'm looking for.
I know that you can use <input type="number">
to restrict a text box to integer only input. However, I was wondering if there is a possibility of range restricting this as well? The limiting factor being without using a javascript function to check it on every keyup
. That seems a little heavy and unnecessary. I would think HTML5 would have something built in to take care of this edge-case, but I haven't been able to find anything.
For example, I have an input box for a deduplication ratio where I want to restrict the user to inputting numbers (integer or float) between 3 and 7.
I have a option-select dropdown currently with whole and half numbers, but this does not provide the level of detail I'm looking for.
Share Improve this question edited Jun 19, 2015 at 22:51 99ProblemsAndTheyreAllCode asked Jun 19, 2015 at 22:48 99ProblemsAndTheyreAllCode99ProblemsAndTheyreAllCode 3421 gold badge2 silver badges9 bronze badges 1- You would THINK HTML5 would have something built in... but sadly, I haven't found anything. I believe you'll have to use one of the Javascript libraries out there, or write yourself a quick validation script. I wouldn't necessarily use keyUp... rather onBlur, or a validation before the form is submitted. My two cents. – Charlie74 Commented Jun 19, 2015 at 23:01
4 Answers
Reset to default 9As I mentioned in the comments earlier... there isn't anything that is HTML only here (you'd think there should be). But... since you did include Javascript and jQuery in your question, I'll propose this simple and light solution.
Assuming this HTML...
<form>
<input type="number" min="3" max="7" step="0.5"></input>
</form>
Then we can use this script to handle our requirements.
$( document ).ready(function() {
$('input').change(function() {
var n = $('input').val();
if (n < 3)
$('input').val(3);
if (n > 7)
$('input').val(7);
});
});
Basically, after the change event fires, we do a quick check to make sure the values are within the guidelines, and if not, force them back within range.
Here's a simple solution for checking that an input is an integer number contained in a given range using the HTML5 constraint validation API that is supported by most browsers:
<label for="n">Enter integer number 1≤n≤10</label>
<input type="number" min="1" max="10" step="1" id="n" oninput="(validity.valid)||(value='');">
To validate and auto-correct the input depending on validity states rangeOverflow
, rangeUnderflow
, stepMismatch
:
<label for="numberSize">Enter integral number 1≤n≤10</label>
<input type="number" min="1" max="10" id="numberSize" oninput="(!validity.rangeOverflow||(value=10)) && (!validity.rangeUnderflow||(value=1)) &&
(!validity.stepMismatch||(value=parseInt(this.value)));">
This will send
- all inputs >max to max
- inputs < min to min
and truncate decimal values.
<input type="number" min="3" max="7" step="0.01"></input>
step
helps restrict the minimum number granularity.
The HTML form element for number is in my humble opinion, poorly designed. It only takes integers so if you wanted a zero at the beginning or two zeros (in the case of a 24 hour system) it's impossible. Other drawbacks are no restrictions to the input when typing in the field so you can add letters, symbols etc. or completely ignore any HTML defined number ranges which pretty much defeats the purpose.
On the other hand, the HTML form element for text allows us to restrict the number of characters (maxlength) which I have done in the example below. The JS first restricts the inputs to numbers only and then targets the class names rather than all input elements, so the range can be specified when and where you need it. Rather than set a number if the input is out of the specified range, I opted to delete the field entirely as this will be more obvious to the user that they have made a mistake and less infuriating as it's highly unlikely that setting a specific value will equate to the value that they had in mind.
Used in conjunction with jQuery 3.4.1
JSFiddle link: https://jsfiddle.net/u2smwbgL/1/
HTML
<h1>Set Hours & Minutes</h1>
<div class='left'>
<label> Hours
<input type="text" class='hour' maxlength="2" />
</label>
</div>
<div class='break'></div>
<div class='left'>
<label> Minutes
<input type="text" class='minute' maxlength="2" />
</label>
</div>
Javascript
// Filter Inputs
(function($) {
$.fn.inputFilter = function(inputFilter) {
return this.on("input keydown keyup mousedown mouseup select contextmenu drop",function() {
if (inputFilter(this.value)) {
this.oldValue = this.value;
this.oldSelectionStart = this.selectionStart;
this.oldSelectionEnd = this.selectionEnd;
} else if (this.hasOwnProperty("oldValue")) {
this.value = this.oldValue;
this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
} else {
this.value = "";
}
});
};
}(jQuery));
// Hours & Minutes - Only Numbers
$(".hour,.minute").inputFilter(function(value) {
return /^[0-9]*$/i.test(value);
});
// Hours
$('.hour').on('input', function () {
var value = this.value;
if (value !== '') {
value = parseFloat(value);
if (value > 23)
this.value = '';
}
});
// Minutes
$('.minute').on('input', function () {
var value = this.value;
if (value !== '') {
value = parseFloat(value);
if (value > 59)
this.value = '';
}
});
CSS
.left {position:relative; float:left; width:100%;}
.break {position:relative; float:left; width:100%; height:20px;}
.minute,.hour {position:relative; float:left; width:50px; margin-left:20px; text-align:center;}
$('.minute').on('input', function () {
var value = this.value;
if (value !== '') {
value = parseFloat(value);
if (value > 59)
this.value = '';
}
});