Reputation: 342
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.
Upvotes: 7
Views: 19245
Reputation: 438
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 = '';
}
});
Upvotes: 0
Reputation: 29437
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
and truncate decimal values.
Upvotes: 4
Reputation: 2903
As 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.
Upvotes: 9
Reputation: 36940
<input type="number" min="3" max="7" step="0.01"></input>
step
helps restrict the minimum number granularity.
Upvotes: 2