Regex disabling escape key - javascript

I am using the following code to try and only allow letters, numbers, backspace, space, dashes, and ampersands. I also want to "disabled" all other keys including the function keys (F1, F2, etc). The problem I am running in to is with the regex also disabling the escape key.
Can the same thing be achieved without using a regular expression?
This function is part of a live search feature, and I don't want the ajax request to be sent if on of the "prohibited" keys are pressed.
searchBox.keyup(function (e) { // LIVE SEARCH FUNCTION
var functionKeysPressed = [112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123].indexOf(e.which) > -1;
if (String.fromCharCode(e.which).match(/^[\w\x08]$/) && !functionKeysPressed) {
// code to execute if key is allowed
}
});

You can do this without a regex. Simple refer to e.keyCode instead of e.which:
if (e.keyCode == 27){
//Esc Key pressed
}
for onKeyUp
keycode returns the Unicode keycode of the key that triggered the event.
You will find the keycodes here:
http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
to exclude multiple keys, you could simply create an array and check if the keycode is blacklisted:
var blacklisted = [1,2,3,4,5];
if (blacklisted.indexOf(e.keyCode) == -1){
//do something
}

Related

Convert a String to KeyCode (with Special Characters)

Couldn't find any post with the right solution,
Basically what i'm trying to get, is to convert a string with special characters to KeyCode Array,
for Example: Convert "Hello#Today" to:
[104, 101, 108, 108, 111, 16, 50, 116, 111, 100, 97, 121]
Notice the "16, 50" which is combination of Shift(16) + 2(50),
In my current code i get (64) for # which is wrong:
[104, 101, 108, 108, 111, 64, 116, 111, 100, 97, 121]
my current function:
function convertToKeyCode(text) {
var results = text.split('')
.map(function (char) {
return char.charCodeAt(0);
});
return results;
}
Thanks
There is not a "ready-to-use" solution to convert a character to a key-code, at least in JavaScript.
Furthermore even if you implement your own conversion/mapping algorithm consider that different keyboard layouts generate characters with different key combinations.
Finally not every character code you may get with charCodeAt may have a corresponding key combination.

Regex validation returns false on Samsung Tizen TV

I am developing a SmartTV web app using JavaScript.
I want to write a regular expression which validate the local mobile operator codes:
op_codes = [33, 50, 63, 66, 67, 68, 73, 93, 95, 96, 97, 98, 99]
My code works as it should in Chrome and LG webOS. But in Samsung Tizen RegExp.test returns false even though it should be true.
Code sample:
var val = '0985739341',
op_codes = [33, 50, 63, 66, 67, 68, 73, 93, 95, 96, 97, 98, 99],
pattern = new RegExp('^0'+'('+op_codes.join('|')+')'+'\\d{7}$');
console.log(pattern.test(val)); //Samsung Tizen output: false
Here is the screenshot of Tizen console:
Tizen console(Updated)
I can't figure out what is wrong with my code, how can I solve it?
Same code executed on Chrome and Tizen:
Tizen(left) Chrome(right) console
Same variable Chrome and Tizen:
How it can be?
New Answer
Your latest screenshot (here) tells us that you have an invisible character in val. I really, really, really should have thought of that earlier. Apparently for whatever reason, whatever your source is for val, it's including an invisible character in it.
You'll need to identify it and, ideally, figure out where it comes from and fix it; otherwise, strip it out.
To figure out what it is, try this:
console.log("val", val);
Array.prototype.forEach.call(val, function(ch) {
console.log(ch.charCodeAt(0).toString(16));
});
If it were the value it seems to be, you'd get
val 0985739341
30 39 38 35 37 33 39 33 34 31
Live Copy:
var val = "0985739341";
console.log("val", val);
console.log(Array.prototype.map.call(val, function(ch) {
return ch.charCodeAt(0).toString(16);
}).join(" "));
...but I bet you get something else. It could be any of several invisible characters — a zero-width space (U+200B), a zero-width non-joiner (U+200C), etc. Here's an example with both of those:
var val = "0985\u200C\u200B739341";
console.log("val", val);
console.log(Array.prototype.map.call(val, function(ch) {
return ch.charCodeAt(0).toString(16);
}).join(" "));
Once you know what it is, you can find out where it comes from and get rid of it (or strip it from the string afterward).
Old, Probably-Incorrect Answer
I can't figure out what is wrong with my code...
If that screenshot is genuine, then there's nothing wrong with your code; there's a bug in the JavaScript engine being used on that device. This would appear to be one of the rare cases where the rule "select isn't broken" fails. (Would appear to be, keep being skeptical and keep double-checking yourself.)
You'll have to experiment to see where it fails (and file an appropriate bug report) and work around it. For instance, maybe the implementation of test incorrectly ignores capture groups and so isn't applying | correctly, or new RegExp is just fundamentally broken, or... It'll take a lot of experimentation to figure it out.
Below are your original validation (validate1) and three alternatives you might try. The second (validate2) uses a non-capturing group instead of a capturing group. They should be the same as far as test is concerned, but then again, your original code should work. :-)
var val = '0985739341';
var op_codes = [33, 50, 63, 66, 67, 68, 73, 93, 95, 96, 97, 98, 99];
var val1PatternStr = '^0'+'('+op_codes.join('|')+')'+'\\d{7}$';
var val1Pattern = new RegExp(val1PatternStr);
var val2PatternStr = '^0'+'(?:'+op_codes.join('|')+')'+'\\d{7}$';
var val2Pattern = new RegExp(val2PatternStr);
console.log(1, validate1(val));
console.log(2, validate2(val));
console.log(3, validate3(val));
console.log(4, validate4(val));
function validate1(val) {
return val1Pattern.test(val);
}
function validate2(val) {
return val2Pattern.test(val);
}
function validate3(val) {
return val.length === 10 &&
val[0] == "0" &&
op_codes.indexOf(+val.substring(1,3)) != -1 &&
/^\d+$/.test(val.substring(3));
}
function validate4(val) {
return val.length === 10 &&
val[0] == "0" &&
op_codes.indexOf(+val.substring(1,3)) != -1 &&
sillyIsDigit(val[3]) &&
sillyIsDigit(val[4]) &&
sillyIsDigit(val[5]) &&
sillyIsDigit(val[6]) &&
sillyIsDigit(val[7]) &&
sillyIsDigit(val[8]) &&
sillyIsDigit(val[9]);
}
function sillyIsDigit(ch) {
return ch >= "0" && ch <= "9";
}
If the JavaScript engine chokes on val[0], you'll have to change all of those [] on val to calls to charAt instead: val[0] => val.charAt(0).

