Hey guys,
Name input value should be entered as shown on credit card eg. 'John P Smith'. I'm trying to prevent 'Aaaaa B Ccccccc' being sent to the sever. Any suggestions appreciated. I'm pritty sure the var rep=regex is causing the script to hang on the first if it acctualy finds the lowercase repeated more than 2times and I realy need to check that lowercase isn't repeated sequentialy more than 2 times?

THE HTML

<p id="reply">Please enter your name as shown on credit card.</p>
<input type="text" id="name" name="name" class="required" value=" " \>

THE SCRIPT

//namechange function

function namechange()
{
var n=name.value;
n.split(' ').join(''); //get rid of extra white space;
var names=new Array();
names=n.split(' '); //set array delimeter ' ' to space
var first=names[0]; //also tried var first=names.slice(0,1);
var middle=names[1]; //also tried var middle=names.slice(1,2);
var last=names[2]; //also tried var last=names.slice(2,3);
var rep=/^[a-z].{3}$/; //if lowercase alpha repeated 3 times word isn't name need sequential regex!
if(names.length<3) //check that input isn't less than 3 words long ie. 'John P Smith'='John Smith'
{
reply.innerHTML='Your name must be 3 words long eg. John P Smith.';
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(names.length>3) //make sure input value not 'John P Smith Jr'
{
reply.innerHTML='Your name must be 3 words long eg. John P Smith.';
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(first.match(rep)) //check that lowercase not repeated 3 times should be sequential?
//once this gets picked up the reply remains the same onchange even if 'John P Smith' is entered?!!
reply.innerHTML='This is not a real name: '+first+'.';//ie. not 'Joooohn'
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(middle.length>=1) // Make sure middle is initialized ie. not 'John Paul Smith' works on it's own
{
reply.innerHTML='Please initialize your middle name '+middle+' eg. John P Smith.';
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(last.match(rep)) //check last for repetive lowercase should be sequential?
//if caught 'John P Smmmmith' reply returns 'This is not a real firstname: '+first+'.'??
{
reply.innerHTML='This is not a real last name: '+last+'. '; //ie. not 'Smmmmith'
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
else
{
reply.innerHTML='Thank you '+name.value+', card verification pending.';
name.style.color='blue'; 
return:true;
}
}

Yeah my javascript is getting better but my regex applied script sucks.:@:$

Recommended Answers

All 29 Replies

remove the join() part and try again.

n.split(' ').join(''); //get rid of extra white space;

-you are not getting rid of the white space, because there already isn't any. What you are doing there there is that you are taking the 'John P Smith' and converting it into a; [for your aim] an unusable 'JohnPSmith' string instead.

Troy III Thanks for the response. I'll check it out. The 'nomilize' function isn't suposed to take out all the space but suposed to reduce multiple spaces to one. I'll run it by itself and alert the value of name input onchange to find out. //name.split('2 white spaces').join('one white space');
In any case I'll find out.

Troy III Hey dude you gave the exact resonce sdleihssirhc gave at Sitepoint.com under the same thread title. His responce was exact and an awsome demonstration of instruction complete with jsfidel demo.http://jsfiddle.net/AZ5KB/. Great stuff. Now if I could only login to my webdeveloper.com account everybody might have a chance to view the subject.

Troy III One draw back is that AAaab B CCCccd passes so the regex still falls short and should be first letter only one uppercase and followed by more than two lower case letters but I'm guessing that the first uppercase letter should be automated in the array
//var first=names[0].length[0].toUpper(); or regex to set the first carachter to uppercase and the rest to lower and then test the string for more than one Uppercase and more than two lowercase?

Relax dude, nobody can write a program by hart in a single breath. You need to take it one step at the time, The solution from your link is quite complete -why don't you use that.

Troy III Your right guy but I'm realy into it right now and I'm already a week late. Turns out that //n.split(' ').join(''); did produce the correct //alert(n)= 'aaaaa p cccc'

no it didn't and can't.
and of course you don't alert the unprocessed string if you really like to know what that expression does to it,but the processed one. ie
alert( n.split(' ').join('') )

THE SCRIPT

if(names.length<3) //check that input isn't less than 3 words long ie. 'John P Smith'='John Smith'
{
reply.innerHTML='Your name must be 3 words long eg. John P Smith.';
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(names.length>3) //make sure input value not 'John P Smith Jr'
{
reply.innerHTML='Your name must be 3 words long eg. John P Smith.';
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(first.match(rep)) //check that lowercase not repeated 3 times should be sequential?
//once this gets picked up the reply remains the same onchange even if 'John P Smith' is entered?!!
reply.innerHTML='This is not a real name: '+first+'.';//ie. not 'Joooohn'
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(middle.length>=1) // Make sure middle is initialized ie. not 'John Paul Smith' works on it's own
{
reply.innerHTML='Please initialize your middle name '+middle+' eg. John P Smith.';
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;
}
if(last.match(rep)) //check last for repetive lowercase should be sequential?
//if caught 'John P Smmmmith' reply returns 'This is not a real firstname: '+first+'.'??
{
reply.innerHTML='This is not a real last name: '+last+'. '; //ie. not 'Smmmmith'
name.value='Error!'; //lower case 'r' repeated 3 times?
name.style.color='red'; 
return:false;

just a few remarks here, not so much about the coding, more about the logic you use.

1. if(names.length<3)
what's this for? I don't have a middle name, so if I were to type my name as it appears on my credit card, It would be rejected?
2. if(names.length>3)
about the same, I know people who have three 'first names', for instance:
John Jack Joan Smith (own name, name of the godfather and godmother). I'm not really sure how this appears on a credit card, just a thought.

as for the repeating letters:
do know that, even though this will be correct for about 99.9% of all names out there, since there are people willing to provide their offspring with the original names of (for instance) Superman (first name),or Park, Jurassic (complete name and no, not made up)
I think it's safe to assume there are names out there which have a name which would make that validation go haywire :)

stultuske Interesting point. I took it for granted, again that all card holder names consisted of 3 words minimum. Could you show me exactly how your name appears on your card?
Troy III once again you where correct about alerting the unaltered string but I had forgotten to mention that I added a function that automated the input value automatically so the alert would read 'John P Smith'.
Now that stultuske pointed out that a valid card name can have just two names/words I can change that if to //if(names.length<2)
easily enough. In any case the original thread was about matching or testing against patterns and I was stumped trying to test A-Z against matching sequential a-z charachters ie. 'Jjohn P Smith' vs 'John P Smith'. paul_wilkins at sitepoint.com pointed out that what I was trying to do would exclude names like 'Lloyd' which means that it's up to Verisign or Paypals etc. to validate the card name and my concern was over weighted and only relevant to the name stored on the house database. I didn't want the usual first and last name just one name that matched the one on the card!

well, if you want to continue with the name John P Smith, it would be just John Smith
I do have a first name, just no middle name, so I can't have an initial from that name :)

stultuske Got it, if length less than 2? Was it acctualy the name on your card? Does anybody have a two word name on their card?

paul_wilins at sitepoint.com had this to say

I had said:

In the end I think you're right. Eg. Lloyd and others would be excluded if what I was trying to do was accomplished. here are the two patterns I was trying to test with.
var AZ=/([A-Za-z])\1{1,}/;//couldn't figure out the correct syntac for A-Z followed by a-z matching
var az=/([a-z])\1{2,}/;

For the sake of completion, it seems that no regular expression can capture an uppercase followed by the same lowercase letter, unless you brute-force a solution with:
/^(Aa|Bb|Cc|...|Xx|Yy|Zz)/

A more elegant solution might be to do a case-insensitive check of the first two letters
/^([a-z])\1/i

Where ^ forces the regular expression to match at the first character, (...) captures a group or in this case, one character, \1 repeats what was found in the captured group, and the /.../i with the i flag makes it a case-insensitive search.

That won't guarantee that they follow the letter casing that you need, but if there is other code that deals with the casing then this would do the job.

You could also allow multiple initial letters, but just display a warning about it to let the user know about the situation, in case they have to correct things there, but allow them to submit it anyway.
"Name starts with duplicate characters. Please check that it is spelled correctly" for example.

stultuske Got it, if length less than 2? Was it acctualy the name on your card? Does anybody have a two word name on their card?

well, I only have a two 'word' name on my card, I just used the example of John Smith since that's been used all along in this thread. Off course, on my card it's not John Smith, but it's the same built: firstname (single word - no middle name initial) lastname
also, what I just thought about, the lastname can exist out of several words, too, and, there are some, for instance The Artist Formerly Known As Prince who once was just 'Prince', at that point, that was his official name, so that would also be on his card, I guess. (even later, he changed it to a symbol, so I have no clue how to test for that ;) )

paul_wilkins at sitepoint.com got the pattern/regex right now I can test both A-Z followed by a-z match with i flag and a-z repeated more than twice. I should take his advice as well and not pass 'Error!' to the input value but suggest they make a spelling check. 'Jooohn' is an error, so is 'Jjoohn' but 'Lloyd' is not an error.

stultuske
Thanks again, your input saved me and my client a whole school of problems though I'm not sure the special charachters are permited on merchant credit or debit cards, they might very well be. Paypals and Verisign etc. confirm or deny the purchase made on the card and the site supplies the cardholder information to them so an alphabetical field would be insufficient for any card names with special characters?
Originaly I was cutting out first and last name inputs, avoiding concacting and exsessive database fields etc. while maintaining direct functionality. I'm guessing I won't be shooting the client in the foot by using the alphabetical only field but it would be good to know what percentage of card holders have cards with names that have special characters.

This will extract you a list of pure legal names including the "O'Brian" type, and fully strip them from any kind of white-space [leading, trailing, and in-between].

/*b.b Troy III p.a.e*/
name.match(/\b[A-Za-z']+\b/g)

Than you can use
a three letter mach to return errors on individual parts, since it is true that no real name can contain Aaa Bbb or Cccc

/[a-zA-Z].{2}/

And you can stop there.

The first regexp will discard any part of input that contains illegal characters that can not constitute a true name and get rid of extra white spaces.

The second one will enable you sequentially check for 3x letter repetitions, on individual parts of the input so that you can return errors with the value tested on n[0]; n[1]; n[2]...

Yet this doesn't guard you from someones input like: "Abvgr X Drmge" -although I can't bet you that there isn't a person with that kind of name living somewhere in this world.

But atop it all - John P Smith may happen to be a real and completely valid name of the user - but that doesn't mean that he also has a card on his name or that particular name for a fact. So at the end of the day... -The only valid check is checking against the bank of client names and see if they match with the input given.

Troy III Wow again! The single Quote " ' " being permitted? Which of course is a legal card name character. I really have to add that one as no punctuation at all is presently permitted. Now I have to check and see if " ' " works with

//except only alphabetical characters in name strings
var alpha=/^[a-zA-Z]+([\s][a-zA-Z]+)*$/;
//except alphabetical characters and single quote like so?
var alpha=/^[a-zA-Z']+([\s][a-zA-Z']+)*$/;

Prevent 'Jjohn P Smith' may not be possible as paul_wilkins suggested ass it would prevent 'Lloyd P Smith'. Unless I had a list of names that had two sequential letters to compare which two letters to allow!

Case insensitive search at beginning of name for one sequentially repeated alpha.

//will prevent 'Lloyd P Smith' with this
var AZ=/^([a-z])\1/i;
//Prevent 'Llloyd P Smith' with this 
var AZ=/^([a-z])\[B]2[/B]/i;
//and I can write 'Error!' to the input value! Not "Please check spelling"

A list of names with double sequential letters would provide the letters that could be added or permitted with a not group in the regex?

//not 'l' for Lloyd or 'c' for McCain etc.
var AZ=/^([a-z][^l|c])\1/i;

Actually "McCain" breaks the automated first Character to upper case after the string is set to lower case? For sure they are legal card names.

Caps function.

/*thanks to Airshow at dani.web and modifications by OMA*/

function Caps(str)
{	
var a=str.toLowerCase().split(' ');//OMA added toLowerCase()?	
for(var i=0; i<a.length; i++)
{		
ch=a[i].charAt(0);	
//add var ch2=a[i].charAt(2); would add the upper case	to all
a[i]=a[i].replace(ch, ch.toUpperCase());
}	
return a.join(' ');
}

function nCaps(name)
{	
var f=document.getElementById ('name');	
if(f) 
{ 
f.value=Caps(f.value);
}
}

function namechange()
{
//name.value.toLowerCase(); avoided
nCaps();

So I guess that would have to be written in a regex or pattern to allow the third character of the last name to be upper case!
The Scots have money to.

paul_wilkins also pointed this out

How about where the name is empty, when people have only one word names for themself, such as Madonna or Cher.

Which means to test the var first I need to change if names less than 2 to equals 1 and come up with a none empty response?

Yeah I'd have to permit the third character of any of the names array strings to be upper case as in McCain which could be avoided by taking the toLowerCase out completely and make most of this post redundat unless I avoid the 'elegant' and force the sequentially repeated character class with regex/pattern.

Any suggestions appreciated:'(;)

Note that:
Names are and should be case insensitive, therefore: "john p smith" equals "John P Smith" wihich is equal to "jOHN p sMITH" since they all mark and point to same Person!
Meaning that you are wasting your attention on irrelevant things. Since this match should be case insensitive.

Second: No special chars exist on real personal names, therefore your regexp may and should discard all portions of names which may contain: "_Smith", "@Smith", "Sm1th" and similar. var name = " J0hn P ., Smith " should return an clean and only ["P", "Smith"] as the only valid part[s] of input in the list.

In this regard you can try the following code strategy:

var name = " J0hn P  .,   Smithtttttt ";
/*b.b Troy III p.a.e*/
var test = name.match(/\b[A-Za-z']+\b/g);

// '
// should return a list containing: ["P", "Smithtttttt"] only! 
// than you should immediately correct the input to: 

userInput.value = test.join(" ");

// displaying: P Smithtttttt
// so he/she can see that the unaccepted part was rejected 
// and continue without a break to: 

for(x in test)if(test[x].match(/([a-z])\1{2}/))alert("Please check your spelling on: "+test[x]);
// which will present your client with the alert message saying: 
"Please check your spelling on: Smithtttttt"

No need to bother with lower case upper case letters at all...

well, Troy made an excellent point by stating the only correct validation is by validating the name using the names in the db of the bank(s) that are being used.

that way, you just compare a text element against the contents of a (huge) collections of text elements.

Troy III It's starting to look like you maybe right.

var AZ=/^([a-km-z])\1/i;
//this prevents L from testing for repeated sequential as in 'Lloyd'

I was looking for a regex that found repeated sequential 'cc' and changed it to 'cC' for Scoties like McCdougle that could be added in the final 'else' statement

var cC=/if value contains cc second c = C/; //REGEX??
else
{
brq.innerHTML='Thank you '+name.value.match(cC)+', card verification pending.';
name.value=name.value.match(cC);//TO FORCE THE OUTPUT?
name.style.color='#2c3664';
return true;
}
}

that's all irrelevant since legally names and words may contain double letters in one and in alternate case like Cc, cc, too, but not or never Ccc, or ccc+, so you don't need to check or reject doublets, but triplets. My secondary regexp will take care to eliminate triplets of user input, whereas the primary one will do more than 90% of all cleaning required.

Either way no matter what you add to this, the only thing you may achieve is to lessen input errors, -which in the end [as already pointed out on my previous posts] may, or may not match with existing valid card names. -You can however achieve to store names which (at least theoretically) may belong to real individuals with cards.

Have fun

that's all irrelevant since legally names and words may contain double letters in one and in alternate case like Cc, cc, too, but not or never Ccc, or ccc+, so you don't need to check or reject doublets, but triplets. My secondary regexp will take care to eliminate triplets of user input, whereas the primary one will do more than 90% of all cleaning required.

Either way no matter what you add to this, the only thing you may achieve is to lessen input errors, -which in the end [as already pointed out on my previous posts] may, or may not match with existing valid card names. -You can however achieve to store names which (at least theoretically) may belong to real individuals with cards.

Have fun

HEY TROY III I ALSO REALIZED THIS AND POSTED ON SITEPOINT.

paul_wilkins Just realized

Please enter your name as shown on credit or debit card.

Excludes all lower case alpha input of a-z! All are upper case on mine and probably all other cards. In any case the following didn't work on the 'cc' in McCdonalds anyway.

function Caps(str)
{	
var a=str.split(' ');//removed toLowerCase
for(var i=0; i<a.length; i++)
{		
ch=a[i].charAt(0);//Probably needs a regex?
C1=a[i].charAt(1);
C2=a[i].charAt(2);		
a[i]=a[i].replace(ch, ch.toUpperCase());
if(C1=='c'&&C2=='c')
{
a[i]=a[i].replace(C1, C1.toLowerCase());//becomes lower case 'c'
a[i]=a[i].replace(C2, C2.toUpperCase());//remains lower case 'c'
return a.join(' ');
}
else
{	
return a.join(' ');
}
}
}
function nCaps(name)
{	
var f=document.getElementById ('name');	
if(f) 
{ 
f.value=Caps(f.value);
}
}

function namec()
{
nCaps();

Question, if a persons name is 'Edward van der Sar', wouldn't it show on the card as 'EDWARD VAN DER SAR' just like 'JOHN P SMITH'?

propably, yes.
what you can do is set the entire name to lower- or uppercase, and do the same for the name you compare it to.

Question, if a persons name is 'Edward van der Sar', wouldn't it show on the card as 'EDWARD VAN DER SAR' just like 'JOHN P SMITH'?

It doesn't matter how will it show on the card itself - what matters is how will it be stored on the database. The case doesn't matter - it will be overridden one way or the other. All uppercase or all lowercase. Since human names are case insensitive by nature.
Yet the most common action is toUpperCase before storing. But that doesn't matter Because anytime you try to compare you will first uppercase them or at least match up with the "i" flag set. Therefore, once again before diving in further speculation:

var check = 
/*b.b Troy III p.a.e*/
function(name, userInput){
	var test = name.match(/\b[A-Za-z']+\b/g); 
	userInput.value = test.join(" ");
		for(x in test)if(test[x].match(/([a-z])\1{2}/))alert("Please check your spelling on: "+test[x]);
	};
<your input onkeyup="check(this.value, this)">

try this and tell us whats up, because I'm pretty sure that this is all you need prior to on before submit action.
------
sorry onkeyup is not the perfect choice here I overlooked the fact that I'm removing the trailing spaces first, try it with onbeforesubmit or utilize the function with a conditional keycode input to halt the check if it happens to be a spacebar use return

Hey Troy III it isn't clear but appears that the name value excludes any other characters than A-Z for the Embossed Name on the card. So the question I have still is, are these examples correct. Even though validation is done on an exact match bases? It would be nice to know the exact pattern to match.

  1. Edward Peter van Der Saar= EDWARD P VAN DER SAAR?
  2. Ronald Paul MacCdonald= RONALD P MACCDONALD?
  3. Ronald Paul Steven MacCdonald= RONALD P STEVEN MACCDONALD?
  4. Ronald Paul Steven David MacCdonald= RONALD P STEVEN MACCDONALD? DAVID not permitted?
  5. Patrick Peter O'Brien= PATRICK P OBRIEN without " ' "?
  6. Celebrity card names with additional characters & symbols can't be used on line?

I have to confirm all of this with my buddy in the credit card department at my bank before I proceed. Any body else knowing differently should also feel free to chirp in. Thanks for any consideration in advance.

Actually the number of names in a name embossed on the card has not been determined and probably relies on the total string length which doesn't account for Initializing the middle name as in 'John P Smith'. This caused me to believe that only three names where permitted which didn't account for 'Edward Peter van Der Saar' etc.

paul_wilkins at Sitepoint.com provided this info on Credit card magnetic strips http://www.abacus21.com/Magnetic-Strip-Encoding-1586.html

OK. I asked just about every where about the syntax of the name of the card holder as held in the magnetic strip commonly referred to as 'Track #1' and the way it would be stored in the new smart card chips. Mostly the banks are rightly concerned that any such query ranks as a fraudulent endeavor and refuse to give out such information at all. The International Card Manufacturers Association www.icma.com is equally secretive and only gives information to it's members who are fully invested in the promotion and development of new technology. Their on line magazine as yet has no archive search ability as for sure the exact subject may very well have been addressed by one of their many experts in the field. The only information that I could obtain showing the name of card holder held in track #1 of a magnetic strip card had to do with a police inquiry into fraud related to hotel room card keys in which the police had used wireless devices and software to read cards and the name of the card holder stored on track #1. Inadvertently they had read the credit card info as well as the hotel room key cards so rights of privacy where called into question and the investigation itself was investigated revealing the name of card holder in the track#1 as all uppercase A-Z with each name/word delimited by '\' only. Unfortunately this did not reveal the case for "O'BRIEN" and the apostrophe though ISO and ANSI information clearly lists many 'Special' characters it is not clear that they are received as raw 'data' or serve as flags or delimiters? Will post back my final script.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.