Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 394
  • Last Modified:

Using OnChange Event for validation doesn't work as documented

I am using the OnChange event to validate user input when the field is exited.  The JavaScript documentation I found on Microsoft's site indicates that if the event's return value is set to false, the field will retain focus until the return value is set to true.

However, after an alert displays the error message, the focus goes to the browser's address bar.  I can click on the field with the error and correct the data but this is an extra step.  

I can't click on any other field so it effectively prevents me from continuing until I have corrected the data.

I set up a simple form to test the problem, here is the code:

head>
<title>Test OnChange Event</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<script language="JavaScript">
function checkName (theField, emptyOK)
{   if (checkName.arguments.length == 1) emptyOK = false;
    if ((emptyOK == true) && (theField.value.length == 0)) return event.returnValue = true;
    else
    { if ((theField.value.length > 30) || (theField.value.length < 3))
       {
       alert("The name must be at least 3 characters and no more than 30 characters long.");
       event.returnValue = false;          
       }      
      else event.returnValue = true;
    }
}
</script>

<form name="form1" method="post" action="">
  <p>Enter First Name:
    <input type="text" name="firstname" onchange="checkName (this, false);">
  </p>
  <p> Enter Last Name:
    <input type="text" name="lastname" onchange="(this, false);">
  </p>
  <p>&nbsp;</p>
</form>
</body>
</html>

Thanks in advance for any assistance.
0
eadecker
Asked:
eadecker
  • 4
  • 3
  • 2
  • +1
1 Solution
 
elstcbCommented:
Does adding the following after the alert command help? (Change FormName and FieldName as appropriate)

Document.FormName.FieldName.focus()
Document.FOrmName.FieldName.select()

Steve
0
 
davlun20080Commented:
Your original script worked for me in IE5, forcing me to edit the field before I could continue and it did keep the focus of the client on the field.  

However, if you want to give the users the chance to exit out of the validation, you can do something like this:

<HTML>
<head>
<title>Test OnChange Event</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<script language="JavaScript">

     function checkName (theField, emptyOK)
     {
          if (checkName.arguments.length == 1)
          {
               emptyOK = false;
          }
          if ((emptyOK == true) && (theField.value.length == 0))
          {    
               event.returnValue = true
          } else {
               if ((theField.value.length > 30) || (theField.value.length < 3))
               {
                    if (confirm("The name must be at least 3 characters and no more than 30 characters long.\n\nCLick ok to go back and edit this field,\nor cancel to continue.\n"))
                    {    
                         event.returnValue = false
                    } else {
                         event.returnValue = true
                    }
               }
          }
     }
</script>

<form name="form1" method="post" action="">
 <p>Enter First Name:
   <input type="text" name="firstname" onchange="checkName (this, false);">
 </p>
 <p> Enter Last Name:
   <input type="text" name="lastname" onchange="(this, true);">
 </p>
 <p>&nbsp;</p>
</form>
</body>
</html>


0
 
elstcbCommented:
<script language="JavaScript">
function checkName (theField, emptyOK)
{   if (checkName.arguments.length == 1) emptyOK = false;
   if ((emptyOK == true) && (theField.value.length == 0)) return event.returnValue = true;
   else
   { if ((theField.value.length > 30) || (theField.value.length < 3))
      {
      alert("The name must be at least 3 characters and no more than 30 characters long.");
      theField.focus();
      theField.select();
      event.returnValue = false;          
      }      
     else event.returnValue = true;
   }
}
</script>

<form name="form1" method="post" action="">
 <p>Enter First Name:
   <input type="text" name="firstname" onchange="checkName (this, false);">
 </p>
 <p> Enter Last Name:
   <input type="text" name="lastname" onchange="(this, false);">
 </p>
 <p>&nbsp;</p>
</form>
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
daniel_cCommented:
Or, probably put the validation in OnSubmit event?

<head>
<title>Test OnChange Event</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<script language="JavaScript">
function checkName (theField, emptyOK)
{   if (checkName.arguments.length == 1) emptyOK = false;
   if ((emptyOK == true) && (theField.value.length == 0)) return event.returnValue = true;
   else
   { if ((theField.value.length > 30) || (theField.value.length < 3))
      {
          alert("The name must be at least 3 characters and no more than 30 characters long.");
          return false;
      }      
          return true;
   }
}

function validateIt()
{
     if (!checkName(document.form1.firstname, false)) {
          document.form1.firstname.focus();
          return false;
     }
     
     if (!checkName(document.form1.lastname, false)) {
          document.form1.lastname.focus();
          return false;
     }
     alert("Pass!")
     return true;
}
</script>

