i want to get the character typed into an html text input field on keypress
then validate the character entered against a list of characters
and return false if it isn't found in that list
(i don't want to use regular expressions)
by 'list' i mean this:
var acceptable = 'abcd12';
this would prevent, for example, the character 'e' being entered, and so on
the html would look like this:
<input id='someId' type='text' onkeypress='return check(this,event);'>
and the javascript:
function check(element,e) {
var acceptable = 'abcd12';
// now get what character was entered
// if it's in the list, return true
// if it's not in the list, return false
}
Generally, you would want to bind an onChange event handler to the input field like this:
jQuery('#someId').change(function() {
var acceptable = ['1', '2', 'a', 'b', 'y'];
var text = jQuery(this).val();
var allowed = true;
// Loop through each character in the string
var length = text.length;
for (var i = 0; i < length; i++) {
// This if condition is fulfilled if the character
// is not in the array of acceptable characters
if (jQuery.inArray(text[i], acceptable) != -1)
allowed = false;
}
if (allowed)
// The input is valid
else
// The input contains an unallowed character
});
IMPORTANT:
You always have to do server side verification of the data submitted via a form. Anyone can mess with the code in your script and the HTML code. There are many ways to send false data to your server, no matter what you do to prevent it. Therefore it is extremely important to always do server side verification, since the server environment is entirely in your control.
Side note
The onChange event handler only fires when the field loses focus. If this behaviour is undesirable for you, use this:
jQuery('#someId').on('change keypress paste focus textInput input',function(){
// The same code as above can be used here
}
See this link for more information on this.
If you create a variable chr with the character that was entered, then
acceptable.indexOf(chr) !== -1
will be true if the character is acceptable (in the string).
I'll propose a solution without regexes, although I don't understand that constraint.
Here is a logical proposal to validate your strings.
Take your input string, replace occurrences of each of the valid characters in it with '' (empty string), then just verify that the length is 0. If there are characters left (length > 0), validation doesn't pass.
Also note there are other ways of doing this. Modern browsers support the pattern attribute on text inputs, which will validate against a regex (which is trivial to write for this case).
Here is a demo of this in action.
HTML
<input type="text">
JavaScript
input = document.querySelector("input");
restrictChars(input, "abc");
function restrictChars(input, chars) {
input.addEventListener("keypress", function (e) {
e.preventDefault();
var character = String.fromCharCode(e.keyCode);
var isValid = chars.indexOf(character) != -1;
if (isValid) {
input.value += character;
}
});
}
Basically we prevent the default behaviour of the keypress event (to prevent typing) and use it to obtain the pressed key from the event.keyCode. Then, we test to see if that character is present in the chars parameter (without the use of unnecessary regex in my opinion), if it is, we simulate the normal behaviour by adding the character to the <input>'s value, if it's not, we do absolutely nothing, resulting in nothing getting typed.
Hope this helps!
I've made a small jQuery-based solution:
$(document).ready(function() {
$('#input').keypress(function(e) {
var allowed = '02468abc';
var e = e||window.event;
var k = e.keyCode||e.which;
var r = allowed.indexOf(String.fromCharCode(k))!=-1;
r = (k==8||(k>=35&&k<=40)||k==46)?true:r;
if(!r) {
e.returnValue = false;
if(e.preventDefault)
e.preventDefault();
}
});
});
Add the characters you want to pass inside the variable allowed, in this code, allowed characters are 0, 2, 4, 6, 8, a, b, and c.
Just make sure you have this in your HTML:
<input id="input" type="text"/>
You should be good to go using this.
If jQuery is not an option, leave a comment and I'll add some jQuery-less code.
Edit: Changed code to allow use of arrow keys, backspace, home, end, and delete.
Rou's code is clean, but keycode will always return capital letters. If you need this to be case-sensitive, keycode won't work.
I'm also assuming you always want to check the last character entered.
function check(e,element) {
var acceptable = 'abcd12';
var char = element.value.charAt(element.value.length - 1);
if(acceptable.indexOf(char)>=0){
document.getElementById("result").innerHTML="true";
}
else
{
document.getElementById("result").innerHTML="false";
}
}
var inputElement = document.getElementById('someId');
inputElement.addEventListener('keyup', function( e ) {
check( e, inputElement )
});
Here's the code in JSFiddle if you want to modify it: http://jsfiddle.net/hckytaez/4/
Related
I don't want to disable the input box, I'd like to either delete the bad character or allow the user to delete it.
So far I've tried to set the max length of the input to the length where the bad character was entered, but I was still able to type after that.
Here is a sample of the function I'm working on:
function validateCharacterName() {
var value = document.getElementById("characterName").value;
var message = document.getElementById("characterNameMessage");
var button = document.getElementById("confirmButton")
if (value.length <= 1) {
message.innerText = "Name must be two or more characters."
disableButton(button)
} else {
for (var counter = 0 ; counter < value.length; counter++) {
var character = value.charAt(counter);
if (isAlpha(character) && !isDigit(character)) {
message.innerText = "";
enableButton(button);
} else {
message.innerText = "Character '" + character + "' is invalid.";
disableButton(button);
}
}
}
}
The recommended way to ensure the entered text only contains expected characters is using the the pattern attribute. This works slightly different than you suggest, but will be more in line of what the user would expect, as it is a very common way how to do this. Here you can see this in action.
To be specific here is an example how you avoid the letter "a":
<input type="text" pattern="[^a]*" title="Please avoid the letter 'a'">
The pattern attribute uses regular expressions. This does need some getting used to, but is rather powerful. In this case the ^ insider the [] means "not". The a means "a" and the * means allow any number of appearances of the previous thing. In summary this means allow any number of any character not being an "a".
You might want to use a whitelist approach rather than a blacklist approach. For example to allow any Latin letters you could use:
<input type="text" pattern="[a-zA-Z]*" title="Please use letters only">
I have a number of HTML inputs in a website. They are inside a form, but the form is not submitted to the server. Rather, values of the assorted inputs (number inputs, text inputs, and check boxes) are used to ultimately 'stitch together' a product code based on the inputs and selected options. (using JavaScript)
My problem is this: while the number input
<input type='number'/>
only allows a number value when used in a server-side submit, I am using JavaScript to check the assorted values of the different inputs. This allows for a letter (alphabet) character to be put in the number input. IF you do this, the input becomes outlined in red, but it still allows the function that stitches together the product code to be called.
What I need is a way to detect if a given string contains an alphabetical character, instead of just numbers. My idea was something like this:
<input type='number' id='inp' />
<script>
input=document.getElementById('inp');
val=input.value;
checkforletters(val);
input.onchange=function(){
if(checkforletters){
//resetting the value to blank if there is an alphabet character in the string
input.value='';
}
}
</script>
You'll notice that there is a function in there called
checkforletters()
I have not written it. This function would check and see if there is an alphabet character inside the string that comes from the value of my input; and if there is, the function would return true.
This function is what I need. The rest of the code resets the value of the input to blank if there is an alphabet character.
So, to summarize, what I need is a function that, when passed a string as an argument, returns true if there is an alphabet letter in it, and false otherwise.
Note
Please use pure JavaScript only. No jQuery or other libraries/frameworks.
You can use isNaN() function to make your own function that check if the given string is numeric :
//Will return true if the given string is number, false if is contain characters
function isNumeric(yourString){
return !isNaN(yourString)
}
Hope this helps.
My problem is this: while the number input only allows a number value when used in a server-side submit, I am using JavaScript to check the assorted values of the different inputs. This allows for a letter (alphabet) character to be put in the number input. IF you do this, the input becomes outlined in red, but it still allows the function that stitches together the product code to be called.
You can utilize the built in HTML5 constraint validation with JavaScript. This means that instead of having to check whether the value is valid, the value can never be invalid to begin with.
The following example will disallow any invalid input at the user level. It does this by checking the validity then storing the value for future use if it is valid or, if the value is not valid, setting the value to the previously stored valid value if there is one, an empty string if not.
This means that the value can never be invalid.
<input type="number"
oninput="(validity.valid&&(dataset['prev']=value))||(value=dataset['prev'])">
The following is the same method, without using inline JavaScript
document.getElementById('test').oninput = function() {
if(this.validity.valid) this.dataset['prev'] = this.value;
else this.value = this.dataset['prev'];
}
<input type="number" id="test">
So, to summarize, what I need is a function that, when passed a string as an argument, returns true if there is an alphabet letter in it, and false otherwise.
If a number input's value is invalid, it will return an empty string.
This means that you cannot compare the returned value to check it's validity, because if it is in fact invalid the returned value will be an empty string.
The following example shows that even if the value is invalid, checking it with isNaN won't show you that, nor will any of the other methods mentioned here.
<input type="number" oninput="document.getElementById('value').textContent = value; document.getElementById('isnum').textContent = !isNaN(value)"><br>
Returned Value: <span id="value"></span><br>
Is a number: <span id="isnum"></span>
If you really want to validate the input element while running your script, you can check the input element's validity at that time.
var test = document.getElementById('test');
document.getElementById('button').onclick = function(e) {
if(!test.validity.valid) {
alert('Its Invalid!');
} else {
alert('Its valid!');
}
}
<input id="test" type="number"><button id="button">Check It</button>
Alternatively, if your input elements are inside a form and you run your script on the form submission event, it will automatically validate for you, and disallow submission unless the value is valid.
var test = document.getElementById('test');
document.getElementById('form').onsubmit = function(e) {
e.preventDefault();
alert("Its valid!"); // this will only happen if the inputs are valid.
}
<form id="form"><input id="test" type="number"><button>Check It</button></form>
Use a regular expression that matches any non-digits.
var myString = 'aaaaa1';
var reg = new RegExp(/\D+/);
console.log(reg.test(myString));
// true
here is simplest way- handle onkeyup:(http://jsfiddle.net/vittore/g7xe0drp/)
var inp2= document.getElementById('inp2')
inp2.onkeydown = onlyNumbers
function onlyNumbers(e) {
console.log(e)
if (e.which <=49 || e.which >=57) {
e.preventDefault()
return false;
}
}
Check that string contains only numbers (\d):
function checkforletters(val) {
var pattern = /^\d+$/;
return pattern.test(val);
}
If you need other characters beside numbers instead of \d use [\d,-] (, and - are characters that you want to allow).
Please use this to check for alphabets or special characters in your input:
checkforletters(val){
var pattern = /[\D]+/
if (pattern.test(val)) {
// val contains a non-digit character, it contains alphabet or special character
}
else{
// val only contains digits
}
}
pattern.test(val) will only return true if val contains alphabet
You could try this I found on the filter page of developer mozilla org.
function isNumber(obj) {
return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
}
array filter
Of course you will need to rework it a little to make isString(), you could try typeof(obj) === 'string' && isNaN(obj).
you can get a list of obj from a string with theString.split('')
For example:
let s = 'Is this 1 or 2 and not 3 strings? .! : '
let c = s.split('')
let d = c.map((c,i) => {
let v = typeof(c) === 'string' && isNaN(c) ? 'string': 'not-string'
return {c, v}
})
console.log(d)
I'm using the following function to remove non-digit characters from input fields onkeyup (as posted in numerous places). The function works fine for text inputs but when linked to a number input, the number input is completely erased when a non-digit character is typed.
Thoughts?
function RemoveNonNumeric(e)
{
var el = e.target;
el.value = el.value.replace(/\D/g,"");
return;
}//end RemoveNonNumeric
What happens is as soon as there is a non-numeric character in a number input field... the value becomes empty. One way to solve this would be to save the last true numeric value and replace the current value with that if it becomes an empty value. Seems kind of hacky, but see if it works for you:
JSFiddle
var lastNumericValue = 0;
function RemoveNonNumeric(e)
{
if(e.keyCode === 8)
return;
var el = e.target;
if(el.value === "") {
el.value = lastNumericValue;
} else {
lastNumericValue = el.value;
}
}
on second thought... how about preventing the non-numeric values from ever being placed instead of removing them after the fact? Run the following onkeypress
JSFiddle
function RemoveNonNumeric(e) {
if (e.which < 48 || e.which > 57) {
e.preventDefault();
}
};
If you debug, you will find that when the value of a number input is invalid, el.value returns an empty string. I am unaware of a workaround.
This is strange behavior to me but on Webkit browsers (Chrome/Safari, not Firefox) if I include a space in a string of numbers in an <input type=number> then the value of that input is empty.
See this JSFiddle: http://jsfiddle.net/timrpeterson/CZZEX/5/
Here's the code:
<input id='withOutspace' type='number' value='123'>
<input id='with_space' type='number' value='123 123'>
<button>click</button>
$('button').click(function(){
alert("withOut:"+$('#withOutspace').val()+" |||| with:"+$('#with_space').val());
});
If you go to this JSFiddle, you'll notice that the with_space input is empty. But if you put it in it a number that has a space or any non-numeric characters, the alert will say that input is empty.
Obviously, this is a disaster for form validation with credit card numbers, etc. so does anyone have a hack for this?
The hack is to use type="tel" instead of type="number".
This solves the 2 main issues:
It pulls up a number keypad on mobile devices
It validates (and is not empty) with numbers or non-numbers as input.
Please see this JSFiddle: http://jsfiddle.net/timrpeterson/CZZEX/6/
I can suggest two ways.
1. Prevent chars in input
# updated to support more numerical characters related
$(window).keydown(function(e) {
if($('input[type=number]').index($(e.target))!=-1) {
if(
($.inArray(e.keyCode, [48,49,50,51,52,53,54,55,56,57,58,96,97,98,99,100,101,102,103,104,105,8,13,190,189]) == -1) // digits, digits in num pad, 'back', 'enter', '.', '-'
|| (e.keyCode == 190 && $(e.target).val().indexOf(".") != -1) // not allow double dot '.'
|| (e.keyCode == 190 && $(e.target).val().length == 0) // not allow dot '.' at the begining
) {
e.preventDefault();
}
}
});
or 2. Change input's type on fly
$('input[type=number]').focus(function() {
$(this).prop('type', 'text');
});
this allows to put whatever you want and change its type back onblur
$(this).blur(function() {
$(this).prop('type', 'number');
});
But still you cannot store nonnumerical values in input with type=number, so val() will always return you empty string if it meets char or space.
So, at least you have to remove all garbage with .replace(/[^\d]/g, '') - that means "remove all except numbers" before you change type back
In my example I show both methods + clear input values.
A way to control input number is to set it empty on blur when you can't read value
static formattedDecimalInput(input, maxScale, allowEmpty = true) {
input = $(input);
input.on("blur", function(e) {
var inputVal = input.val();
if(inputVal != "" || !allowEmpty) {
if(inputVal == "") {
inputVal = "0";
}
var number = Number(inputVal);
input.val(number.toFixed(maxScale));
} else {
input.val("");
}
});
}
You can formatted it by the way, and if you have invalid char on server side you can send a bad request response.
If you want a requiered field, you can just check if the input is empty with javascript before your server call
It is not really the answer of the initial question but I was looking for a user friendly control for this type of input when I arrived here
My hack for this problem includes the following (i use jQuery validators):
$(document).on('keyup', '[type="number"]', function () {
if (this.validity.badInput) {
$(this).attr('data-badinput', true);
}
});
Later in validator method i do this:
$.validator.addMethod('isInteger', function (value, element, parameterValue) {
if ($(element).attr('data-badinput')) {
//We know nasty browser always clears incorrect input, so empty string will look OK next time
$(element).removeAttr('data-badinput');
return false;
}
return !value || /^-?\d+$/.test(value);
});
You're setting a numeric input field to a string which is not a number. What did you expect to happen? The whole point is that these fields don't allow or accept non-numeric input. They are documented as only accepting a floating point value.
There is no "hack" available or required; the solution is to stop using a number input field for a value that isn't a number. Credit cards, phone numbers, etc; these things are not numbers. They contain digits as a subset of the valid characters, but they also contain completely non-numeric characters like spaces, hyphens and parenthesis. They need to be stored and treated as regular strings.
Use <input type="text"/>.
I have a JavaScript function that validates an input field and prevents the user from typing anything that doesn't match the condition. This function is based on event.keyCode.
I'm trying to modify the function to use a RegExp and validates not "per character" but "per whole input" so that it does the same, but with different conditions:
numeric only
allowed decimal "." or ","
Here is the function in its current form, using event.keyCode:
function isNumeric(evt, alertDIVid, alertMsg) {
var charCode = (evt.which) ? evt.which : event.keyCode
if (charCode >= 48 && charCode <= 57) {
document.getElementById(alertDIVid).innerHTML = '';
return true;
}
else {
document.getElementById(alertDIVid).innerHTML = alertMsg;
return false;
}
}
document.getElementById('AMNT').onkeypress = function(event) {
event = event || window.event;
return isNumeric(event, 'numericalert', 'Numeric values only!')
};
In order to do the kind of validation you want, you need to listen to the keyup event instead. This event fires after the field is changed, so that you know the new value of the field. You also need to know the previous value of the field so you can "reset" it if what the user typed turns out to be invalid.
For example:
(function() {
var previousValue = document.getElementById('myInput').value;
var pattern = /^\d*((\.|,)\d*)?$/;
function validateInput(event) {
event = event || window.event;
var newValue = event.target.value || '';
if (newValue.match(pattern)) {
// Valid input; update previousValue:
previousValue = newValue;
} else {
// Invalid input; reset field value:
event.target.value = previousValue;
}
}
document.getElementById('myInput').onkeyup = validateInput;
}());
Working demo: http://jsfiddle.net/8kUdG/
It's worth noting that this will also validate empty strings, as well as unfinished numbers, like 5, or 42. (otherwise the user would have to insert the decimal sign after typing the decimals, which would be... weird).
And finally, keep in mind that this might not be a cross-browser safe solution. If you need a pure-JavaScript solution, you will need to refine it (i.e., this might not work in IE).
Edit: of course, showing an error message instead of resetting the input field to the previous value is also perfectly possible (updated JSFiddle):
(function() {
var pattern = /^(?=.)\d*(?:[.,]\d+)?$/;
var error = document.getElementById('error');
document.getElementById('myInput').onkeyup = function(event) {
event = event || window.event;
var newValue = event.target.value || '';
if (newValue.match(pattern)) {
error.innerHTML = '';
} else {
error.innerHTML = 'Not a valid number!';
}
};
}());
I leave it up to you to replace the alert with something more user-friendly.
The easiest solution would be something like this
// Returns true on valid, false on invalid
function myInputFilter(input)
{
var value = input.value;
var regex = /^[\d\,\.]*$/;
if(!regex.test(value))
return false;
return true;
}
You could edit the function to just take a string argument, but I've chosen to have it accept the text input element instead. The RegEx can be replaced by anything, I've made a simple one for this example. I would refine it a bit if I were you (You can use the excellent online tool RegExr)
Here is an example of the filter implemented
http://jsfiddle.net/kVV77/
You can use following regular expression:
/^[+-]?(?=.)(?:\d+,)*\d*(?:\.\d+)?$/
to allow only any number of comma and only one dot . with the condition that number cannot start with a comma. Number can have optional + or - at the start.