//  <form onSubmit="
//  this.firstName.nospaces = true;
//  this.firstName.description = 'First Name';
//  this.surname.description = 'Surname';
//  this.address1.description = 'Address Line 1';
//  this.city.description = 'City';
//  this.email.description = 'Email';
//  this.email.email = true;
//  this.dob.dob = true;
//  this.dob.description = 'Date of Birth (DD/MM/YYYY)';
//  return verify(this);"
//  method="post" action="example.6-8.php"> 
// *** different bit of code.
//	<input type="password" name="formPassword1" onChange="
//    thesame(formPassword1.value, formPassword2.value, 'passwords');"    
//    size=10>

function isblank(s) {
  for(var i = 0; i < s.length; i++) {
     var c = s.charAt(i);
     if ((c != ' ') && (c != '\n') && (c != '\t'))
        return false;
  }
  return true;
}

// This is the function that performs <form> validation.  
// It will be invoked from the onSubmit() event handler.
// The handler should return whatever value this function
// returns.
function verify(f) {
  var msg;
  var empty_fields = "";
  var errors = "";

  // Loop through the elements of the form, looking for all
  // text and textarea elements that don't have an
  //  "optional" property defined.  Then, check for fields
  // that are empty and make a list of them.
  // Also, if any of these elements have a "min" or a "max"
  // property defined, then verify that they are numbers 
  // and that they are in the right range.
  // Put together error messages for fields that are wrong.
  for(var i = 0; i < f.length; i++) {
     var e = f.elements[i];

     if (((e.type == "text") || (e.type == "textarea")) && !e.optional) {
        // first check if the field is empty
        if ((e.value == null) || (e.value == "") || isblank(e.value)) {
           empty_fields += "\n        " + e.description;
           continue;
        }

        // Now check for fields that are supposed 
        // to be numeric.
        if (e.numeric || (e.min != null) || (e.max != null)) {
           var v = parseFloat(e.value);
           if (isNaN(v) || ((e.min != null) && (v < e.min)) || ((e.max != null) && (v > e.max))) {
              errors += "\n- The field " + e.description + " must be a number";
              if (e.min != null)
                 errors += " that is greater than " + e.min;

              if (e.max != null && e.min != null) 
                 errors += " and less than " + e.max;
              else if (e.max != null)
                 errors += " that is less than " + e.max;

              errors += ".\n";
           } // if (isNaN(v) || ((e.min != null) && (v < e.min)) || ((e.max != null) && (v > e.max))
        } // if (e.numeric || (e.min != null) || (e.max != null))

        // Now check for fields that are supposed 
        // to be emails.
        // Not exactly as described in RFC 2822, but 
        // a rough attempt of the form "local-bit@domain-bit"
        if (e.email && !isblank(e.value)) {
           var seenAt = false;
           var append = "";
           for(var j = 0; j < e.value.length; j++) {
              var c = e.value.charAt(j);
              if ((c == ' ') || (c == '\n') || (c == '\t'))
                 append += "\n           - not contain white-space";
              if ((c == '@') && (seenAt == true))
                 append += "\n           - contain only one @";
              if ((c == '@'))
                 seenAt = true;
           } // for(var j = 0; j < e.value.length; j++)

           if (seenAt == false)
              append += "\n           - contain exactly one @";
           if (append)
              errors += "- The field " + e.description + " must: " + append;
        } // if (e.email && !isblank(e.value))

        // Now check for fields that are supposed 
        // to be DOBs.
        if (e.dob && !isblank(e.value)) {
           var slashCount = 0;
           var append = "";
           var addedError1 = false;
           var addedError2 = false;

           for(var j = 0; j < e.value.length; j++) {
              var c = e.value.charAt(j);

              if ((c == '/'))
                 slashCount++;

              if (c != '/' && (c < '0' || c > '9') && addedError1 == false) {
                 addedError1 = true;
                 append +=  "\n           - must contain only numbers " + "and forward-slashes";
              } // if (c != '/' && (c < '0' || c > '9') && addedError1 == false)
           } // for(var j = 0; j < e.value.length; j++)

           if (j != 10 || slashCount != 2)
              append += "\n           - must have the format DD/MM/YYYY";
           if (slashCount != 2)
              append += "\n           - must contain two slashes";
           if (append)
              errors +=  "- The field " +  e.description + " must: " + append;
        } // if (e.dob && !isblank(e.value))

        // Now check for fields that are supposed 
        // not to have spaces
        if (e.nospaces) {
           var seenAt = false;
           var append = "";

           for(var j = 0; j < e.value.length; j++) {
              var c = e.value.charAt(j);

              if ((c == ' ') || (c == '\n') || (c == '\t'))
                 errors += "- The field " + e.description + " must not contains white-space";
           } // for(var j = 0; j < e.value.length; j++)
        } // if (e.nospaces)

     } // if (type is text or textarea) and !optional
  } // for each character in field

  // Now, if there were any errors, then display the
  // messages, and return true to prevent the form from
  // being submitted.  Otherwise return false
  if (!empty_fields && !errors) 
     return true;

  msg  = "------------------------------------------------------\n\n"
  msg += "The form was not submitted because of the following error(s).\n";
  msg += "Please correct these error(s) and re-submit.\n";
  msg += "------------------------------------------------------\n\n"

  if (empty_fields) {
     msg += "- The following required field(s) are empty:" + empty_fields + "\n";
     if (errors)
        msg += "\n";
  } // if (empty_fields)
  msg += errors;
  alert(msg);
  return false;
} // function verify(f)

function thesame(value1, value2, description) {
  if (((value1 != null) || (value1 != "")) && value2 != "" && value1 != value2) {
       alert("The " + description + " must be identical.");
       return (false);
  } // if (((value1 != null) || (value1 != "")) && value2 != "" && value1 != value2)
  return (true);
} // function thesame(value1, value2, description)
