The Un-Official Proxomitron Forum

Full Version: Javascript onBlur()
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I've got a simple form:

Code:
<html xmlns="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<title>Phone and E-mail</title>
<script type="text/javascript" src='validtest.js'></script>
</head>
<body>
<FORM name="servform" onsubmit="return checkform();" method="post">
<table cellpadding=0 cellspacing=5 border=0><tr>
    <td align="left">Your E-mail:</td><td align="left">
<input type="text" value="" name="email" onBlur="checkemail(this.value)" /></td>
</tr><tr>
    <td align="left">Your Phone Number:</td><td align="left">
<input type="text" value="" name="cust_phone" onBlur="checkPhone(this.value)" /></td>
</tr>
<tr>
<td>
<input type="submit" value="Send" />
</td>
</tr>
</table>
</form>
</body>
</html>

I've written some JavaScript that used for field level validation:
Code:
// validtest.js

function checkform() {
var msgtext="";

if (document.servform.email.value == "") {
msgtext = msgtext + "Required! E-mail Address: field is empty\n";
}

if (document.servform.cust_phone.value == "") {
msgtext = msgtext + "Required! Phone Number: field is empty\n";
}

if(msgtext != "") {
    alert(msgtext);
    return false;
}

return true;
}

// E-mail

function checkemail(yourEmail){
if(yourEmail.match(/^.[^<>@]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/)){
   return true;
} else {
   alert("Enter a valid E-mail Address.\n example: [email protected]");
    document.servform.email.select();
    document.servform.email.focus();
   return false;
}
}

// phone number

function checkPhone(cust_phone){
if(cust_phone.match(/^\(?\d{3}\)?\s|-\d{3}-\d{4}$/)) {
   return true;
} else {
   alert("Enter a valid Phone Number: \n example: ###-###-####");
    document.servform.cust_phone.select();
    document.servform.cust_phone.focus();
   return false;
}
}

The problem is : If one enters data that turns out to be invalid when using the TAB key or using the mouse-click on the next field which also fires onBlur() this causes the ALERT to fire in an endless loop. The objective is -- if the field data is not valid then focus must return to the element that contains the error to enable the user to correct.

Anyone have the solution that fixes my code?

Thanks.
mozerd;

[edit] See further posts below, corrections have been made. [/edit]

This one was really persnickety!! Banging Head

I finally found it, though. And, I have a suggestion or two to help you along the way. First, the solution:

[code snippet]
<span style='font-family:arial'><span style='font-size:13pt;line-height:100%'>onblur="check___(this.value)"</span><span style='color:red'><span style='font-size:15pt;line-height:100%'>;</span></span></span>
[/code snippet]

See that semi-colon at the end? That's your trouble. The HTML form was not processing that as a command to execute the function, and wait for a return. Instead, it was proceeding as soon as the System Focus was returned to the Browser Window, away from the Alert Dialog box (caps added for emphasis).

I found this out by importing your code into my editor, and then executing it in my browser. From that, I saw that the errors actually cycled through the input boxes, and that was my clue. I ended up by adding a third field, which proved my theory was correct, and then I filled the first two fields correctly. That made the error stick with only the unfilled box (or incorrectly filled, your choice). After reading through the code very thoroughly, I found the missing semi-colon(s). That was insidious, I'll tell you. [smoke]

Now, some suggestions.

1) Reverse your select and focus statements. That seemed to make things flow more smoothly on my screen. The idea is, you focus on the field, then you select everything within it.

2) When passing your parameter (this.____), use the value's name instead. While the "this" name is correct, it lends itself to errors more easily. Giving the exact name reduces the chances of error, plus it makes things easier to track in your mind when re-reading the code for the 50th time. :P

3) Your body statement should have an onload statement in order to force the focus to the first box on the form. Maybe you already have one, and just didn't show it in your snippet, but I mention it just in case. Smile!

4) I'm under the impression that the Form tag requires (as in, mandatory) an Action modifier. If you do nothing else with this form, just point that action right back at the same page, like this: action="document.url()". This just makes the Submit button act like a Reset button, otherwise, no effect.

