focus after onchange event and regex test not working

J

jab3

Hello. I"m new to this group, and to JavaScript in general, so please
forgive me if I breach local etiquette. I'm trying to implement some
client-side 'dynamic' validation on a form. I'm having a couple of
problems, which I'll try to describe. But this e-mail will only
reproduce one of them, in a "short" example. What I'm generally doing
is having each form entry contained in a div, which as a label, an
input with some event handlers, and a span that provides contextual
help. Example:

<div class="form_entry">
<label>Username:</label>
<input name="uname" id="uname" type="text" onfocus="focus_event"
onblur="blur_event"
onchange="verify_new_username()" />
<span id="uname_help"></span>
</div>

The focus_event and blur_event functions are taken out for brevity.
That may be addressed in another email; they just hide and un-hide
default text in the span.

The specific problem I'm asking about here involves focusing and
altering innerHTML after a regex check, apparently with an onchange
handler. The code example will follow at the end of the message. But
what I would like to happen is, the person enters and e-mail address.
After entering the first e-mail address, the onchange event handler
calls a function that runs a basic regex against the email to see if it
fits some basic parameters. If the test fails, I would like to change
the span for that entry, then keep focus there until the e-mail
validates. The problem is that the focus won't stay there.

Here are some things I've figured out with tinkering. If I change the
event handler to onblur instead of onchange, it works with IE, but not
Firefox. But it needs to be onchange because onblur is already being
used to hide the <span /> help text when the user moves focus. Also,
if I change innerHTML and focus calls to a separate function, then use
setTimeout('other_function', 0), then the focus works in both Firefox
and IE, but the innerHTML doesn't change in IE. Also, and this code
will be included, all of this works when all I do is test 2 values for
equality, for instance with passwords. It seems to be the regex check
that screws things up.

If ANYONE can assist me with this, I'd be very much obliged. Of
course, I have bigger problems, particularly as far as incorporating
this into the big form and the onfocus/onblur events, but first things
first.

Here's the code for e-mail validatoin:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1" />
<title>Form Entry Test</title>
<style type="text/css">
div.form_entry {
padding: 5px 0px;
vertical-align: top;
}
div.form_entry label {
font-size: .95em;
float: left;
width: 112px;
margin: 0 5px 0 0;
text-align: right;
}
.no_display {
display: none;
}
.show_usage {
background-color: #FFFAB2;
color: #0000FF;
font-family: Verdana, Helvetica, sans-serif;
font-size: .75em;
padding: 2px 1px;
}
</style>
<script type="text/javascript">
function switch_back_to_email1()
{
var email_help = document.getElementById('email1_help');

document.forms["acct_form"].mb_email1.value = '';
document.forms["acct_form"].mb_email1.focus();
email_help.className = 'show_usage';
email_help.innerHTML = 'Invalid e-mail address';
}

function is_email_valid(this_email)
{
var new_acct_form = this_email.form;
// really basic test...
var reMail = /^(?:\w+\.?)*\w+@(?:\w+\.)+\w+$/;

var email_help = document.getElementById('email1_help');

if (!reMail.test(this_email.value)) {
// this setTimeout works for focusing in both IE/Firefox. But IE won't
// change the innerHTML
// setTimeout('switch_back_to_email1()', 0);
new_acct_form.mb_email1.focus();
email_help.innerHTML = 'Invalid e-mail address';
email_help.className = 'show_usage';
return false;
}
return true;
}

function verify_email(this_email)
{
var new_acct_form = this_email.form;
var email1 = acct_form.mb_email1.value;
var email2 = acct_form.mb_email2.value;

if (email1 != email2) {
var email_help = document.getElementById('email1_help');

new_acct_form.mb_email1.focus();
new_acct_form.mb_email2.value = '';
email_help.innerHTML = 'The emails are <strong>'+
'not equal<' +
'/strong>.';
email_help.className = 'show_usage';
return false;
}
}
</script>
</head>
<body>
<form id="acct_form" name="acct_form"
method="post" action="#"
onsubmit="return validate_new_account(this)">

