I'm working with a JavaScript routine I didn't write. It is called from a text box's onkeydown attribute to prevent unwanted keystrokes.
The first argument is apparently not used. The second argument is a list of characters that should be allowed.
function RestrictChars(evt, chars) {
var key;
var keychar;
if (window.event)
key = window.event.keyCode;
else if (e)
key = e.which;
else
return true;
keychar = String.fromCharCode(key);
if ((key == null) || (key == 0) || (key == 8) ||
(key == 9) || (key == 13) || (key == 27))
// Control key
return true;
else if (((chars).indexOf(keychar) > -1))
return true;
else
return false;
}
This seems to work for alpha-numeric characters. However, characters such as . and / cause this function to return false, even when these characters are included in the chars parameter. For example, if the . key is pressed, key is set to 190, and keychar gets set to the "3/4" character.
Can anyone see how this was meant to work and/or why it doesn't? I don't know enough about JavaScript to see what it's trying to do.
Two things are wrong with that: first, if you're analysing what character has been typed, you need to use the keypress event instead of keydown because that is the only event that tells you anything reliable about the actual character typed. For (a lot) more detail about about this and JavaScript key events in general, see http://unixpapa.com/js/key.html. Second, there are references to a variable called e which doesn't (but should) correspond with the evt parameter.
Here's a rewrite, assuming you have a variable called textBox that refers to the text input element.
jsFiddle: http://jsfiddle.net/9DZwL/
Code:
function isKeypressCharValid(e, chars) {
e = e || window.event;
// Allow delete, tab, enter and escape keys through
if (/^(8|9|13|27)$/.test("" + e.keyCode)) {
return true;
}
var charCode = (typeof e.which == "number") ? e.which : e.keyCode;
var charTyped = String.fromCharCode(charCode);
return chars.indexOf(charTyped) > -1;
}
textBox.onkeypress = function(evt) {
if (!isKeypressCharValid(evt, "abc123")) {
return false;
}
};
I'm not a JS person, either, but... I can explain how it's supposed to work; I don't know why you're getting the values you are for the keys you mentioned, however.
keychar = String.fromCharCode(key);
This checks to see if the key is a printable character (letter, punctuation mark, etc.)
if ((key == null) || (key == 0) || (key == 8) ||
(key == 9) || (key == 13) || (key == 27))
// Control key
The above checks to see if the key is null OR (||)` 0 or 8 (backspace) or 9 (tab) or 13 (0x0D, or ENTER) or 27 (0x1B or ESCAPE) - it's exactly the Boolean result you'd expect: IF <thiscondition> or <thatcondition> or <anothercondition> or ...
else if (((chars).indexOf(keychar) > -1))
This checks to see if the keychar is in the string of characters passed as the chars parameter
Related
I have been using jquery to capture the keydown event and validate the entered text for different cases like: characters only, alpha-numeric, characters and spaces etc.
Regex used:
Characters with spaces: ^[a-zA-Z ]+$
Characters only: ^[a-zA-Z]+$
Alphanumerics: ^[a-zA-Z0-9]+$
This is how I am using the bind function:
$('.chars_and_space_only').bind('keydown', function (event) {
// http://stackoverflow.com/a/8833854/260665
var eventCode = !event.charCode ? event.which : event.charCode;
if((eventCode >= 37 && eventCode <= 40) || eventCode == 8 || eventCode == 9 || eventCode == 46) { // Left / Right Arrow, Backspace, Delete keys
return;
}
// http://stackoverflow.com/a/8833854/260665
var regex = new RegExp("^[a-zA-Z ]+$");
var key = String.fromCharCode(eventCode);
if (!regex.test(key)) {
event.preventDefault();
return false;
}
});
All of above uses cases are working fine, however I have to now include characters, spaces, apostrophe and periods. So this is the method I have modified:
$(".chars_space_dots_apostrophes_only").bind('keydown', function (event) {
// http://stackoverflow.com/a/8833854/260665
var eventCode = !event.charCode ? event.which : event.charCode;
if((eventCode >= 37 && eventCode <= 40) || eventCode == 8 || eventCode == 9 || eventCode == 46) { // Left / Right Arrow, Backspace, Delete keys
return;
}
// http://stackoverflow.com/a/8833854/260665
var regex = new RegExp("^[a-zA-Z '.]+$");
var key = String.fromCharCode(eventCode);
if (!regex.test(key)) {
event.preventDefault();
return false;
}
});
This, strangely doesn't seem to work. Here is the fiddle: https://jsfiddle.net/ugu8f4y3/
Regex used: ^[a-zA-Z '.]+$
Regex validator does validate this text for the above regex:
Hello. World's
But the text field in fiddle does not allow me to enter periods and apostrophes, is there something I am missing here?
The problem is with jquery and the keydown event. Replace it with keypress and you'll be good to go. You should also only need to check in which.
keydown and keyup are important for cases when you're concerned with the position of the key's physical location. In this case you want to know that the key was depressed and handle the resulting input. jquery will normalize the character codes differently.
Further information about the differences between keypress, keydown and key up.
Updated Fiddle
I have an HTML form in which I need to allow only numeric key-press. For this i have used the following code
$(".span8").keypress(function(e)
{
var unicode=e.charCode? e.charCode : e.keyCode
//alert(unicode);
if ((unicode ==8) || (unicode==9)|| (unicode==46)){
//if the key isn't the backspace key (which we should allow)
}
else
{
if (unicode<48||unicode>57&&unicode!=65) //if not a number
return false //disable key press
}
});
but here if I am testing keycode, I am getting value as 46 for delete key. 46 is for dot(- period)
Others values are coming correct. I am not able to find were am I going wrong.
Please help
I've found this weird behaviour too with the keypress function.
Instead, try the following:
jQuery(function($) {
var input = $('.span8');
input.on('keydown', function() {
var key = event.keyCode || event.charCode;
if(key == 8 || key == 46)
//Do something when DEL or Backspace is pressed
});
});
For my html, I'm trying to validate a form with a postcode input.
But this input is not working (or not being recognized). For my postcode input, I want to text box to only accept numbers.
Postcode input:
var Postcode = document.forms["Rego"]["postcode"].value;
var e = Postcode;
var code = e.keyCode;
if (code > 47 && code < 58) || code == 40 || code == 41 || code == 43) {
return true;
}
alert("Invalid Postcode. Please enter numbers only.");
return false;
What am I doing wrong?
In your condition if in line 4 after 58 why you close the ) ???
You are doing quite a few things wrong. You are not setting an event handler, you are actually binding to the value in the input box. You have to first get the DOM element representing the text box, then bind an event handler to the DOM element. Try this:
var Postcode = document.getElementById('post');
Postcode.onclick = function(e) {
console.log(e);
var code = e.keyCode;
if (code > 47 && code < 58 || code == 40 || code == 41 || code == 43) {
return true;
}
alert("Invalid Postcode. Please enter numbers only.");
e.preventDefault()
return false;
}
Fiddle: http://jsfiddle.net/S47gV/
To only accept numbers, you can use (for HTML5):
<input type="number" name="whatever">
Plus, if you want to validate it with js (doing so in browser is not recommended as anyone can modify your js file and push the contents to the server) or server code, here's some insight:
Try to convert the string passed to the server into a number. For example, in python you can do: int(whatever). If the conversion fails, that means the string isn't a number.
Hope that helps :)
If you use HTML5 you can set this automatically.
<input type="number" name="quantity" min="47" max="58">
By using below code textbox/inputbox allow only numeric value
$j('#inputbox_id').keydown(function (e) {
if (e.shiftKey || e.ctrlKey || e.altKey) {
e.preventDefault();
} else {
var key = e.keyCode;
if (!((key == 8) || (key == 46) || (key >= 35 && key <= 40) || (key >= 48 && key <= 57) || (key >= 96 && key <= 105))) {
e.preventDefault();
}
}
});
and if you want to set length of textbox/input box then set "maxlength=5"
I think i have found what you are doing wrong:
You are reading postcode value from input type and then comparing its keycode.
However‚ it may work only when your input has single number and when you type more characters in it your postcode variable becomes something for example 5436 and then when you use keycode function on this in wont work as expected.
Is there any shortcut( actually a function) in jQuery or Javascript to handle button press except something, or only something, e.g.:
$(input).keypress('nonfunctional' function(){
// do something
});
that will trigger only on [a-z][0-9] buttons pressed and ignoring single shift or ctrl but handling shift+a => A pressed?
P.S.i do know about if(key.code == 123) then ...
No, if you want to exclude specific keys that's what the event.keyCode / event.which properties are there for.
Or you can extend jquery keypress. Something like this I guess:
$.fn.keypressBut = function(codes, callback) {
$(this).keypress(function(e) {
~$.inArray(e.keyCode, codes) || callback.call(this, e);
});
}
// Lets ignore Enter and Space
$('input').keypressBut([13, 32], function(e) {
alert(e.keyCode);
})
You could do something like
Extend jquerys fn propertie with a function which takes params like
Some Data
A callback function
Write a validation Function which
Converts the keyCode to a String
Match it against a Regular Expression.
If the shiftKey was Pressed
Convert it to Upper Case
Check if other Conditions, like Ctrl/Alt key Pressed are met.
Returns the Result.
If the validation succeeds
execute the callback function
On the code site this could like
$.fn.selectedKey = function (cb, data) {
def.call(data, {
ctrlKey: 2, //0: musn't be pressed, 1: must be pressed, 2: both.
altKey: 2, // "
invert: 0, //inverts the filter
filter: /.*/, // A Regular Expression, or a String with a Regular Expression
preventDefault: false //Set to true to prevent Default.
}); //Sets the default Data for the values used,
function validate(e) {
var key = e.char = String.fromCharCode(e.keyCode || e.which); // Converts the pressed key to a String
if (e.shiftKey) key = key.toUpperCase(); //Handles Case Sensitivity.
var exp = new RegExp(e.data.filter.replace(/\\\\(\d)/g, String.fromCharCode("$1"))); //Creates a new RegExp from a String to e.g. allow "\2" to match the keyCode 2
var c = !! (e.data.ctrlKey ^ e.ctrlKey ^ 1 > 0); //c == true if the above stated conditions are met e.g Ctrl Key Pressed and `ctrlKey == 1` -> true
var a = !! (e.data.altKey ^ e.altKey ^ 1 > 0); //e.g Alt Key Pressed and `altKey == 0` -> false
return (exp.test(key) && (c && a)); //Returns the validation Result
}
function def(obj) { //a minimal helper for default values
for (var prop in obj) {
this[prop] = this[prop] || obj[prop];
}
}
this.keypress(data, function (e) {
if (e.data.preventDefault) e.preventDefault();
if (validate(e) != e.data.invert) cb(e); //Calls the callback function if the conditions are met
});
};
Which you could then use the following ways
With a regex
$("body").selectedKey(function (e) {
console.log("All lower characters Numbers and 'A': " + e.char);
}, {
filter: /[a-z]|[0-9]|A/,
ctrlKey: 2,
altKey: 2
});
This would be triggered if any [a-z] or [0-9] or the Shift key + A has been pressed, regardless of the state of ctrl and alt
Or a keycode
$("body").selectedKey(function (e) {
// do somet
console.log("KeyCode 2 " + e.char);
}, {
filter: "\\2", //Ctrl + b
ctrlKey: 1,
altKey: 2
});
Would be triggered if you press ctrl +b
You could also combine those both.
Heres an Example on JSBin, to fiddle around with.
There is a jQuery plugin for using classes and regex for filtering keypresses if you dont want to write a large if statement to detect the key code pressed, its called keyfilter. An example would be
$(selector).keyfilter(/[a-z]/);
For example this function below allow only numbers en handle this functions using the keydown event.
function OnlyNumbers(event) {
if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 || (event.keyCode == 65 && event.ctrlKey === true) || (event.keyCode >= 35 && event.keyCode <= 39)) { return; }
else { if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) { event.preventDefault(); } }
}
have you tried event.altKey/event.shiftKey/event.ctrlKey ??
I'm trying to build a communal wall, that appears the same for all those who access the web page, and syncs between users. I'm struggling to capture keyboard input correctly to apply to the canvas. My function is based on document.onkeydown, and can be seen in the 'script.js' referenced in the said web page. It can be seen working when you double click a word and the write.
Unfortunately this seems to be failing to capture anything but capital letters, and I'm looking for an alternate way to go about this. I've looked into the 'textInput' event, described in this page, however it seems to be only supported by WebKit browsers, and I want to build something which works generically. Can someone suggest an alternate way to go about capturing keyboard input for use in canvas? Or perhaps I'm doing something silly?
Code described is here:
document.onkeydown = keyHandler;
function keyHandler(e)
{
var pressedKey;
if (document.all) { e = window.event;
pressedKey = e.keyCode; }
if (e.which) {
pressedKey = e.which;
}
if (pressedKey == 8) {
e.cancelBubble = true; // cancel goto history[-1] in chrome
e.returnValue = false;
}
if (pressedKey == 27)
{
// escape key was pressed
keyCaptureEdit = null;
}
if (pressedKey != null && keyCaptureEdit != null)
{
keyCaptureEdit.callback(pressedKey);
}
}
... Later on in code describing each text object ...
keyCaptureEdit.callback = function (keyCode) {
var keyCaptured = String.fromCharCode(keyCode);
if (keyCaptured == "\b" ) { //backspace character
t.attrs.timestamp = t.attrs.timestamp + 1;
t.setText(t.getText().slice(0, -1));
}
else if (keyCode == 32 || keyCode >= 48 && keyCode <= 57 || keyCode >= 65 && keyCode <= 90)
{
t.attrs.timestamp = t.attrs.timestamp + 1;
t.setText(t.getText() + keyCaptured);
}
layer.draw();
}
Well one trivial way to change your code would be to keep track of the shift key:
...
{
keyCaptureEdit.callback(pressedKey, e.shiftKey); // <-- keep track of shift key
}
}
...
keyCaptureEdit.callback = function (keyCode, shift) {
var keyCaptured = String.fromCharCode(keyCode);
// shift key not pressed? Then it's lowercase
if (shift === false) keyCaptured = keyCaptured.toLowerCase()
But that doesn't account for CapsLock.
In jQuery its really simple because the right key code is done for you:
$(document).keypress(function(event) {
var keyCaptured = String.fromCharCode(event.keyCode);
console.log(keyCaptured);
});
In that example the console will correctly log P or p depending on what would be typed.