Thanks for your help with my earlier question:
How to find all instances and display in alert
Now I discover that I need to include some invalid character validation.
I'm trying to figure out how to include a set of regex invalid characters as part of the validation that will also show up in the same alert/textbox/whatever as the "too long/too short" validation.
So, I have a textbox which users will type or paste comma separated values such as AAAAAAA,BBBBBBB,CCCCCCCC,DDDDDDDD
And they cannot be more or less than seven characters long and they can only include certain characters.
I currently have have two separate pieces of Javascript that I'm trying to now combine:
var Invalidchars = "1234567890!##$%^&*()+=[]\\\';./{}|\":<>?";
for (var i = 0; i < document.getElementById("TextBox1").value.length; i++) {
if (Invalidchars.indexOf(document.getElementById("TextBox").value.charAt(i)) != -1){
alert
and this
var val = document.getElementById("Textbox1").value,
err = $.grep(val.split(','), function(a) { return a.length != 7; });
if (err.length) {
alert("All entries must be seven (7) characters in length. Please correct the following entries: \n" + err);
return false;
}
return true;
Any help is much appreciated!
=================================================
SOLUTION
Took a while, but using Tenub's code (which didn't quite combine my two sets code, but was close enough), I finally figured out how to merge my two sets of code into one. Here's the code if anyone is ever interested in using it:
var val = document.getElementById("TextBox1").value,
err = $.grep(val.split(','), function(a) {return (a.length = (!/^[^0-9!##$%^&*()+=;.\/\{}|:<>\\?\[\]\'\"]{7}$/.test(a)));});
if (err.length){
document.getElementById("DIV1").style.display = "inline-block";
document.getElementById("TextBox2").value = err.join(',');
return callback (false);
}
document.getElementById("DIV1").style.display = "none";
return true;
The answer is as simple as it is elegant:
var val = document.getElementById("Textbox1").value;
if(!/[^0-9!##$%^&*()+=;./{}|:<>?\[\]\\\'\"]{7}/.test(val)) {
// handle invalid value
}
This tests that the string is 7 characters in length and does not contain any character within the brackets after the "^" (also some characters are escaped with a "\").
You can test in console:
/[^0-9!##$%^&*()+=;./{}|:<>?\[\]\\\'\"]{7}/.test('adfFDKZ'); // returns true
/[^0-9!##$%^&*()+=;./{}|:<>?\[\]\\\'\"]{7}/.test('adf(DKZ'); // returns false
Try this:
/*
* This regex matches all the invalid characters. I escaped the
* special characters.
*/
var regex = /.*[0-9!##\$%\^&\*\(\)\+=\[\]\\';\./\{\}\|":\<\>\?]+.*/;
var text = document.getElementById("TextBox1").value;
/* Test for match...much faster than a for-loop under any circumstances */
if (text.matches(regex)) {
alert("Invalid characters present. Please correct the input");
return false;
}
/* split on delimiter */
var err = $.grep(val.split(','), function(a) { return a.length != 7; });
if (err.length) {
alert("All entries must be seven (7) characters in length. Please correct the following entries: \n" + err);
return false;
}
Please tell me if there are any bugs in this. Also, the only real way to test for this in one step is to set up an enormously long regex. Also, with only one check, it would make it a little harder to guide the user to make the right correction. I will mention that.
Related
I have a function to validate phone number in a contact form, but i need to be able to put in "xxx xxx xxxx" for example, and not just "xxxxxxxx"
The number format should be:
xxx xxx xxxx
xxx-xxx-xxxx
xxx.xxx.xxxx
function validatePhone() {
var phone = document.getElementById("phone").value;
if (phone.length == 0) {
var w = document.getElementById("phoneError").textContent;
alert(w);
return false;
}
if (phone.length != 10) {
var r = document.getElementById("phoneError").textContent;
alert(r);
return false;
}
// THIS IS NOT WORKING
if (
!phone.match(/^[0-9]{10}$/) ||
!phone.match(/^\d{3}-\d{3}-\d{4}$/) ||
!phone.match(/^\d{3}.\d{3}.\d{4}$/)
) {
var t = document.getElementById("phoneError").textContent;
alert(t);
return false;
}
}
Two things: First, you are mixing up AND and OR:
if (
!phone.match(/^[0-9]{10}$/) ||
!phone.match(/^\d{3}-\d{3}-\d{4}$/) ||
!phone.match(/^\d{3}.\d{3}.\d{4}$/)
) {
As soon as one of the conditions fails, it will return false (which is basically always). You want this if to apply, when none of the expressions matches, e.g. when all of them are false. Therefor, you have to use && instead of ||. Not a AND not b AND not c.
Second: your 3rd regex is a bit off: . means "any character", so this regex would also match "123x123y1234". You need to escape the dot with a backslash: /^\d{3}\.\d{3}\.\d{4}$/
Also, you can improve this code significantly. You have 5 conditions, which could all be handled in one (if you want to allow the input of "123.123 234", otherwise you will have to do it using 3 regex). And for just checking if a regex matches a string, you maybe should use test(), because it is just slightly faster (it won't matter in your case, but just out of principle).
You can reduce your code to:
if (/^\d{3}[\s-.]\d{3}[\s-.]\d{4}$/.test(document.getElementById("phone").value) === false) {
alert (document.getElementById("phoneError").textContent);
return false;
}
I've been doing a lot of searching, chopping and changing, but I'm...slightly lost, especially with regards to many of the regex examples I've been seeing.
This is what I want to do:
I have a text input field, size 32.
I want users to enter their telephone numbers in it, but I want them to enter a minimum of 10 numbers, separated by a single comma. Example:
E.g. 1
0123456789,0123456789 = right (first group is >=10 numbers, second group = >=10 numbers & groups are separated by a single comma, no spaces or other symbols)
E.g. 2
0123456789,,0123456789 = wrong (because there are 2 commas)
E.g. 3
0123456789,0123456789,0123456789 = right (same concept as E.g. 1, but with 3 groups)
I've got the following, but it does not limit the comma to 1 per 10 numbers, and it does not impose a minimum character count on the number group.
$(document).ready(function(){
$("#lastname").keypress(function (e) {
//if the letter is not digit then display error and don't type anything
if (e.which != 8 && e.which != 0 && String.fromCharCode(e.which) != ','
&& (e.which < 48 || e.which > 57)) {
//display error message
$("#errmsg").html("Digits Only").show().fadeOut("slow");
return false;
}
});
});
Preferably, I'd like to warn the user of where they are going wrong as well. For example, if they try to enter two commas, I'd like to specifically point that out in the error, or if they havent inserted enough numbers, i'd like to specifically point that out in the error. I'd also like to point out in the error when neither a number or a comma is inserted. I'd like to ensure that the tab, and F5 keys are not disabled on the keyboard as well. And very importantly, I'd like to specifically detect when the plus or addition key is used, and give a different error there. I think I'm asking for something a little complex and uninviting so sorry :/
The example code I provided above works pretty well across all browsers, but it doesn't have any of the minimum or maximum limits on anything I've alluded to above.
Any help would be appreciated.
As far as a regex that will check that the input is valid (1-3 phone numbers of exactly 10 digits, separated by single commas), you can do this:
^\d{10}(,\d{10}){0,2}$
Try like the below snippet without Regex
var errrorMessage = '';
function validateLength (no) {
if(!no.length == 10) {
return false;
}
return true;
}
function validatePhoneNumbers (currentString, splitBy) {
if(currentString) {
var isValid = true,
currentList = currentString.split(splitBy);
// If there is only one email / some other separated strings, Trim and Return.
if(currentList.length == 1) {
errrorMessage = 'Invalid Length in Item: 1';
if(validateLength( currentString.trim() )) isValid = false;
}
else if(currentList.length > 1) {
// Iterating mainly to trim and validate.
for (var i = 0; i < currentList.length; i++) {
var listItem = currentList[i].trim();
if( validateLength(listItem ) ) {
isValid = false;
errrorMessage = 'Invalid Length in Item:' + i
break;
}
// else if for some other validation.
}
}
}
return isValid;
}
validatePhoneNumbers( $("#lastname").val() );
My code isn't working, can someone please tell me what the problem is?
I'm guessing it's the for loop, but I cannot find the problem.
<html>
<body>
<script>
username = prompt("Please enter a your username:");
for (var i = 0; i < username; i++) {
if(isFinite(username.charAt(i))) {
result = true;
document.write("The username consists of one or more numbers." + BR);
}
else {
result = false;
document.write("The username must consist of one or more numbers." + BR);
}
}
</script>
</body>
</html>
You have two problems in your code:
In the for loop, use the length of the variable to establish the stop condition
for (var i = 0; i < username.length; i++)
BR is not defined
Working code: http://jsfiddle.net/f643fr4w/
From the output I can probably assume you just want to check if username consists of at least one number, actually: a digit.
// iterate over the input
for (var i = 0; i < username.length; i++) {
// check if it is a number (not a digit but that's the same here)
if (isFinite(username.charAt(i))) {
result = true;
// The requirement "one or more numbers" is fulfilled,
// we can break out of the loop
break;
}
else {
result = false;
}
// print something according to "result"
if(result === true){
document.write('The username consists of one or more numbers.');
} else {
document.write('The username must consist of one or more numbers.');
}
}
You have to go over the full length of the string to find out if there's no number but not if you want to find out if there is any number in it.
Now, if you want to test if it consists of only digits you have to reword the requirements, they are a bit too ambiguous now.
Additional hints:
you need to check the input, you always have to check user input!
you need to be aware that JavaScript strings are UTF16. Rarely a problem but gets easily one if you iterate over JavaScript strings.
String.charAt() returns a character, not a number. Don't rely on the automatic conversions in JavaScript, you way too easily shoot yourself in the foot if you rely on it but also if you don't, so be careful.
please don't use document.write, use either the console if available or change the text-node of an HTML element.
With these points in mind you may get something like this:
// make a list of digits
var digits = ['0','1','2','3','4','5','6','7','8','9'];
// ask the user for a username
var username = prompt("Please enter a your username:");
// check input
if (username.length === 0) {
console.log('no username given');
} else {
for (var i = 0; i < username.length; i++) {
// indexOf searches for the same type, that's why the digits above
// are strings with quotes around them
if (digits.indexOf(username.charAt(i)) >= 0) {
result = true;
// The requirement "one or more numbers" is fullfilled,
// we can break out of the loop
break;
}
else {
result = false;
}
}
// print something according to "result"
if (result === true) {
console.log('The username consists of one or more numbers.');
} else {
console.log('The username must consist of one or more numbers.');
}
}
The above is one variation of many and could easily give rise to a heated discussion on some forums (not here! Of course not! ;-) ) but I hope it helps.
Use a regex for such shenanigans:
var username = prompt("username plz kk thx");
var result = /[0-9]/.test(username);
document.write("The username " + (result ? "consists" : "must consist") + " of one or more numbers");
I have a form where a user inserts the GPS coordinates of a location to a corresponding photo. Its easy enough to filter out invalid numbers, since I just have to test for a range of (-90, 90), (-180, 180) for lat/long coordinates.
However, this also means that regular text is valid input.
I've tried changing the test pattern to
var pattern= "^[a-zA-Z]"
and is used in the function to detect alphabetical characters
$(".lat").keyup(function(){
var thisID= this.id;
var num = thisID.substring(3, thisID.length);
var thisVal = $(this).val();
//if invalid input, show error message and hide save button
if (pattern.test(thisVal)){
$("#latError"+num).fadeIn(250);
$("#save"+num).fadeOut(100)
}
else { //otherwise, hide error message and show save
$("#save"+num).fadeIn(250);
$("#latError"+num).fadeOut(100);
}
});
However, this doesn't work as Firebug complains that pattern.test is not a function What would solve this issue?
This is what i use in my project:
const regexLat = /^(-?[1-8]?\d(?:\.\d{1,18})?|90(?:\.0{1,18})?)$/;
const regexLon = /^(-?(?:1[0-7]|[1-9])?\d(?:\.\d{1,18})?|180(?:\.0{1,18})?)$/;
function check_lat_lon(lat, lon) {
let validLat = regexLat.test(lat);
let validLon = regexLon.test(lon);
return validLat && validLon;
}
check_lat_lon(-34.11242, -58.11547) Will return TRUE if valid, else FALSE
I hope this will be usefull to you!
Do you need to use regex? Consider the following:
var val = parseFloat(lat);
if (!isNaN(val) && val <= 90 && val >= -90)
return true;
else
return false;
How about the pattern -?[0-9]{1,3}[.][0-9]+ then you parseInt and check the range as you said before.
test() is a method of the RegExp object - you're running it on a string, so will fail.
Enclose your pattern in a RegExp literal (/pattern/), so
var pattern= /^[a-zA-Z]/
That will get rid of the errors you're getting, but you have a separate issue with regards to a) whether your pattern is correct for what you want it to do; b) whether you need REGEX at all.
REGEX acts on strings - it cannot be used to determine whether a number is within a given range (unless that range is 0-10 inclusive).
#flem's answer shows the best way to approach what you're doing - no REGEX needed. The call to parseInt() will catch non-numeric characters since it will return NaN if the value contains any.
#paul flemming gave a great answer, this answer extends his and includes longitude and uses typescript.
I would suggest this in place of regex for speed and simplicity.
Since, parseFloat takes a string and returns a number isNaN check isn't needed. This function allows a string or a number and converts it to string for parseFloat and will then do the simple threshold tests against +-90 & +-180.
function isValidLatAndLong(lat: number |string, lon:number|string){
const num1 = "" +lat; //convert toString
const num2 = "" +lon;
if (parseFloat(num1) <= 90 && parseFloat(num1) >= -90 && parseFloat(num2) <= 180 && parseFloat(num2) >= -180){
return true;
}
else{
return false;
}
}
How to write a regular expression in javascript that must follow the conditions
All segment in the DN address should follow the sequence cn=<name>,ou=<name>,o=<bic8>,o=swift
All segments should be separated with ,.
The DN address should have maximum of 100 characters.
No space is allowed.
Minimum of 2 and maximum of 10 segments are allowed in a DN address.
The <name> part must contain minimum of 2 characters and maximum 20 alphanumeric characters. The characters should be in lower case. Only one special character is allowed to be used i.e. -(Hypen).
The DN address will have maximum 2 numbers. The <name> part can contain maximum of 2 numerical digits.
Thanks in advance
I think .split() is a lot easier to use in this case.
First split the entire string on the ,'s and then split every separate segment of the resulting array on the ='s.
Especially on a well defined spec as this, split is more then enough to handle it.
Untested code follows, don't blame me if it blows up your computer:
var parseDn(str)
var m = /^cn=(.*?),ou=(.*?),o=(.*?),o=swift$/.exec(str);
if (!m) { return null; } // (a) and (b).
if (s.length > 100) { return null; } // (c).
if (/\s/.exec(s)) { return null; } // (d).
var x = {cn:m[1], ou:m[2], o:m[3]};
var isValidName = function(s) { return (/^[a-z-]{2,20}$/).exec(s); }
if (!isValidName(x.cn) || !isValidName(x.ou) || !isValidName(x.o)) {
return null; // (f).
}
var countNumbers = function(s) { return s.replace(/\D/g, "").length; }
if (countNumbers(x.cn)>2 || countNumbers(x.ou)>2 || countNumbers(x.o)>2) {
return null; // (g).
}
return x; // => {"cn":"name", "ou":"name", "o":"bic8"}
}
Note that (e) and a few of the points regarding "segments" are completely unchecked since the description is vague. But this should get you started...