5) For the love of Mike, man, lay out your code in a readable manner! Banging Head The grammatical syntax of spewing parenthesis and brackets all over the place makes for no fun at all when reading code. In this coder's perception of how things should be done, all opening and closing delimiters must be lined up in the same vertical column. Some of your brackets were lined up in Column 1, but look at your 'else' statements - UGH! Doing this makes for fast "first pass" troubleshooting, being able to assert proper opening and closing delimiters like that.

After that, the next thing to do is indent everything under a given section. This will also make the code easier to read, as you know just where everything falls in relation to that uppermost tag. When doing multiple choice IF statements with lots of Else's, indentation will keep your Else statements in line with their proper IF sections. I suggest two spaces for each level, but YMMV.

I know that examples abound of how to do all this incorrectly, but I just consider the source - that most ugly layout was first started by some Twinkie-junkies that were never programmers in any sense of the word, they just wanted to be cool like real coders, only they "didn't get it". Sigh.

And what I'm saying here applies to both HTML and javascript. I've zipped up and attached an example of how I think your code should look, at least the snippets you presented to us. Admittedly, I'm being anal-retentive about this, but on the other hand, I did fix your problem, so I'm hoping you'll excuse my boorish behavior. <_<

Next!


Oddysey

[edit] The attached file has been deleted from here, and replaced in a later post below. [/edit]
Oddysey Wrote:This one was really persnickety!!&nbsp; Banging Head
I finally found it, though.&nbsp; And, I have a suggestion or two to help you along the way.&nbsp; First, the solution:
Sorry, young man, your solution does not work Banging Head . But thank you for the effort and the constructive suggestions you have made. Rocker

Try the following in the form I provided and include the missing ";" as you suggested;

In the email field enter an incorrect email address something like <span style='color:blue'>Oddysey<>hotmail.com</span> then TAB or mouse-click on the Phone number field

and you will end up with an endless loop that only can be stopped by killing the process.

PLEASE remember THAT my objective was to find a solution that prevented the endless loop regardless of the number of onBlur="check_____(name)"; existed on a form.
mozerd;

[edit] Once again, see further postings below for more details. [/edit]

Well, my face is not quite covered with egg, but it is rather scowling. Wink [blush]

I don't rightly know what's going on, but I can tell you this - if I remove the semi-colons, then the loop executes infinitely. With the semi-colons, and with a correct email address, the loop never starts - you are taken back to the custPhone field, which I believe is what you want.

After seeing your reply, I tried it again, doing as you suggested, and the *#%)@^&# infinite loop started up again! Banging Head So, I reinserted my alerts (Which reminds me, I apologize to one and all - I accidentally left an alert in the "good" portion of the email check function. Sorry 'bout that!), and watched the action. Wouldn't you know it, but when I hit the Tab (or Enter, but not a mouse click), the focus moves forward two fields, not just one.

I can't explain that, but I can fix it. Simply set up your error-checking function to return the user to the desired field after making sure the current field is good. I've rezippd the file, and appended it here. I've also removed the original file from my post above. Someone besides mozerd has downloaded it, so I hope whoever it is gets this newer version too! Big Teeth

Does this cure your ills, me bucko? Whistling


Oddysey

[edit] This file has also been deleted for unsatifactory operation. See the following postings for the reasons, and a new file. [/edit]
Oddysey Wrote:Well, my face is not quite covered with egg, but it is rather scowling.&nbsp; Wink&nbsp; [blush]

Does this cure your ills, me bucko?&nbsp; Whistling
Thanks for your effort -- however your solution does not work. If one steps into the email filed [because I will not use an on load etc] and leaves it blank by either TABBING or MOUSE-CLICKING on the next field we get an endless loop ... and if an invalid email is entered in the email field and one TABS or mouse-clicks into the next field the same endless loop exists. When one validates data at the field level one has to be prepared for any condition the user chooses. They may NOT want to honor the TAB order that may have been set for them.