<div class="form_entry">
<label>Username: </label>
<input name="mb_uname" id="mb_uname_new" maxlength="25"
size="15" value="" type="text"
onchange="verify_new_username()" />
<span id="uname_help" class="no_display">&nbsp;</span>
</div>
<div class="form_entry">
<label>E-mail: </label>
<input name="mb_email1" id="mb_email1" maxlength="50" size="25"
type="text"
onchange="is_email_valid(this)" />
<span id="email1_help" class="no_display">&nbsp;</span>
</div>
<div class="form_entry">
<label>E-mail: </label>
<input name="mb_email2" id="mb_email2" maxlength="50" size="25"
type="text"
onchange="verify_email(this)" />
<span id="email2_help" class="no_display">&nbsp;</span>
</div>
<div class="form_entry">
<input type="submit" name="action" value="Create" />
</div>
</form>

----------------------------------------------------------------------

And here's the code for an example that works:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
<title>Form Entry Test</title>
<style type="text/css">
div.form_entry {
padding: 5px 0px;
vertical-align: top;
}
div.form_entry label {
font-size: .95em;
float: left;
width: 112px;
margin: 0 5px 0 0;
text-align: right;
}
.no_display {
display: none;
}
.show_usage {
background-color: #FFFAB2;
color: #0000FF;
font-family: Verdana, Helvetica, sans-serif;
font-size: .75em;
padding: 2px 1px;
}
</style>
<script type="text/javascript">
function verify_passwords(pass_field)
{
var new_acct_form = pass_field.form;
var pass1_help = document.getElementById('upass1_help');
var pass1 = MothForm.mb_upass1.value;
var pass2 = MothForm.mb_upass2.value;

if (pass1 != pass2) {
new_acct_form.mb_upass1.value = '';
new_acct_form.mb_upass2.value = '';
new_acct_form.mb_upass1.focus();
upass1_help.innerHTML = 'The passwords are '+
'<strong>not
equal<'+'/strong>.';
upass1_help.className = 'show_usage';
}
}

</script>
</head>
<body>
<form id="acct_form" name="acct_form"
method="post" action="#"
onsubmit="return validate_new_account(this)">

<div class="form_entry">
<label>Username: </label>
<input name="mb_uname" id="mb_uname_new" maxlength="25"
size="15" value="" type="text"
onchange="verify_new_username()" />
<span id="uname_help" class="no_display">&nbsp;</span>
</div>
<div class="form_entry">
<label>Password: </label>
<input name="mb_upass1" id="mb_upass1" maxlength="25" size="15"
value="" type="password" />
<span id="upass1_help" class="no_display">&nbsp;</span>
</div>
<div class="form_entry">
<label>Password: </label>
<input name="mb_upass2" id="mb_upass2" maxlength="25" size="15"
type="password"
onchange="verify_passwords(this)" />
<span id="upass2_help" class="no_display">&nbsp;</span>
</div>
<div class="form_entry">
<input type="submit" name="action" value="Create" />
</div>
</form>

-------------------------------------------------------------------

I know that code is going to look like crap, but I did what I could to
try to make it work.

Thanks!
jab3
 
R

RobG

jab3 said:
Hello. I"m new to this group, and to JavaScript in general, so please
forgive me if I breach local etiquette. I'm trying to implement some
client-side 'dynamic' validation on a form. I'm having a couple of
problems, which I'll try to describe. But this e-mail will only
reproduce one of them, in a "short" example. What I'm generally doing
is having each form entry contained in a div, which as a label, an
input with some event handlers, and a span that provides contextual
help. Example:

<div class="form_entry">
<label>Username:</label>
<input name="uname" id="uname" type="text" onfocus="focus_event"
onblur="blur_event"
onchange="verify_new_username()" />
<span id="uname_help"></span>
</div>

The focus_event and blur_event functions are taken out for brevity.
That may be addressed in another email; they just hide and un-hide
default text in the span.

The specific problem I'm asking about here involves focusing and
altering innerHTML after a regex check, apparently with an onchange
handler. The code example will follow at the end of the message. But
what I would like to happen is, the person enters and e-mail address.
After entering the first e-mail address, the onchange event handler
calls a function that runs a basic regex against the email to see if it
fits some basic parameters. If the test fails, I would like to change
the span for that entry, then keep focus there until the e-mail
validates.

