I believe this is an easy one, but I couldn't find any answer after a couple of hours searching on google (maybe I wasn't able to use the correct words in the search :-P)
I have a javascript method that prevents the user to fill the textbox with other characters than numbers, as it can be seen in the code below, and it's used in KeyDown event:
function checkNumberInput(e) {
// Allow: backspace, delete, tab, escape, enter and .
if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110]) !== -1 ||
// Allow: Ctrl+A, Command+A
(e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) ||
// Allow: home, end, left, right, down, up
(e.keyCode >= 35 && e.keyCode <= 40)) {
// let it happen, don't do anything
return;
}
// Ensure that it is a number and stop the keypress
if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
}
The problem is that, if the user types accent characters that "waits" a second key (such as ~´`^), it appears in the textbox when a number is typed right after.
For example:
a) types 1 => [1________]
b) types ~ => [1________]
c) types 3 => [1~3______]
How can I prevent this from happening? Thanks in advance.
Do you mean that ' and a are converted to а́?
This is built in the system, you cannot change that.
What you can do is check the input after that. This way you'll also prevent paste with mouse:
$('input').on('keydown', checkNumberInput).on('blur focus', function(){
var val = $('input').val();
// now remove everything that is not allowed
val = val.replace(/[^0-9.]+/g, '');
$('input').val(val);
})
(The exact implementation is deffinitely not perfect, just to illustrate what's going on)
https://jsfiddle.net/5afwdhzx/
About really instant fix - give this closure a name and call it inside the keyDown function with some short delay, like #haroldo said above.
https://jsfiddle.net/5afwdhzx/1/
Related
I have this piece of code. According to keycodes here
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000520.html
this code should work but for some reason I am getting these characters as true.
eiadfghcb.
function validate(event) {
var keycode = event.keyCode;
if (!(keycode == 8 || keycode == 46) && (keycode < 48 || keycode > 57) && (keycode < 96 || keycode > 105)) {
return false;
}
}
html:
<asp:TextBox ID="txtImp" runat="server" Height="23px" Width="80" onkeypress="return validate(event)" onkeyup="calc()"/>
The following code should work for you:
function validate(event) {
var code = event.code;
if (typeof code !== "undefined") {
var
codeBeginning = code.substr(0, code.length - 1);
if (code === "Period" || code === "NumpadDecimal" || code === "Backspace" || ((codeBeginning === "Digit" || codeBeginning === "Numpad") && !parseInt(code.substr(code.length - 1)).isNaN())) { // key pressed is one of the "."-keys, the "Backspace"-key or one of the number-keys.
return true;
}
return false;
}
var keyCode = event.which || event.keyCode;
if (keyCode === 8 || keyCode === 46 || (keyCode >= 48 && keyCode <= 57)) {
return true;
}
return false;
}
Explanation regarding to why your code didn't work.
The first condition in your if-statement !(keycode == 8 || keycode == 46) will indeed evaluate to true when the key pressed is neither the decimal point-key or the BACKSPACE-key.
However the second and third condition will conflict with one another. This can be show by the following example:
The user presses the Numpad 2-key which (in my case) results in 50. This value does comply to the second condition as 50 is both higher than 48 and lower than 57, but it will not comply to the third condition as 50 is lower than 96.
As both the second and third condition will have to result to true and there is always one of the two that will result in false the code will never do what you intend it to do.
Disclaimer
My previous answer stated that KeyBoardEvent.keyCode is unreliable and resulted in an inability to capture the right keys on my machine.
Even though I'm now unable to reproduce this issue I would still advice you to only use KeyBoardEvent.keyCode when absolutely necessary (as the documentation of KeyBoardEvent.keyCode does state that it is implementation specific), and use KeyBoardEvent.which whenever possible.
Explaination regarding to why my code works.
As the KeyBoardEvent.keyCode relies heavily on the browser implementation thereof, I've chosen to using it as much as possible by instead using KeyBoardEvent.which.
However as both of these properties have become deprecated I've also used KeyBoardEvent.code to make sure that the solution adheres the lastest KeyBoardEvent specification.
As such my solution uses KeyBoardEvent.code when available as it isn't deprecated or implementation specific. If KeyBoardEvent.code is unavailable it uses KeyBoardEvent.which as it is more consistent that KeyBoardEvent.keyCode. And finally if KeyBoardEvent.which (as is the case in older browsers e.g. Internet Explorer 8) it will have to use KeyBoardEvent.keyCode.
The issue:
Take a look at your third condition:
keycode < 96 || keycode > 105 //Where keycode is NOT between 96-105
Now look at the ASCII codes for the characters you entered:
a: 97
b: 98
c: 99
d: 100
e: 101
f: 102
g: 103
h: 104
It should now be obvious why your code is failing - You've included a condition that very specifically ignores the characters you're claiming "don't work".
keyCode vs charCode:
When it comes to keyCode, you're going to run into some cross-browser issues. For that reason you may want to consider checking both keyCode and/or charCode, as each works in a specific set of browsers. A simple way to be sure we're getting a value that's consistent is to do something like this:
var keycode = event.keyCode || event.charCode;
In the event that event.keyCode won't work, charCode will be used instead.
The solution:
If you simply want to ignore the condition that I pointed out as the problem, then just remove it:
if (!(keycode == 8 || keycode == 46) && (keycode < 48 || keycode > 57)) {
return false;
}
That being said, your question doesn't say what your desire is... at all. It simply says that what you have "doesn't work for the characters mentioned".
Additional info:
As a side note, I'd be remiss if I didn't point out that your code is not exactly... friendly, for lack of a better word. An elegant way of resolving this is to replace condition lists with named functions, so the purpose and result is much more discernible, like so:
Bad:
if (sunny || not raining and warm || not(cloudy and raining) || not cold)
Good:
if (weatherIsNice(...))
Applied in your case it may be something like
function characterIsAllowed(keycode) {
if (!(keycode == 8 || keycode == 46) && (keycode < 48 || keycode > 57) && (keycode < 96 || keycode > 105)) {
return true;
} else {
return false;
}
}
function validate(event) {
var keycode = event.keyCode || event.charCode;
if (characterIsAllowed(keycode)) {
return false;
}
}
Or, simplified one step further...
function characterIsAllowed(keycode) {
return (!(keycode == 8 || keycode == 46) && (keycode < 48 || keycode > 57) && (keycode < 96 || keycode > 105))
}
function validate(event) {
var keycode = event.keyCode || event.charCode;
return !characterIsAllowed(keycode);
}
I've an input box that I only want to allow letters, hyphen, space and backspace. All is good on chrome but on Firefox backspace (or charcode 8) does not work. - https://jsfiddle.net/npo7y7fr/
$(document).ready(function () {
$('.textInput').keypress(function (key) {
if ((key.charCode < 97 || key.charCode > 122) && (key.charCode < 65 || key.charCode > 90) && (key.charCode != 45)) return false;
});
});
I've tried adding && (key.charCode != 8) also changes keypress to others like 'keydown, keyup' etc...
Can anybody get this working in Firefox (40.0.3) or something that I can use instead?
Since Space will send keycode 32 and backspace will send 0 in Mozilla so that's why it is not working in mozilla.
change your script as below
$(document).ready(function () {
$('.textInput').keypress(function (key) {
if ((key.charCode < 97 || key.charCode > 122) && (key.charCode < 65 || key.charCode > 90) && (key.charCode != 45) && (key.charCode != 32) && (key.charCode != 0) ) return false;
});
});
hope this helps..!!
Instead of hardcoding some special keys, just skip the filtering for all of them. With the accepted solution, you still cancel arrow keys, Home, End, etc., which is a bad thing for the user.
As all special keys have a key field longer than 1 character, you can safely do this:
$(document).ready(function () {
$('.textInput').keypress(function (event) {
return event.key.length > 1 || event.ctrlKey || !!event.key.match(/[a-zA-Z \-]/);
});
});
The pressed key is accepted if it's a special key, it's been pressed simultaneously with the Ctrl key (to allow copying and pasting) or if it matches the regular expression (letters, space and hyphen).
As the user can paste invalid content, you should still remove illegal characters with the oninput event (probably something like ctrl.value.replace(/[^a-zA-Z \-]+/g, '')).
Rather than trying to control what the browser can enter into the input, it might be easier to just filter the contents of the textbox on keyup.
Consider the following:
$('.textInput').keyup(function() {
$(this).val( $(this).val().replace(/[^a-zA-Z]/,''));
});
Hope this helps.
I'm just starting to write some coded-ui tests, and I have run into a problem during playback when I try to enter a value into a textbox which is constrained to only numeric (decimal) values via a javaScript function. I've identified the script as the "culprit" because the test runs successfully when it is disabled.
The value I've entered in the test is legitimate per the constraints of the function, so I don't understand why the exception is being thrown when the test runner enters it. Can anyone offer any insight? The javascript function seems to work for our purposes, so it would seem unfortunate to have to remove it just to make the automated tests work.
Here are some more details:
My test is fairly straight-forward. I'm finding 2 textbox controls and verifying that the proper validation message appears when a value is missing from the first. Setting the OrderIdTextBox.Text works, but setting the AmountTextBox.Text throws the exception (when the js function below is enabled):
[TestMethod]
public void Should_show_validation_error_if_orderId_is_missing()
{
_page.OrderIdTextBox.Text = "";
if (_page.AmountTextBox.Exists)
{
_page.AmountTextBox.Text = "10.00";
}
Mouse.Click(SubmitButton);
Assert.AreEqual(true, _page.OrderIdValidationSpan.Exists);
}
This is the javascript on the page which filters out unacceptable keystrokes:
$(document).on('keydown', ".number", function (event) {
// Allow: backspace, delete, tab, escape, enter, and decimal
if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 || event.keyCode == 110 || event.keyCode == 190 ||
// Allow: Ctrl+A
(event.keyCode == 65 && event.ctrlKey === true) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
else {
// Ensure that it is a number and stop the keypress
if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
event.preventDefault();
}
}
});
And here is the exception that's thrown when my test tries to set AmountTextBox value during playback.
Test method (namespace snipped).Should_show_validation_error_if_orderId_is_missing threw exception:
Microsoft.VisualStudio.TestTools.UITest.Extension.PlaybackFailureException: Cannot perform 'SetProperty of Text with value "10.00"' on the control. Additional Details:
TechnologyName: 'Web'
ControlType: 'Edit'
Id: 'Amount'
Name: 'Amount'
TagName: 'INPUT'
---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0xF004F006
Try
Playback.PlaybackSettings.SendKeysAsScanCode = true;
This similar question (https://stackoverflow.com/questions/16239673/exception-from-hresult-0xf004f006) lead to a go4answers topic which suggested the above.
"Playback by default sends keys to any application as Unicode. It might be necessary to send keys as scancode to certain applications. We can do this by using an over load of Keyboard.Sendkeys function."
From http://blogs.msdn.com/b/vstsqualitytools/archive/2010/04/13/uitest-framework-in-visual-studio-2010-part-2.aspx
You could also try:
if (_page.AmountTextBox.Exists)
{
Mouse.Click(_page.AmountTextBox);
Keyboard.Sendkeys("10.00");
}
I have written some JavaScript and jQuery code that accepts only numeric input in a textbox.
But this is not enough; I need to limit the input to certain numbers.
This textbox needs to deal with SSN numbers (Swedish SSN), and it has to start with 19 or 20. I want to force it to start with these numbers, but I can't manage to limit it to these.
$('input.SSNTB').keydown(function (event) {
var maxNrOfChars = 12;
var ssnNr = $('input.SSNTB').val();
if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 ||
// Allow: Ctrl+A
(event.keyCode == 65 && event.ctrlKey === true) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
else {
// Ensure that it is a number and stop the keypress
if (((event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105))) {
console.log("if-1");
event.preventDefault();
}
if (event.shiftKey == true) {
console.log("if-3");
event.preventDefault();
}
//rules to make sure the textbox starts with correct number
if (event.keyCode != 49 || event.keyCode != 50 || event.keyCode != 97 || event.keyCode != 98) {
console.log("if-4, Keycode:" + event.keyCode);
event.preventDefault();
}
}
});
The last if-case is executed to for testing this it is. It is executed as planed but it wont limit the input chars as its built for.
any tips or ideas?
You can use regex to limit the user to only inputting numbers and dashes. Using regex has the advantage that users can more naturally interact with the input, for instance they can paste into the text input and it will be validated successfully:
//bind event handler to the `keyup` event so the value will have been changed
$('.SSNTB').on('keyup', function (event) {
//get the newly changed value and limit it to numbers and hyphens
var newValue = this.value.replace(/[^0-9\-]/gi, '');
//if the new value has changed, meaning invalid characters have been removed, then update the value
if (this.value != newValue) {
this.value = newValue;
}
}).on('blur', function () {
//run some regex when the user un-focuses the input, this checks for the number ninteen or twenty, then a dash, three numbers, a dash, then four numbers
if (this.value.search(/[(20)(19)](-)([0-9]{3})(-)([0-9]{4})/gi) == -1) {
alert('ERROR!');
} else {
alert('GOOD GOING!');
}
});
Here is a demo: http://jsfiddle.net/BRewB/2/
Note that .on() is new in jQuery 1.7 and in this case is the same as using .bind().
Thought I would post the solution that came to the end. I actually kept the similar code that I posted above and did not covert this it RegExp. What was done was to verify the number after focus on this textbox is lost. It it is incorret the user will be informed and forced to fill in a valid number.
$('input.SSNTB').focusout(function () {
var ssnNr = $('input.SSNTB').val();
var ssnNrSub = ssnNr.substring(0, 2);
//console.log(ssnNrSub);
//checks for correct lenggth
if (ssnNr.length < 12) {
$('div.SSNHelp label.Help').html('SSN to short. Please fill in a complete one with 12 numbers');
setTimeout(function () {
$('input.SSNTB').focus();
}, 0);
validToSave = false;
return;
}
//checks so it starts correct
if (ssnNrSub != "19" && ssnNrSub != "20") {
$('div.SSNHelp label.Help').html('The SSN must start with 19 or 20. Please complete SSN.');
setTimeout(function () {
$('input.SSNTB').focus();
}, 0);
validToSave = false;
return;
}
$('div.SSNHelp label.Help').html('');
validToSave = true;
});
Works for me. : ]
You have to use regex. Regex is of help in these kind of situations.
Learn more about it from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp
How to know if .keyup() is a character key (jQuery)
$("input").keyup(function() {
if (key is a character) { //such as a b A b c 5 3 2 $ # ^ ! ^ * # ...etc not enter key or shift or Esc or space ...etc
/* Do stuff */
}
});
You can't do this reliably with the keyup event. If you want to know something about the character that was typed, you have to use the keypress event instead.
The following example will work all the time in most browsers but there are some edge cases that you should be aware of. For what is in my view the definitive guide on this, see http://unixpapa.com/js/key.html.
$("input").keypress(function(e) {
if (e.which !== 0) {
alert("Charcter was typed. It was: " + String.fromCharCode(e.which));
}
});
keyup and keydown give you information about the physical key that was pressed. On standard US/UK keyboards in their standard layouts, it looks like there is a correlation between the keyCode property of these events and the character they represent. However, this is not reliable: different keyboard layouts will have different mappings.
Note: In hindsight this was a quick and dirty answer, and may not work in all situations. To have a reliable solution, see Tim Down's answer (copy pasting that here as this answer is still getting views and upvotes):
You can't do this reliably with the keyup event. If you want to know
something about the character that was typed, you have to use the
keypress event instead.
The following example will work all the time in most browsers but
there are some edge cases that you should be aware of. For what is in
my view the definitive guide on this, see
http://unixpapa.com/js/key.html.
$("input").keypress(function(e) {
if (e.which !== 0) {
alert("Character was typed. It was: " + String.fromCharCode(e.which));
}
});
keyup and keydown give you information about the physical key that
was pressed. On standard US/UK keyboards in their standard layouts, it
looks like there is a correlation between the keyCode property of
these events and the character they represent. However, this is not
reliable: different keyboard layouts will have different mappings.
The following was the original answer, but is not correct and may not work reliably in all situations.
To match the keycode with a word character (eg., a would match. space would not)
$("input").keyup(function(event)
{
var c= String.fromCharCode(event.keyCode);
var isWordcharacter = c.match(/\w/);
});
Ok, that was a quick answer. The approach is the same, but beware of keycode issues, see this article in quirksmode.
I'm not totally satisfied with the other answers given. They've all got some kind of flaw to them.
Using keyPress with event.which is unreliable because you can't catch a backspace or a delete (as mentioned by Tarl).
Using keyDown (as in Niva's and Tarl's answers) is a bit better, but the solution is flawed because it attempts to use event.keyCode with String.fromCharCode() (keyCode and charCode are not the same!).
However, what we DO have with the keydown or keyup event is the actual key that was pressed (event.key).
As far as I can tell, any key with a length of 1 is a character (number or letter) regardless of which language keyboard you're using. Please correct me if that's not true!
Then there's that very long answer from asdf. That might work perfectly, but it seems like overkill.
So here's a simple solution that will catch all characters, backspace, and delete. (Note: either keyup or keydown will work here, but keypress will not)
$("input").keydown(function(event) {
var isWordCharacter = event.key.length === 1;
var isBackspaceOrDelete = event.keyCode === 8 || event.keyCode === 46;
if (isWordCharacter || isBackspaceOrDelete) {
// do something
}
});
This helped for me:
$("#input").keyup(function(event) {
//use keyup instead keypress because:
//- keypress will not work on backspace and delete
//- keypress is called before the character is added to the textfield (at least in google chrome)
var searchText = $.trim($("#input").val());
var c= String.fromCharCode(event.keyCode);
var isWordCharacter = c.match(/\w/);
var isBackspaceOrDelete = (event.keyCode == 8 || event.keyCode == 46);
// trigger only on word characters, backspace or delete and an entry size of at least 3 characters
if((isWordCharacter || isBackspaceOrDelete) && searchText.length > 2)
{ ...
If you only need to exclude out enter, escape and spacebar keys, you can do the following:
$("#text1").keyup(function(event) {
if (event.keyCode != '13' && event.keyCode != '27' && event.keyCode != '32') {
alert('test');
}
});
See it actions here.
You can refer to the complete list of keycode here for your further modification.
I wanted to do exactly this, and I thought of a solution involving both the keyup and the keypress events.
(I haven't tested it in all browsers, but I used the information compiled at http://unixpapa.com/js/key.html)
Edit: rewrote it as a jQuery plugin.
(function($) {
$.fn.normalkeypress = function(onNormal, onSpecial) {
this.bind('keydown keypress keyup', (function() {
var keyDown = {}, // keep track of which buttons have been pressed
lastKeyDown;
return function(event) {
if (event.type == 'keydown') {
keyDown[lastKeyDown = event.keyCode] = false;
return;
}
if (event.type == 'keypress') {
keyDown[lastKeyDown] = event; // this keydown also triggered a keypress
return;
}
// 'keyup' event
var keyPress = keyDown[event.keyCode];
if ( keyPress &&
( ( ( keyPress.which >= 32 // not a control character
//|| keyPress.which == 8 || // \b
//|| keyPress.which == 9 || // \t
//|| keyPress.which == 10 || // \n
//|| keyPress.which == 13 // \r
) &&
!( keyPress.which >= 63232 && keyPress.which <= 63247 ) && // not special character in WebKit < 525
!( keyPress.which == 63273 ) && //
!( keyPress.which >= 63275 && keyPress.which <= 63277 ) && //
!( keyPress.which === event.keyCode && // not End / Home / Insert / Delete (i.e. in Opera < 10.50)
( keyPress.which == 35 || // End
keyPress.which == 36 || // Home
keyPress.which == 45 || // Insert
keyPress.which == 46 || // Delete
keyPress.which == 144 // Num Lock
)
)
) ||
keyPress.which === undefined // normal character in IE < 9.0
) &&
keyPress.charCode !== 0 // not special character in Konqueror 4.3
) {
// Normal character
if (onNormal) onNormal.call(this, keyPress, event);
} else {
// Special character
if (onSpecial) onSpecial.call(this, event);
}
delete keyDown[event.keyCode];
};
})());
};
})(jQuery);
I never liked the key code validation. My approach was to see if the input have text (any character), confirming that the user is entering text and no other characters
$('#input').on('keyup', function() {
var words = $(this).val();
// if input is empty, remove the word count data and return
if(!words.length) {
$(this).removeData('wcount');
return true;
}
// if word count data equals the count of the input, return
if(typeof $(this).data('wcount') !== "undefined" && ($(this).data('wcount') == words.length)){
return true;
}
// update or initialize the word count data
$(this).data('wcount', words.length);
console.log('user tiped ' + words);
// do you stuff...
});
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<input type="text" name="input" id="input">
</body>
</html>