My original posted code tries to cover the Validity of the Form and the Fields. For example if you invoke my SEND button without filling any of the fields [blank fields] and alert sounds and the form goes nowhere while at the same time providing information as to why, In a production form I would have a action statement that when a form is completed properly it then would go to the next step like FormMail.pl sitting on the server.

Al I am trying to do is figure out how to prevent the endless loop from annoying the heck out of you me and the goal post. Big Teeth
OK, I found the problem and changed the code that now works:
I added the following input to the working example:
Code:
<tr>
<td align="left">Your Full Name:</td><td align="left">
<input type="text" value="   " name="realname" onFocus="this.select()" onBlur="checkName(this.value)" size="55" />
</td>
</tr>
The added Validation script:
Code:
function checkName(realname)
  {
  if(realname == "   ")
    {
    return true;
    }
   else
    {
    if(realname.match(/(\w+)\s*(\w+)/))  // first name last name //
      {
      return true;
      }
     else
      {
      alert("Enter Your Full Name: \n Hint: Your First and Last Name");
      document.servform.realname.focus();
      return false;
      }
    }
  }

The Problem was a missing right parenthesis on the match statement -- those missing parenthesis drive me nuts! Banging Head And I also removed the comma from the match string. Also removed a redundant \s from the match string and what you see above is correct. Wink
mozerd;

One reason might be that your onBlur calls checkname, and your function is named checkName. That capital letter makes a difference, as you probably already know.

Beyond that, I do have some questions about your regexp, and one or two suggestions;

Why are you using the \v? Do you expect the user to be inserting a vertical tab? Or did your fingers cramp up and hit a 'v' where you wanted a 'w'? :o (Here's my favorite resource for all the regexp special characters used in javascript.)

Also, since the comma is not a special character (according to the above website), it appears to me that you are requiring one in the string, between the two names. However, in your Alert to the user you don't give him a clue about said comma. Why's that, pray tell? Come on, it's not nice to mess with the user's head; be nice to the poor laddie, and give him a proper hint. [lol] But unless I missed a big change in writing styles since I entered this cave they call the Curmudgeon's home, the last I heard, it was either LastName comma space FirstName, or it was FirstName space LastName, without any commas.

And to cap it all off, I'm certain that removing that comma would make the second \s redundant, no?

One possible explanation for the comma is that you will later split the field into two components, and you'd like to use it as a delimiter. Great, except why not let the user do that for you now, with two fields? Just a guess, and a thought.


Oddysey
mzoerd;

Aarrrggghhh, you posted right as I was composing my reply. I hate it when that happens, don't you? Sad Big Teeth

Anyway, I see that you also found the naming thing, so I was a bit late on that one, but I'm posting again because I forgot to include something in my last message. I had thought of it, then got carried away with that regexp business and forgot all about it.

As usual (meaning, as with most programmers), when the job's done, you walk away for a break. Then you come back, review your work to make sure you haven't forgotten anything, and <span style='color:red'>WHAM!</span> it hits you right between your baby blues - a screw-up so embarrassing that it makes you wanna run right out and buy one of these.

Anyway, I found a spot where I failed to exercise all due care and caution. Don't worry, it's not bad, it's just a redundancy. Note the section of javascript that switches focus. It then also selects the field's contents, right? Well, every time the field regains focus, the contents are selected anyway, thanks to the onFocus event in the HTML code. The HTML code is necessary (initially, to insure that the 3 spaces go away if the user does anything at all), so the javascript select statement can be safely removed.

Pure oversight on my part. Because the code all worked as expected, I saw no problem, so I didn't look for anything like this. Sigh. I know I'm getting old, but does it have to show so brazenly like this? [angry] [/mumble]

I'll update the zip file in my previous post, but you don't need to re-d/l it, I've told you what the change is right here, and you can either leave it or change it as you desire.


Oddysey
Oddysey, just wanted to reinforce the fact that your contribution to the onBlur() issue was/is very helpful -- Thank you again. Cheers
Reference URL's