No, don't. Do not trap the user in a field until they 'get it right',
that kind of behaviour drives users bezerk.

It might be that your regular expression is not appropriate for their
e-mail address, or they may have partially completed the field and gone
off do to something else (like check what their e-mail address is).
Further, the fact that the e-mail address fits your regular expression
does not make it valid. And if the user turns off scripting you can't
validate anything at the client, they can enter whatever they like.

By all means provide a helpful message onchange if you think the address
is wrong, but that's it.

You should deal with it at the server - send a confirmation e-mail to
the supplied address. If it bounces or they don't respond within say 48
hrs, scratch them.

The problem is that the focus won't stay there.

I wouldn't call that a problem, I'd say it's a bonus. :)
Here are some things I've figured out with tinkering. If I change the
event handler to onblur instead of onchange, it works with IE, but not
Firefox. But it needs to be onchange because onblur is already being
used to hide the <span /> help text when the user moves focus. Also,

You can call more than one function from the same event.

<input onblur="func01(); func02(); ..." ...>

[...]
 
J

jab3

RobG said:
jab3 said:
[ some snipped ]

After entering the first e-mail address, the onchange event handler
calls a function that runs a basic regex against the email to see if it
fits some basic parameters. If the test fails, I would like to change
the span for that entry, then keep focus there until the e-mail
validates.

No, don't. Do not trap the user in a field until they 'get it right',
that kind of behaviour drives users bezerk.

That's funny. As I was typing that message out and got to that
sentence, I started thinking about it. And I started realizing holding
a user in a field could turn into a bad thing. But, I decided I still
wanted to find out what I was doing wrong to keep it from re-focusing,
so I left it as is. :)
It might be that your regular expression is not appropriate for their
e-mail address, or they may have partially completed the field and gone
off do to something else (like check what their e-mail address is).
Further, the fact that the e-mail address fits your regular expression
does not make it valid. And if the user turns off scripting you can't
validate anything at the client, they can enter whatever they like.

By all means provide a helpful message onchange if you think the address
is wrong, but that's it.

I agree, and I was always planning on doing validation on the
server-side too, just because 'bad' people could submit information
outside of the form period. But I do like the idea of some dynamic
validation on the client's machine to cut down on server/client
communication. I am going to reassess this e-mail validation lock,
however. Like the comment in the code says, the validation is basic,
which is why I ask for the email again, and then I may send a response
for verification. Who knows. I do like the idea of setting a simple
message that suggests the email is invalid. At least let 'em know I'm
on to 'em. haha
You should deal with it at the server - send a confirmation e-mail to
the supplied address. If it bounces or they don't respond within say 48
hrs, scratch them.



I wouldn't call that a problem, I'd say it's a bonus. :)

HA. Yeah, you're probably right.
You can call more than one function from the same event.

<input onblur="func01(); func02(); ..." ...>

Now that I did not know. That's helpful, and obvious enough I suppose.
:) Just didn't want to confuse the bubbling or propagating or
whatever.

Anyway, thanks for the help and advice!

-jab3
 
R

RobG

jab3 said:
RobG said:
jab3 wrote: [...]
By all means provide a helpful message onchange if you think the address
is wrong, but that's it.


I agree, and I was always planning on doing validation on the
server-side too, just because 'bad' people could submit information
outside of the form period. But I do like the idea of some dynamic
validation on the client's machine to cut down on server/client
communication. I am going to reassess this e-mail validation lock,
however. Like the comment in the code says, the validation is basic,
which is why I ask for the email again, and then I may send a response
for verification. Who knows. I do like the idea of setting a simple
message that suggests the email is invalid. At least let 'em know I'm
on to 'em. haha

Make sure the message lets them know what you consider valid. The usual
idea is to have on-screen help that unobtrusively suggests a format
wherever validation is to be applied. It should be in the HTML and its
visibility should not be script-dependent (though you might use script
to highlight it if validation fails).

[...]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top