My Requirement is to validate the ip ranges, I need to create a JavaScript function to accept only numeric and it must allow only between the range 0 to 255. If anything is ente
You can use the following solution to check if the user input for a single integer is between 0 - 255:
document.getElementById('example').addEventListener('input', event => {
const input = event.target.value;
console.log(/^\d+$/.test(input) && input > -1 && input < 256);
});
<input id="example" type="text" placeholder="Enter single integer" />
Alternatively, you can use the code below to verify that each section of an IP address is between 0 - 255:
document.getElementById('example').addEventListener('input', event => {
const input = event.target.value;
console.log(input === new Uint8ClampedArray(input.split('.')).join('.'));
});
<input id="example" type="text" placeholder="Enter IP address" />
I've seen many answers that have overlooked two important factors that may fail to validate range number on keypress:
(input.value * 10) + parseInt(e.key)
and not simply input.value + parseInt(e.key)
. It should be * 10
because you add one more digit at the back during keypress, e.g. 10
becomes 109
.Number.isInteger(parseInt(e.key))
because when 255
is selected, pressing 9
will not turn into 2559
but 9
instead.So first of all, write a simple function that check if the input value is selected by the user:
function isTextSelected (input) {
if (!input instanceof HTMLInputElement) {
throw new Error("Invalid argument type: 'input'. Object type must be HTMLInputElement.");
};
return document.getSelection().toString() != "" && input === document.activeElement;
}
Next, this will be your on keypress event handler that takes into consideration of the above two factors:
$("input[type='number']").on("keypress", function (e) {
if (!Number.isInteger(parseInt(e.key)) || (($(this).val() * 10) + parseInt(e.key) > 255
&& !isTextSelected($(this)[0]))) {
e.preventDefault();
};
});
Take note of this condition within another brackets, it is one whole condition by itself:
(($(this).val() * 10) + parseInt(e.key) > 255 && !isTextSelected($(this)[0]))
For the < 0
condition, you don't even need it here because the negative sign (-)
will be automatically prevented as the sign itself is not an integer.
KNOWN ISSUE: The above solution, however, does not solve the situation when the user move the cursor to the start position of 29
and press 1
, which will become 129
. This is because 29 * 10 = 290
, which already exceed 255
, preventing user from entering 129
, which is valid. The start position is particularly hard to track when the input type="number"
. But it should be enough to resolve the normal way of input for an integer range field. Any other better solutions are welcome.
You need to validate the current value of the input, rather than the last key that was pressed:
<input type='text' id='numonly' onkeypress='allownums(this.value)'>
Your function then just needs to be modified to: if(a < 0 || a > 255)
Currently you have the test
(a < 48) || (a > 57)
for invalid values. So I would change those:
(a < 0 ) || (a > 255)
You may also need to consider what you'll do with non-integral input like 2.3 - either round it or treat it as invalid.
At present, as Kelvin Mackay points out, you are performing the validation on the keypress event rather than the input value, so change the onkeypress to allownums(this.value)
.
I would advise changing the alert to a warning in a div, and using the validation to enable/disable a submit button, as popups are quite annoying in just about every circumstance.
To clear the input when an invalid entry is made (as requested in a comment) would make it rather annoying for the user; as soon as a key is pressed to add a digit and make the input invalid, the whole input is cleared. The code, however, would be:
if(!validnum(this.value))
this.value="";
in the input tag, thus:
<input type='text' id='numonly'
onkeyup='if(!validnum(this.value)) this.value="";'>
with the function changed to:
function validnum(a) {
if(a < 0 || a > 255)
return false;
else
return true;
}
or more succinctly:
function validnum(a) {
return ((a >= 0) && (a <= 255));
}
Edit: To alert and clear the box, if you must:
function validOrPunchTheUser(inputElement) {
if(!validnum(inputElement.value)) {
window.alert('badness'); // punch the user
inputElement.value = ""; // take away their things
}
}
<input type='text' id='numonly'
onkeyup='validOrPunchTheUser(this)'>
However, reading other answers, apparently you are looking to validate an octet (e.g. in an IP address). If so, please state that in the question, as it passed me by today. For an octet:
function validateIPKeyPress(event) {
var key = event.keyCode;
var currentvalue = event.target.value;
if(key < 96 || key > 105)
{
event.preventDefault();
window.alert('pain');
return false;
}
else if(currentvalue.length > 2 ||
(currentvalue.length == 2 &&
key > 101)) {
window.alert('of death');
event.preventDefault();
event.target.value = event.target.value.substring(0,2);
}
else
return true;
}
With the input tag:
<input type='text' id='octet'
onkeydown='validateIPKeyPress(event)'>
Except please don't use alerts. If you take out the alert lines, it will silently prevent invalid inputs. Note the change to use onkeydown now, so that we can catch invalid key presses and prevent the value changing at all. If you must clear the input, then do if(!validateIPKeyPress(event)) this.value = "";
.
Update
I've set up a fiddle that does some basic IP-formatting and checks weather or not all input is in range (0 - 255) etc... feel free to use it, improve it, study it... I've also updated the code snippet here to match the fiddle
There are several things you're not taking into account. First and foremost is that not all browsers have a keycode
property set on the event objects. You're better off passing the entire event object to the function, and deal with X-browser issues there.
Secondly, you're checking key after key, but at no point are you checking the actual value that your input field is getting. There are a few more things, like the use of the onkeypress
html attribute (which I don't really like to see used), and the undefined return value, but that would take us a little too far... here's what I suggest - HTML:
<input type='text' id='numonly' onkeypress='allowNums(event)'>
JS:
function allowNums(e)
{
var key = e.keycode || e.which;//X-browser
var allow = '.0123456789';//string the allowed chars:
var matches,element = e.target || e.srcElement;
if (String.fromCharCode(key).length === 0)
{
return e;
}
if (allow.indexOf(String.fromCharCode(key)) === 0)
{//dot
element.value = element.value.replace(/[0-9]+$/,function(group)
{
return ('000' + group).substr(-3);
});
return e;
}
if (allow.indexOf(String.fromCharCode(key)) > -1)
{
matches = (element.value.replace(/\./g) + String.fromCharCode(key)).match(/[0-9]{1,3}/g);
if (+(matches[matches.length -1]) <= 255)
{
element.value = matches.join('.');
}
}
e.returnValue = false;
e.cancelBubble = true;
if (e.preventDefault)
{
e.preventDefault();
e.stopPropagation();
}
}
Now this code still needs a lot of work, this is just to get you going, and hopefully encourage you to look into the event object, how JS event handlers work and all the rest. BTW, since you're new to JS, this site is worth a bookmark
A function like this should do it:
function allownums(value){
var num = parseInt(value,10);
if(num <0 || num>255)
alert('invalid')
}
Then have your html look like:
<input type='text' id='numonly' onblur='allownums(this.value)'>
Live example: http://jsfiddle.net/USL3E/