Greetings all. I have the following function to validate input depending if is numeric, alpha, alphanumeric and email:
function permite(e, permitidos) {
var key = e.keyCode || e.which;
//Validate if its an arrow or delete button
if((key == 46) || (key == 8) || (key >= 37 && key <= 40))
return true;
var keychar = String.fromCharCode(key);
switch(permitidos) {
case 'num':
permitidos = /^[0-9]$/;
break;
case 'car':
permitidos = /^[\sa-zA-Z]$/;
break;
case 'num_car':
permitidos = /^[\sa-zA-Z0-9]$/;
break;
case 'correo':
permitidos = /^[a-zA-Z0-9._\-+#]$/;
break;
}
return permitidos.test(keychar);
}
The var names are in spanish but its an easy function to understand.
The problem is the following. The keycode for '%' is 37 the same than the left arrow and the keycode for '(' is 40 the same than the right arrow. So my function is not validating '%' and '(' and it sucks. I dont know what to do, please help.
The keypress event doesn't fire for arrow and delete keys, so you can just remove your if statement. Darn you FireFox!
You are mixing up keyCode and charCode, which is understandable because event.keyCode actually contains charCode for keyPress events, unlike keydown and keyup. The keyCode for ( is 57 (same as for 9 - those characters are on the same key). Its charCode is 40. Arrow keys don't have charCodes, so they don't fire keypress events. (Except in FireFox... Argh!)
Your best bet is to use the keydown event and look for keyCode rather than charCode, checking for shift keys when necessary. You'll have to manually map keyCodes to characters when the shift key is pressed.
Slightly OT (apologies) but you may want to look at one of the Javascript libraries out there, for example JQuery; almost all of them come with (or have) libraries for "validating input".
For example: if you were using JQuery you may consider the "Validation" plugin - http://bassistance.de/jquery-plugins/jquery-plugin-validation/
Check for whether the shift key is being pressed as well by checking event.shiftKey:
//Validate if its an arrow or delete button
if((key == 46) || (key == 8) || (key >= 37 && key <= 40 && !e.shiftKey))
return true;
Another option (depending on your application) is to handle the keydown event instead of the keypress event, which won't result in overlapping key codes.
Related
At the moment, I have an input. I am allowed to enter any characters, even special characters, no digits.
What I've tried so far is to setup a keydown and a keyup event.
ng-keydown="vm.preventNumberInput($event)"
ng-onkeyup="vm.preventNumberInput($event)"
vm.preventNumberInput = function (e) {
var keyCode = (e.keyCode ? e.keyCode : e.which);
if (keyCode > 47 && keyCode < 58 || keyCode > 95 && keyCode < 107) {
e.preventDefault();
}
}
This works okay, but it prevents me from adding special characters like !##%^&*.
May I ask how do I allow characters from being entered into my input that aren't digits.
Check the event's key property to get the pressed key. If it matches \d (a digit), call preventDefault:
vm.preventNumberInput = function (e) {
if (/\d/.test(e.key)) {
e.preventDefault();
}
}
Any characters other than digits will be allowed.
(note that the keyCode and which properties are deprecated, and should be avoided when possible)
I'm trying to get a response for when visitor uses the keys right and left
<script>
$(document).keypress(function(event) {
key = String.fromCharCode(event.which)
if(key == '37' || key == '39') {
$('main').html('You pressed : ' + key)
event.preventDefault()
}
});
</script>
It's not working. what did work was the line
if(key == 'a')
I used this table to find the code https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
Is it because jQuery has different table? or maybe I should load JavaScript as well? then how do I do use the two of them? (jQuery and JavaScript?)?
EDIT:
I think I got it
String.fromCharCode(event.which)
JavaScript can't read strings as numbers? do I need to use different function? I'm new to this can you tell me what to do?
I find for myself that when I go to implement these sorts of "get item from event", that a simple console.log(event) does wonders. I'd start with:
$('body').on('keypress', function(evt){
console.log('Event: ', evt);
});
Then, press the right and left arrow keys and see what happens.
First, an observation: I note that you're comparing the string '37', which is distinct from the integer value 37. The former is two or four bytes (depending on how the JS implementation stores characters), while the latter is one byte. Is that your intention after reading the appropriate APIs?
Second, as a specific suggestion, if you're using jQuery, take advantage of it's normalization routines. In this case, event.which is returning 0, but you can use event.keyCode which is probably what you want to compare:
if ( 37 === event.keyCode ) {
// ...
}
else if ( 39 === event.keyCode ) {
// ....
}
What you want to use is the keydown event. Also, no reason to use the String.fromCharCode, you can just compare the integers. Something like this would work
$(document).keydown(function(event) {
if (event.which == 37 || event.which == 39) {
var key = event.which == 37 ? 'left' : 'right';
$('main').html('You pressed : ' + key)
event.preventDefault()
}
})
In Javascript, I have callback function for keydown event. I use keyCode and which properties to detect which keys user pressed.
var keyPressed = event.keyCode || event.which;
if (keyPressed > 47 && keyPressed < 58) {
//do something
}
It works well. However, this properties are deprecated, I switch to key property. When I replace code, it does not work correctly.
if (event.key > 47 && event.key < 58) {
//do something
}
I can't check user's pressed key in range.
For printable characters, .key() returns a non-empty Unicode character string containing the printable representation of the key.
Essentially: for ASCII characters, you get the character itself rather than its ASCII code.
So, for digits you could just do:
var myInput = document.getElementsByTagName('input')[0];
myInput.addEventListener("keydown", function(event) {
if(event.key >= "0" && event.key <= "9") {
console.log('digit: ' + event.key);
}
});
<input>
For letters, you'll also have to check that .key() returns a single character because a non-printable key such as delete will be encoded as "Delete", which would pass the test "Delete" >= "A" && "Delete" <= "Z".
var myInput = document.getElementsByTagName('input')[0];
myInput.addEventListener("keydown", function(event) {
if(event.key.length == 1 && event.key >= "A" && event.key <= "Z") {
console.log('capital letter: ' + event.key);
}
});
<input>
According to
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
"The KeyboardEvent.key read-only property returns the value of a key or keys pressed by the user."
The values that get returned are strings. You would probably have to remain using key.code if you want to check range.
Alternatively you could use switch statements like in the example on mdn
switch (event.key) {
case "ArrowDown":
// Do something for "down arrow" key press.
break;
case "ArrowUp":
// Do something for "up arrow" key press.
break;
case "ArrowLeft":
// Do something for "left arrow" key press.
break;
case "ArrowRight":
// Do something for "right arrow" key press.
break;
case "Enter":
// Do something for "enter" or "return" key press.
break;
case "Escape":
// Do something for "esc" key press.
break;
default:
return; // Quit when this doesn't handle the key event.
}
Or event still make an array like
var validKeys = ["ArrowDown", "ArrowUp", ...]
and then check to see if the event.key is in the array.
Finally you could use regular expressions
This should work
<script type="text/javascript">
document.addEventListener('keydown', function(event){
var charTyped = event.key;
if (/^[a-z\d]$/i.test(charTyped)) {
console.log("Letter or number typed: " + charTyped);
}
})
</script>
I am trying to create a directive that only accepts characters input in textbox which is A-Z and a-z. This is my directive:
angApp.directive('onlyCharacters', function () {
return {
link: function (scope, elem, attrs) {
$(elem).keydown(function (e) {
if (!((e.keyCode >= 65 && e.keyCode <= 90) ||
e.keyCode == 8 || e.keyCode == 37 || e.keyCode == 39 || e.keyCode == 9)
) {
e.preventDefault();
}
});
}
}
});
This even works for small a-z. I am wondering how does that. Isn't ascii keys for lowercase A-Z is 97-122? However the above directive works for upper as well as lower case.
Please suggest how does the above code work for lower case?
The short answer is that keyup and keydown are used to identify the physical keys pressed not the value which those keys correspond to. Compare the codes to the ones you get from the keypress event.
You'll see that you are correct with regard to the key ranges in keypress but both a and A are achieved by hitting the same physical key => same key code in keyup and keydown.
I wrote the following code (using jQuery) to show the pressed key.
$(window).keydown(function(e){
$("div").text("Key:" + String.fromCharCode(e.keyCode).toLowerCase());
return false;
});
This code works in normal alphabet characters (q,w,e,r...).
But when I press non alphabet keys (like ']'), an incorrect character is shown.
ex: ',' -> ¼, ']' -> ý
What's wrong with my code?
Use the keypress event and e.which property.
jQuery normalizes the keycodes, and stores the variable in event.which. The keypress event's which property is the only reliable value for String.fromCharCode.
The event.keyCode property may not be equal to the event.charCode or event.which properties.
For non-printable characters, event.which has a value of zero, contrary to event.keyCode. That's why you're seeing weird characters.
$(window).keypress(function(e) {
var charCode = e.which;
if (!charCode) { // <-- charCode === 0
return;// return false, optionally
}
$("div").text("Key:" + String.fromCharCode(charCode).toLowerCase());
return false; // Or e.preventDefault(); and/or e.stopPropagation()
}).keyup(function(e) {
// Key is lifted, do something
});