Combination Keydown function not working for Mac Keyboard - javascript

I'm trying to show the Searchbar on my application using keyboard shortcuts.
While the keyboard shortcuts work perfectly using a Windows keyboard, the code fails when I'm using a Mac machine with a Mac keyboard.
Following is the function which I've written -
var osName = "Unknown OS";
if (navigator.appVersion.indexOf("Win") != -1) osName = "Windows";
if (navigator.appVersion.indexOf("Mac") != -1) osName = "MacOS";
function showSearchBarOnKeyPress() {
$(document).keydown(function (e) {
if ((e.ctrlKey && e.altKey && e.key === "z") || (osName === "MacOS" && e.keyCode === 90 && e.keyCode === 17 && e.keyCode === 91)) {
searchBarIsShown();
}
});
}
Initially I didn't have the '||' condition in the 'If' statement. The first condition works when using a Windows keyboard. When I checked on a Mac it didn't work. So I had to put in the '||' condition.
For the MacOS condition initially I had used keycodes - 59,55 and 6 as shown in this reference -
https://eastmanreference.com/complete-list-of-applescript-key-codes
On checking in the Mac machine, the keycodes detected were - 90,91 and 17 which I then replaced.
But it still doesn't work.
Can someone please provide their insights/thoughts on this issue?
Thanks

try this:
metaKey is cmd key on mac. altKey is the option key on mac.
var osName = "Unknown OS";
if (navigator.appVersion.indexOf("Win") != -1) osName = "Windows";
if (navigator.appVersion.indexOf("Mac") != -1) osName = "MacOS";
function showSearchBarOnKeyPress() {
$(document).keydown(function (e) {
var modifier = (navigator.appVersion.indexOf("Mac") != -1) ? e.ctrlKey : e.metaKey;
if (modifier && e.altKey && e.key === "z") {
searchBarIsShown();
}
});
}
note that metaKey is not supported on old browseres..

e.ctrlKey and e.altKey are special properties on the KeyboardEvent object that contain the state of these buttons.
e.keyCode === 90 && e.keyCode === 17 && e.keyCode === 91
the property e.keyCode can not be three differrent values at once.
I have little experience with apple but I assume you'd have to manually keep track of the state of these buttons.
a simple statemanager would be:
const keyDown = Object.create(null);
$(document).on("keydown keyup", e => keyDown[e.keyCode] = e.type === "keydown");
so now you can check all three Buttons at once:
keyDown[90] && keyDown[17] && keyDown[91]

Related

allow backspace in regex [duplicate]

