AngularJS only characters directive - javascript

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.

Related

How to allow all characters but number from input

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)

Method to support integer input with replace and Regex

I have an input field which I only want positive and negative integers to be allowed in. I track their typing with onkeyup() since that's the most consistent across browsers. The real issue comes in when trying to replace non-numeric characters without replacing the dash at the start.
if(e.keyCode < 48 || e.keyCode > 57) {
var data = e.target.value;
if(e.target.value.match(/^[-]?/))
e.target.value = '-' + data.substr(1).replace(/\D*/, "");
else
e.target.value = data.replace(/\D*/,"");
}
Basically what's happening here is I ignore when they type in numbers, but for everything else attempt to replace anything they may have added that isn't a number. The issue with this right now is when I press Backspace, the dash comes back right away for some reason.
E.g. My input field has this: - When I press backspace. My input field stays as this: -
WORKING CODE:
if(e.keyCode < 48 || e.keyCode > 57) {
var data = e.target.value;
if(e.target.value.match(/^[-]+/))
e.target.value = '-' + data.substr(1).replace(/\D/, "");
else { console.log('else');
e.target.value = data.replace(/\D/,"");
}
}
Change
if(e.keyCode < 48 || e.keyCode > 57) {
to
if((e.keyCode < 48 || e.keyCode > 57) && e.keyCode!=8) {
Then you'll ignore the backspace character just like a number, which won't cause any other issues.
I just figured out the issue, Renegade has a decent method, but I made a Regex mistake. It should be this:
if(e.target.value.match(/^[-]+/))
Rather than:
if(e.target.value.match(/^[-]?/))
Since the latter will give true even if the dash does not exist. ? means 0 or 1 matches, + is 1 or more.

keycode and fromCharCode in javascript

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
});

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.

JavaScript - Test for an integer

I have a text field that allows a user to enter their age. I am trying to do some client-side validation on this field with JavaScript. I have server-side validation already in place. However, I cannot seem to verify that the user enters an actual integer. I am currently trying the following code:
function IsValidAge(value) {
if (value.length == 0) {
return false;
}
var intValue = parseInt(value);
if (intValue == Number.NaN) {
return false;
}
if (intValue <= 0)
{
return false;
}
return true;
}
The odd thing is, I have entered individual characters into the textbox like "b" and this method returns true. How do I ensure that the user is only entering an integer?
Thank you
var intRegex = /^\d+$/;
if(intRegex.test(someNumber)) {
alert('I am an int');
...
}
That will absolutely, positively fail if the user enters anything other than an nonnegative integer.
For real int checking, use this:
function isInt(value) {
return !isNaN(parseInt(value,10)) && (parseFloat(value,10) == parseInt(value,10));
}
The problem with many int checks is that they return 'false' for 1.0, which is a valid integer. This method checks to make sure that the value of float and int parsing are equal, so for #.00 it will return true.
UPDATE:
Two issues have been discussed in the comments I'll add to the answer for future readers:
First, when parsing string values that use a comma to indicate the decimal place, this method doesn't work. (Not surprising, how could it? Given "1,001" for example in the US it's an integer while in Germany it isn't.)
Second, the behavior of parseFloat and parseInt has changed in certain browsers since this answer was written and vary by browser. ParseInt is more aggressive and will discard letters appearing in a string. This is great for getting a number but not so good for validation.
My recommendation and practice to use a library like Globalize.js to parse numeric values for/from the UI rather than the browser implementation and to use the native calls only for known "programmatically" provided values, such as a string parsed from an XML document.
use isNaN(n)
i.e.
if(isNaN(intValue))
in place of
if (intValue == Number.NaN)
UPDATE
I have fixed the code that had an error and added a var called key to store the key pressed code using keyCode and which, that depend of the browser.
var key = e.which || e.keyCode;
Thanks Donald.McLean :)
If you want to check if you are writing numbers while typing (and avoid writing other characters into your input field), you can use this simple function and you can define the elements allowed (this include whatever you want to filter). In this way you can choose not only integers but for example a certain group of characters. The example is based in jQuery to attach it to an input field.
$('#myInputField').keypress(function(e)
{
var key = e.which || e.keyCode;
if (!(key >= 48 && key <= 57) && // Interval of values (0-9)
(key !== 8) && // Backspace
(key !== 9) && // Horizontal tab
(key !== 37) && // Percentage
(key !== 39) && // Single quotes (')
(key !== 46)) // Dot
{
e.preventDefault();
return false;
}
});
If you use other key than the defined, it won't appear into the field. And because Angular.js is getting strong these days. this is the directive you can create to do this in any field in your web app:
myApp.directive('integer', function()
{
return function (scope, element, attrs)
{
element.bind('keydown', function(e)
{
var key = e.which || e.keyCode;
if (!(key >= 48 && key <= 57) && // Interval (0-9)
(key !== 8) && // Backspace
(key !== 9) && // Horizontal tab
(key !== 37) && // Percentage
(key !== 39) && // Single quotes (')
(key !== 46)) // Dot
{
e.preventDefault();
return false;
}
});
}
});
But what happens if you want to use ng-repeat and you need to apply this directive only in a certain number of fields. Well, you can transform the upper directive into one prepared to admit a true or false value in order to be able to decide which field will be affected by it.
myApp.directive('rsInteger', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
if (attrs.rsInteger === 'true') {
element.bind('keydown', function(e)
{
var key = e.which || e.keyCode;
if (!(key >= 48 && key <= 57) && // Interval (0-9)
(key !== 8) && // Backspace
(key !== 9) && // Horizontal tab
(key !== 37) && // Percentage
(key !== 39) && // Single quotes (')
(key !== 46)) // Dot
{
e.preventDefault();
return false;
}
});
}
}
}
});
To use this new directive you just need to do it in a input type text like this, for example:
<input type="text" rs-integer="true">
Hope it helps you.
I did this to check for number and integer value
if(isNaN(field_value * 1) || (field_value % 1) != 0 ) not integer;
else integer;
Modular Divison
Example
1. 25.5 % 1 != 0 and ,
2. 25 % 1 == 0
And
if(field_value * 1) NaN if string eg: 25,34 or abcd etc ...
else integer or number
function isInt(x) {return Math.floor(x) === x;}
If your number is in the 32bit integer range, you could go with something like:
function isInt(x) { return ""+(x|0)==""+x; }
The bitwise or operator forces conversion to signed 32bit int.
The string conversion on both sides ensures that true/false want be matched.
Nobody tried this simple thing?
function isInt(value) {
return value == parseInt(value, 10);
}
What's wrong with that?
You may use isInteger() method of Number object
if ( (new Number(x)).isInteger() ) {
// handle integer
}
This method works properly if x is undefined or null. But it has poor browser support for now
I found the NaN responses lacking because they don't pick up on trailing characters (so "123abc" is considered a valid number) so I tried converting the string to an integer and back to a string, and ensuring it matched the original after conversion:
if ("" + parseInt(stringVal, 10) == stringVal) { alert("is valid number"); }
This worked for me, up until the numbers were so large they started appearing as scientific notation during the conversion.
...so of course this means you could enter a number in scientific notation, but checking minimum and maximum values as well would prevent that if you so desire.
It will of course fail if you use separators (like "1,000" or "1.000" depending on your locale) - digits only allowed here.
If (enteredAge < "1" || enteredAge > "130") ......
Simple and it works....until they develop immortality

Categories