Validate Hex Textfield Not Working

I'm trying to validate a textfield for hex colors only using regex. I stumbled upon this answer, and tried it for my textField, and it doesn't work as I expect it to. Here's the code:
/^[0-9A-F]{6}$/i.test(e.target.value)
It's supposed to check if the textfield is 0 - 9 || A - F (capital or lowercase), but when I log that, it always says false.
How can I validate a hex textfield?
Full Code:
JSFiddle
document.getElementById('hexTextField').addEventListener('keyup', function(e) {
// Allow: tab, home, end, left, up, right, down
if ([9, 36, 35, 37, 38, 39, 40].indexOf(e.keyCode) !== -1 ||
// Allow: Ctrl || Command && a, c, x and v
(!0 === e.ctrlKey || !0 === e.metaKey) && /65|67|88|86/.test(e.keyCode)) {
if (e.keyCode === 86 && /(^[0-9A-F]{6}$)|(^[0-9A-F]{3}$)/i.test(e.target.value)) {
//myColor.setColor(e.target.value, 'hex');
}
return;
}
console.log(/^[0-9A-F]{6}$/i.test(e.target.value));
if (/^[0-9A-F]{6}$/i.test(e.target.value)) {
//myColor.setColor(e.target.value, 'hex');
} else {
e.preventDefault();
}
});
<input type="text" id="hexTextField" spellcheck="false" maxlength="6">
Update
There seems to be some confusion of what exactly I'm asking. I'm trying to validate the textField as the user is typing, not when the user finished. I hope this will clarify my question.
What the regex code does is, it checks if the textfield has the 'valid' chars, && if there are 6 chars in the textfield.
So if one would want to validate the textfield as the user types, you would use this regex:
/[0-9A-Fa-f]$/i
Notice, I removed the {6} which comes out to true only if there are 6 chars.

alert letters by name on pressing keyboard buttons without using a switch statement