Using <input type=number> will cause this.value inside of an event listener to return an empty string if the input is not a valid number. You can see an example of this at http://jsfiddle.net/fSy53/
However, the invalid characters are still displayed in the input.
Is there any way to get the value that is actually displayed, including the invalid characters, from within an event listener?
My ultimate goal is to prevent users from actually typing any non-numeric characters into the field. I need to use type=number so that the numeric virtual keyboard is used by mobile devices. My goal would be to do something like this.value = this.value.replace(/[^0-9.]/g, "") on keyup keypress, but this doesn't work because if an invalid character is typed, reading from this.value returns "".
Try preventing the default behaviour if you don't like the incoming key value:
document.querySelector("input").addEventListener("keypress", function (evt) {
if (evt.which < 48 || evt.which > 57)
{
evt.preventDefault();
}
});
You can accomplish this by preventing the keyPress event from occurring for non-numeric values
e.g (using jQuery)
$('.input-selector').on('keypress', function(e){
return e.metaKey || // cmd/ctrl
e.which <= 0 || // arrow keys
e.which == 8 || // delete key
/[0-9]/.test(String.fromCharCode(e.which)); // numbers
})
This accounts for all different types of input (e.g. input from the number pad has different codes than the keyboard) as well as backspace, arrow keys, control/cmd + r to reload etc
Please note that e.which, e.keyCode and e.charCode are deprecated: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which
I prefer e.key:
document.querySelector("input").addEventListener("keypress", function (e) {
var allowedChars = '0123456789.';
function contains(stringValue, charValue) {
return stringValue.indexOf(charValue) > -1;
}
var invalidKey = e.key.length === 1 && !contains(allowedChars, e.key)
|| e.key === '.' && contains(e.target.value, '.');
invalidKey && e.preventDefault();});
This function doesn't interfere with control codes in Firefox (Backspace, Tab, etc) by checking the string length: e.key.length === 1.
It also prevents duplicate dots at the beginning and between the digits: e.key === '.' && contains(e.target.value, '.')
Unfortunately, it doesn't prevent multiple dots at the end: 234....
It seems there is no way to cope with it.
The other answers seemed more complicated than necessary so I adapted their answers to this short and sweet function.
function allowOnlyNumbers(event) {
if (event.key.length === 1 && /\D/.test(event.key)) {
event.preventDefault();
}
}
It won't do change the behavior of any arrow, enter, shift, ctrl or tab keys because the length of the key property for those events is longer than a single character. It also uses a simple regular expressions to look for any non digit character.
inputs[5].addEventListener('keydown', enterNumbers);
function enterNumbers(event) {
if ((event.code == 'ArrowLeft') || (event.code == 'ArrowRight') ||
(event.code == 'ArrowUp') || (event.code == 'ArrowDown') ||
(event.code == 'Delete') || (event.code == 'Backspace')) {
return;
} else if (event.key.search(/\d/) == -1) {
event.preventDefault();
}
}
in this case, the value of the input field stays intact when a non-number button is pressed, and still delete, backspace, arrowup-down-left-right work properly and can be used for modifying the digital input.
This solution seems to be working well for me. It builds on #pavok's solution by preserving ctrl key commands.
document.querySelector("input").addEventListener("keypress", function (e) {
if (
e.key.length === 1 && e.key !== '.' && isNaN(e.key) && !e.ctrlKey ||
e.key === '.' && e.target.value.toString().indexOf('.') > -1
) {
e.preventDefault();
}
});
I will add MetaKey as well, as I am using MacOS
input.addEventListener("keypress", (e) => {
const key = e.key;
if (!(e.metaKey || e.ctrlKey) && key.length === 1 && !/\d\./.test(key)) {
e.preventDefault();
}
}
Or, you can try !isNaN(parseFloat(key))
try this one :
current key pressed -> e
if e is not a number -> isNaN(e.key)
when condition is true , so default action should not be taken as it normally would be -> e.preventDefault()
else, return default action... e
input.addEventListener("keypress", function (e) {
if (isNaN(e.key)) e.preventDefault();
});
Update on the accepted answer:
Because of many properties becoming deprecated
(property) KeyboardEvent.which: number #deprecated
you should just rely on the key property and create the rest of the logic by yourself:
The code allows Enter, Backspace and all numbers [0-9], every other character is disallowed.
document.querySelector("input").addEventListener("keypress", ({ key, preventDefault }) => {
if (isNaN(parseInt(key, 10)) && !['Backspace', 'Enter'].includes(key)) {
preventDefault();
}
});
NOTE
This will disable paste action
Based on Nrzonline's answer: I fixed the problem of the multiple "." at the end of the input by adding a
let lastCharacterEntered
outside of the input and then onKeyPress
e => {
var allowedChars = "0123456789.";
function contains(stringValue, charValue) {
return stringValue.indexOf(charValue) > -1;
}
var invalidKey =
(e.key.length === 1 && !contains(allowedChars, e.key)) ||
(e.key === "." && contains(e.target.value, "."));
console.log(e.target.value);
invalidKey && e.preventDefault();
if (!invalidKey) {
if (lastCharacterEntered === "." && e.key === ".") {
e.preventDefault();
} else {
lastCharacterEntered = e.key;
}
}
}
I just had the same problem and discovered an alternative solution using the validation API - works without black magic in all major browsers (Chrome, Firefox, Safari) except IE. This solution simply prevents users from entering invalid values.
I also included a fallback for IE, which is not nice but works at least.
Context: onInput function is called on input events, setInputValue is used to set the value of the input element, previousInputValue contains the last valid input value (updated in setInputValue calls).
function onInput (event) {
const inputValue = event.target.value;
// badInput supported on validation api (except IE)
// in IE it will be undefined, so we need strict value check
const badInput = event.target.validity.badInput;
// simply prevent modifying the value
if (badInput === true) {
// it's still possible to enter invalid values in an empty input, so we'll need this trick to prevent that
if (previousInputValue === '') {
setInputValue(' ');
setTimeout(() => {
setInputValue('');
}, 1);
}
return;
}
if (badInput === false) {
setInputValue(inputValue);
return;
}
// fallback case for IE and other abominations
// remove everything from the string expect numbers, point and comma
// replace comma with points (parseFloat works only with points)
let stringVal = String(inputValue)
.replace(/([^0-9.,])/g, '')
.replace(/,/g, '.');
// remove all but first point
const pointIndex = stringVal.indexOf('.');
if (pointIndex !== -1) {
const pointAndBefore = stringVal.substring(0, pointIndex + 1);
const afterPoint = stringVal.substring(pointIndex + 1);
// removing all points after the first
stringVal = `${pointAndBefore}${afterPoint.replace(/\./g, '')}`;
}
const float = parseFloat(stringVal);
if (isNaN(float)) {
// fallback to emptying the input if anything goes south
setInputValue('');
return;
}
setInputValue(stringVal);
}
Prevent typing non-Alphabet in specific input id for pages that have more than one input item.it's usable for Oracle Apex developers
--- Append in HTML header of page
<script type="text/javascript">
function validateNumber(event) {
const activeElmnt = document.activeElement;
var keyCode = event.keyCode;
var excludedKeys = [8, 37, 39, 46];
if ( activeElmnt.id == "input id in HTML page"){
if (!((keyCode >= 65 && keyCode <= 90) ||
(keyCode >= 97 && keyCode <= 122) ||
(excludedKeys.includes(keyCode)))) {
console.log("alphabets are not allowed");
event.preventDefault();
}
}
console.log("keycode: " + keyCode + "ActiveElemet: "+activeElmnt.id);
}
</script>
-- Append in page HTML Body attribute
onkeydown="validateNumber(event);"
here is my simple solution simply
in this solution u should keep the input type to text so when you use event.target.value you get the full string not only the numbers or an empty string instead so you actually can check if there is a point yet or not.
and i didn't use the deprecated properties event.which
isNumber(event) {
var allowed = "";
if (event.target.value.includes(".")) {
allowed = "123456789";
} else {
allowed = "123456789.";
}
if (!allowed.includes(event.key)) {
event.preventDefault();
}
}
document.getElementById('number').addEventListener('keypress', isNumber);
the HTML
```
function isNumber(event) {
var allowed = "";
if (event.target.value.includes(".")) {
allowed = "0123456789";
} else {
allowed = "0123456789.";
}
if (!allowed.includes(event.key)) {
event.preventDefault();
}
}
document.getElementById('number').addEventListener('keypress',isNumber);
<h3>You can input only numbers and one point (this would be a float or int) </h3>
<input type="text" id="number" />
This one should work. Only works with integers.
function validateNumberInput(e) {
if (isNaN(e.key)) {
e.preventDefault();
}
}
You can however implement floats with few more lines:
function validateNumberInput(e) {
if (isNaN(e.key) && e.key !== '.') {
e.preventDefault();
} else if (e.key === '.') {
if (e.target.value.indexOf('.') >= 0) {
e.preventDefault();
}
}
}
Finally use it like:
targetInput.addEventListener('keypress', function (e) {
validateNumberInput(e);
});
A very nice react solution... You just want to consume the event if its NaN
onKeyedPress = (e) => {
if(!parseInt(e.key)){
e.preventDefault();
}
}
Try it:
document.querySelector("input").addEventListener("keyup", function () {
this.value = this.value.replace(/\D/, "")
});

JavaScript, HTML: How can I disable the Shift Key (specially when combined with other keys to create special characters)?

https://ysuran92.github.io/calculator-project/index
I have a calculator project, or something like that. It's made in HTML, CSS and JavaScript.
Now, in my JS file there is some code to prevent characters like letters from showing up in the calculator's display. The only thing I can't get my head around is how to "disable" Shift+(0-9).
Here is some code:
// let regEx = /^\s*([-+]?)(\d+)(?:\s*([-+*\/])\s*((?:\s[-+])?\d+)\s*)+$/;
document.addEventListener("keydown", (event) => {
if (event.keyCode == 13 || event.code == "NumpadEnter") {
calc.value = eval(calc.value);
} else if (event.keyCode == 46) {
calc.value = "";
} else if (event.keyCode == 8) {
back();
} else if (event.keyCode >= 48 && event.keyCode <= 57) {
calc.value += event.key;
} else if (event.keyCode >= 96 && event.keyCode <= 105) {
calc.value += event.key;
} else if (
event.keyCode == 107 ||
event.keyCode == 109 ||
event.keyCode == 106 ||
event.keyCode == 111 ||
event.keyCode == 190 ||
event.keyCode == 110
) {
calc.value += event.key;
}
});
As you may notice, I've already tried RegEx (which didn't work, probably because I don't know anything about it) and I've also tried event.preventDefault().
Any tips or comments will be appreciated. Thanks in advance.
The idea behind the recommendation that was given to you to use a regexp is to actually test event.key instead of event.keyCode.
You don't have to test for the keyboard key that was pressed, but simply which value you're going to add into your string. This is better, because this is not dependent on the keyboard of the user.
Here is a naive way of doing that:
if (['0', '1', '2', '3', '5', '6', '7', '8', '9'].includes(e.key)) {
console.log('I am a number');
}
Regexps are more complex, but allow you to write this is a way more condensed form:
if (e.key.match(/[0-9]/)) {
console.log('I am a number');
}
The regexp you have doesn't only allow numbers though.
It can be used to validate that a given expression is correct, e.g. 1 * 2 / -3. This regex101 could help you understand it a bit more.

Prevent typing non-numeric in input type number

Using <input type=number> will cause this.value inside of an event listener to return an empty string if the input is not a valid number. You can see an example of this at http://jsfiddle.net/fSy53/
However, the invalid characters are still displayed in the input.
Is there any way to get the value that is actually displayed, including the invalid characters, from within an event listener?
My ultimate goal is to prevent users from actually typing any non-numeric characters into the field. I need to use type=number so that the numeric virtual keyboard is used by mobile devices. My goal would be to do something like this.value = this.value.replace(/[^0-9.]/g, "") on keyup keypress, but this doesn't work because if an invalid character is typed, reading from this.value returns "".
Try preventing the default behaviour if you don't like the incoming key value:
document.querySelector("input").addEventListener("keypress", function (evt) {
if (evt.which < 48 || evt.which > 57)
{
evt.preventDefault();
}
});
You can accomplish this by preventing the keyPress event from occurring for non-numeric values
e.g (using jQuery)
$('.input-selector').on('keypress', function(e){
return e.metaKey || // cmd/ctrl
e.which <= 0 || // arrow keys
e.which == 8 || // delete key
/[0-9]/.test(String.fromCharCode(e.which)); // numbers
})
This accounts for all different types of input (e.g. input from the number pad has different codes than the keyboard) as well as backspace, arrow keys, control/cmd + r to reload etc
Please note that e.which, e.keyCode and e.charCode are deprecated: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which
I prefer e.key:
document.querySelector("input").addEventListener("keypress", function (e) {
var allowedChars = '0123456789.';
function contains(stringValue, charValue) {
return stringValue.indexOf(charValue) > -1;
}
var invalidKey = e.key.length === 1 && !contains(allowedChars, e.key)
|| e.key === '.' && contains(e.target.value, '.');
invalidKey && e.preventDefault();});
This function doesn't interfere with control codes in Firefox (Backspace, Tab, etc) by checking the string length: e.key.length === 1.
It also prevents duplicate dots at the beginning and between the digits: e.key === '.' && contains(e.target.value, '.')
Unfortunately, it doesn't prevent multiple dots at the end: 234....
It seems there is no way to cope with it.
The other answers seemed more complicated than necessary so I adapted their answers to this short and sweet function.
function allowOnlyNumbers(event) {
if (event.key.length === 1 && /\D/.test(event.key)) {
event.preventDefault();
}
}
It won't do change the behavior of any arrow, enter, shift, ctrl or tab keys because the length of the key property for those events is longer than a single character. It also uses a simple regular expressions to look for any non digit character.
inputs[5].addEventListener('keydown', enterNumbers);
function enterNumbers(event) {
if ((event.code == 'ArrowLeft') || (event.code == 'ArrowRight') ||
(event.code == 'ArrowUp') || (event.code == 'ArrowDown') ||
(event.code == 'Delete') || (event.code == 'Backspace')) {
return;
} else if (event.key.search(/\d/) == -1) {
event.preventDefault();
}
}
in this case, the value of the input field stays intact when a non-number button is pressed, and still delete, backspace, arrowup-down-left-right work properly and can be used for modifying the digital input.
This solution seems to be working well for me. It builds on #pavok's solution by preserving ctrl key commands.
document.querySelector("input").addEventListener("keypress", function (e) {
if (
e.key.length === 1 && e.key !== '.' && isNaN(e.key) && !e.ctrlKey ||
e.key === '.' && e.target.value.toString().indexOf('.') > -1
) {
e.preventDefault();
}
});
I will add MetaKey as well, as I am using MacOS
input.addEventListener("keypress", (e) => {
const key = e.key;
if (!(e.metaKey || e.ctrlKey) && key.length === 1 && !/\d\./.test(key)) {
e.preventDefault();
}
}
Or, you can try !isNaN(parseFloat(key))
try this one :
current key pressed -> e
if e is not a number -> isNaN(e.key)
when condition is true , so default action should not be taken as it normally would be -> e.preventDefault()
else, return default action... e
input.addEventListener("keypress", function (e) {
if (isNaN(e.key)) e.preventDefault();
});
Update on the accepted answer:
Because of many properties becoming deprecated
(property) KeyboardEvent.which: number #deprecated
you should just rely on the key property and create the rest of the logic by yourself:
The code allows Enter, Backspace and all numbers [0-9], every other character is disallowed.
document.querySelector("input").addEventListener("keypress", ({ key, preventDefault }) => {
if (isNaN(parseInt(key, 10)) && !['Backspace', 'Enter'].includes(key)) {
preventDefault();
}
});
NOTE
This will disable paste action
Based on Nrzonline's answer: I fixed the problem of the multiple "." at the end of the input by adding a
let lastCharacterEntered
outside of the input and then onKeyPress
e => {
var allowedChars = "0123456789.";
function contains(stringValue, charValue) {
return stringValue.indexOf(charValue) > -1;
}
var invalidKey =
(e.key.length === 1 && !contains(allowedChars, e.key)) ||
(e.key === "." && contains(e.target.value, "."));
console.log(e.target.value);
invalidKey && e.preventDefault();
if (!invalidKey) {
if (lastCharacterEntered === "." && e.key === ".") {
e.preventDefault();
} else {
lastCharacterEntered = e.key;
}
}
}
I just had the same problem and discovered an alternative solution using the validation API - works without black magic in all major browsers (Chrome, Firefox, Safari) except IE. This solution simply prevents users from entering invalid values.
I also included a fallback for IE, which is not nice but works at least.
Context: onInput function is called on input events, setInputValue is used to set the value of the input element, previousInputValue contains the last valid input value (updated in setInputValue calls).
function onInput (event) {
const inputValue = event.target.value;
// badInput supported on validation api (except IE)
// in IE it will be undefined, so we need strict value check
const badInput = event.target.validity.badInput;
// simply prevent modifying the value
if (badInput === true) {
// it's still possible to enter invalid values in an empty input, so we'll need this trick to prevent that
if (previousInputValue === '') {
setInputValue(' ');
setTimeout(() => {
setInputValue('');
}, 1);
}
return;
}
if (badInput === false) {
setInputValue(inputValue);
return;
}
// fallback case for IE and other abominations
// remove everything from the string expect numbers, point and comma
// replace comma with points (parseFloat works only with points)
let stringVal = String(inputValue)
.replace(/([^0-9.,])/g, '')
.replace(/,/g, '.');
// remove all but first point
const pointIndex = stringVal.indexOf('.');
if (pointIndex !== -1) {
const pointAndBefore = stringVal.substring(0, pointIndex + 1);
const afterPoint = stringVal.substring(pointIndex + 1);
// removing all points after the first
stringVal = `${pointAndBefore}${afterPoint.replace(/\./g, '')}`;
}
const float = parseFloat(stringVal);
if (isNaN(float)) {
// fallback to emptying the input if anything goes south
setInputValue('');
return;
}
setInputValue(stringVal);
}
Prevent typing non-Alphabet in specific input id for pages that have more than one input item.it's usable for Oracle Apex developers
--- Append in HTML header of page
<script type="text/javascript">
function validateNumber(event) {
const activeElmnt = document.activeElement;
var keyCode = event.keyCode;
var excludedKeys = [8, 37, 39, 46];
if ( activeElmnt.id == "input id in HTML page"){
if (!((keyCode >= 65 && keyCode <= 90) ||
(keyCode >= 97 && keyCode <= 122) ||
(excludedKeys.includes(keyCode)))) {
console.log("alphabets are not allowed");
event.preventDefault();
}
}
console.log("keycode: " + keyCode + "ActiveElemet: "+activeElmnt.id);
}
</script>
-- Append in page HTML Body attribute
onkeydown="validateNumber(event);"
here is my simple solution simply
in this solution u should keep the input type to text so when you use event.target.value you get the full string not only the numbers or an empty string instead so you actually can check if there is a point yet or not.
and i didn't use the deprecated properties event.which
isNumber(event) {
var allowed = "";
if (event.target.value.includes(".")) {
allowed = "123456789";
} else {
allowed = "123456789.";
}
if (!allowed.includes(event.key)) {
event.preventDefault();
}
}
document.getElementById('number').addEventListener('keypress', isNumber);
the HTML
```
function isNumber(event) {
var allowed = "";
if (event.target.value.includes(".")) {
allowed = "0123456789";
} else {
allowed = "0123456789.";
}
if (!allowed.includes(event.key)) {
event.preventDefault();
}
}
document.getElementById('number').addEventListener('keypress',isNumber);
<h3>You can input only numbers and one point (this would be a float or int) </h3>
<input type="text" id="number" />
This one should work. Only works with integers.
function validateNumberInput(e) {
if (isNaN(e.key)) {
e.preventDefault();
}
}
You can however implement floats with few more lines:
function validateNumberInput(e) {
if (isNaN(e.key) && e.key !== '.') {
e.preventDefault();
} else if (e.key === '.') {
if (e.target.value.indexOf('.') >= 0) {
e.preventDefault();
}
}
}
Finally use it like:
targetInput.addEventListener('keypress', function (e) {
validateNumberInput(e);
});
A very nice react solution... You just want to consume the event if its NaN
onKeyedPress = (e) => {
if(!parseInt(e.key)){
e.preventDefault();
}
}
Try it:
document.querySelector("input").addEventListener("keyup", function () {
this.value = this.value.replace(/\D/, "")
});

issue when limiting input characters to numbers on android chrome with javascript/jquery

i'm trying to limit the input of a text input to only numbers. I have an event handler set up for jquery keydown() that can be seen below. It works as expected on the desktop browsers i've tested and also in mobile safari and chrome on iOS. But i'm experiencing a few issues in chrome on the Nexus 7.
function keyDownHandler( e ) {
e.stopImmediatePropagation();
if( !e.shiftKey && !e.altKey && !e.ctrlKey ) {
var key = e.which || e.keyCode;
if( key >= 48 && key <= 57 ||
key >= 96 && key <= 105 ||
key == 8 || key == 9 ||
key == 37 || key == 39 ||
key == 46 || key == 45 ) {
return true;
}
if( key == 13 ) {
//returned pressed, do something
}
}
e.preventDefault();
return false;
};
There appears to be few known bugs related to the android soft keyboard, whereby the same value for keycode is returned for every key. This value also varies depending on device, but for the nexus 7 it's 229. The numerical keys also intermittently return the correct value for keycode, which is nice. I should be able to just add some catch all logic to deal with this, but the issue i'm stuck on is that, even though this method returns false and calls e.preventDefault(), it's not preventing the characters appearing in the text input?
Am i doing something wrong and need to call something else to cancel the event on android chrome or is this a bug?
Just to note, it works fine in firefox and dolphin on the Nexus 7, just not chrome or opera, where the same issue occurs.
Thanks.

Validating '%' and '(' on JavaScript

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.

Categories