<form name="form1" method="post" action="" onSubmit="return validateIt()">
 <p>Enter First Name:
   <input type="text" name="firstname" onchange="checkName (this, false);">
 </p>
 <p> Enter Last Name:
   <input type="text" name="lastname" onchange="(this, false);">
 </p>
 
 <p><input type=submit></p>
</form>
</body>
</html>
0
 
eadeckerAuthor Commented:
I have tried numerous variation of focus() and select() in an effort to get it select the field that triggered the event instead of the browser's address bar.

It is interesting that it did work for one of you.  It makes me wonder if there might be a browser setting that is causing the browser's address bar to be selected.  Any thoughts on what setting that would be?  I am also using IE 5.  I have not tried any other browsers, I wanted to get this one working first.

I thought about using onsubmit to do the validation.  The real form that I need this for is quite large with lots of fields to validate.  As a user, I would prefer to be notified on the spot that the data I entered is invalid rather than go through entire form before finding out that I've made errors.  

Additionally, the onsubmit can become very annoying if there are multiple errors on the form.  I could list all the errors in one message, but then it is likely that the user will overlook one.  I could only show one error at a time, but then the user has to go through several iterations of submitting the form and correcting data.

I could always fall back to onsubmit if I can't get the onchange to work.

Thanks for the comments.

0
 
davlun20080Commented:
I am using version 5.00.2920.0000 if that helps any.

Have you tried using the old style validations where you just check the information and focus the form element if there is a problem, rather than relying on the returnCode?

0
 
elstcbCommented:
The focus and select worked fine for me and that's the way I'd expect it to be done, can't think of any other way to reselect the field at any rate.

I'm using IE 5.00.3103.1000

I've noticed some versions of IE5 acting strange before - one of the versions at work doesn't draw the page properly and stuff. I'm not saying it is a version issue but it is possible - I can't think of any settings that would affect it either apart from possibly HTTP1.1 -  I have this option turned on.

HTH,

Steve
0
 
elstcbCommented:
Just had a brainwave.... maybe!

Have you tried using setTimeout?

Replace:
theField.focus();
with:
setTimeout(theField.focus()',10);

Steve
0
 
eadeckerAuthor Commented:
I downloaded a more recent version of IE and it does appear to be a version issue.

I had tested the page on two different browsers one with IE 5.00.28 something and 128 bit encryption and another with IE 5.00.2920.0000 and 56 bit encryption.  In both instances, the focus would return to the browser's address bar instead of the field.

I upgraded one browser to IE 5.00.3105.0106 with 128 bit encryption and the test page began working as I had originally expected it to.  The focus was returned to the field that was generating the onchange event.

I did try the other suggestion to use the setTimeout.  That did prevent the browser's address bar from being selected but then nothing was selected.  I still had to click on the field before I could begin editing it.

Thank you everyone for your help.
0
 
eadeckerAuthor Commented:
A friend discovered a work around for the browser versions that don't return focus to the appropriate field.  It does use setTimeout but adds one more step.  In the validation function, a global variable to assigned the field that caused the error.  Then the setTimeout calls a function that sets focus to the field stored in the global variable.  It seems that older versions of IE 5 were "forgetting" which field they were working with when they returned from the validation function.

Here is the adjusted code for the test form I created.

<html>
<head>
<title>Test OnChange Event</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<script language="JavaScript">
var ErrorField

function refocus ()
{ if (ErrorField != null)
  {
    ErrorField.focus();
    ErrorField = null;
  }
}

function checkName (theField, emptyOK)
{   if (checkName.arguments.length == 1) emptyOK = false;
    if ((emptyOK == true) && (theField.value.length == 0)) return event.returnValue = true;
    else
    { if ((theField.value.length > 30) || (theField.value.length < 3))
       {
           alert("The name must be at least 3 characters and no more than 30 characters long.");
        ErrorField = theField;
        theField.focus();
        theField.select();
           event.returnValue = false;          
       }      
      else event.returnValue = true;
    }
}
</script>

<form name="form1" method="post" action="">
  <p>Enter First Name:
    <input type="text" name="firstname" onchange="if (!checkName (this, false)) setTimeout('refocus();', 200);">
  </p>
  <p> Enter Last Name:
    <input type="text" name="lastname" onchange="if (!checkName (this, false)) setTimeout('refocus();', 200);">
  </p>
  <p>&nbsp;</p>
</form>
</body>
</html>
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

  • 4
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now