Here i have a simple piece of code.I want it to alert letters [A-Z] on pressing buttons on keyboard representing those letters.Till now it only alerting keyCodes.I know i can do that whit a switch statement.But it will be a large piece of switch statement. So my questions are:
1.Is there a way i can alert every letters by their name on keypress without a switch statement?
2.Left,right,up,down arrow keys are not alerting their keycode numbers.Why is that so??How can i overcome this problem??
(function(){
document.body.addEventListener('keypress',function(e){
alert(e.keyCode);
});
})();
To show the letters from their keyCode:
alert (String.fromCharCode(e.keyCode));
To address the problems with the arrow-keys not showing their keyCodes (37 - 40):
(function(){
document.body.addEventListener('keyup',function(e){
// the keyCodes of the arrow keys, matched to an appropriate
// unicode arrow symbol:
var directionals = {
'38' : 8593, // String.fromCharCode(38) => &
'39' : 8594, // String.fromCharCode(39) => '
'40' : 8595, // String.fromCharCode(40) => (
'37' : 8592 // String.fromCharCode(37) => %
},
// if there is a falsey value from directionals object,
// we use the e.keyCode unchanged; otherwise we substitute
// e.keyCode for the above-supplied arrow-character:
keyCodeToUse = !directionals[e.keyCode] ? e.keyCode : directionals[e.keyCode];
// I don't like alerts; to access the console (in most browsers) press 'F12':
console.log(String.fromCharCode(keyCodeToUse));
});
})();
html, body {
background-color: rgba(255,255,180, 0.5);
height: 100%;
}
The problem itself is that (for whatever reason) the arrow keys only return keyCodes on keyup and keydown, not on keypress. Further, the String.fromCharCode() using their key codes (as shown in the JavaScript, above) return characters that are not, in fact, arrows. So, we have to use alternate Unicode references (supplied above, in the JavaScript).
References:
String.fromCharCode().
You can use String.fromCharCode function for this:
String.fromCharCode(e.keyCode)

Javascript to match a specific number using regular expressions

I was using javascript to detect for specific key strokes and while writing the method I thought I'd try regular expressions and the test() method and came up with:
if (/8|9|37|38|46|47|48|49|50|51|52|53|54|55|56|57|96|97|98|99|100|101|102|103|104|105|110/.test(num)) {
// do something if there's a match
}
This doesn't seem to work 100% as some values seem to make it past the regex test, such as 83. I've since moved on, but I'm still curious as to why this didn't work.
This is the completely wrong way to do it.
To answer the question, the regex is matching part of your string. The string 83 passes by matching the 8.
You need to anchor your regex by putting ^( at the beginning and )$ at the end.
The correct way to do this is to make an array of valid numbers, and compare using parseInt.
For example:
var validNumbers = [ 8, 9, 37, 38, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110 ];
if (validNumbers.indexOf(parseInt(num, 10)) >=0 ) {
//Match
}
You'll need an indexOf function for IE:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(needle) {
for(var i = 0; i < this.length; i++) {
if(this[i] === needle) {
return i;
}
}
return -1;
};
}
You need to specify the start and end of the string. Otherwise 8 in 8|… will match the 8 in 83:
/^(8|9|37|38|46|47|48|49|50|51|52|53|54|55|56|57|96|97|98|99|100|101|102|103|104|105|110)$/.test(num)
But you should rather use numeric comparison. If you don’t like to list every number, you can use ranges like this:
function foo(number, numbers) {
for (var i=0; i<numbers.length; ++i) {
if (numbers[i] === number) {
return true;
} else if (numbers[i].constructor === Array) {
if (numbers[i][0] <= number && number <= numbers[i][1]) {
return true;
}
}
}
return false;
}
var numbers = [8, 9, 37, 38, [46, 57], [96, 105], 110];
if (foo(num, numbers)) {
// …
}
If you make a regular expresion like /\b(100|101)/g it will match only 100 and 101 and not 5100, 5101 or ...101...;
The only problem with this is if your are using negative numbers, e.g in case of 101 and -101 both match with the regexp.
I know this because is what I'm facing and want to avoid.
I can share with you an example:
let array = [89, 7, 92, 78, 899, 65, 56, 92, 922, 292, 289, 389, 2879, 2932, 8999];
I want to find how many instances of the number 92 exist in that array. Therefore I am searching for the precise number of 92. And I want to use Regular Expressions in Javascript.
First part comes with the transformation of the array into a string:
let strCheck = array.toString(); // "89,7,92,78,899,65,56,92,922,292,289,389,2879,2932,8999"
let regex = /\b92\b/g;
I used the flag g for global so that it finds all the matches and the \b word boundary as described in MDN.
let arrResult = strCheck.match(regex); // ["92", "92"]
That's it. The tricky part was first to acknowledge that Regular Expressions work with strings, the second was that once I got the string I had to think about getting the number I wanted not as a number but as a string which was going to be surrounded by other characters and reaching out to those other characters, helped to find the solution.

Categories