// validate.js
// 10/23/2008
//

// Form validation routines
// NOTE: NOTE:  The comments labeled IE are the "right" code according
// to the W3C DOM standard.  The code left in is what "almost" works
// in IE7.

var xhtmlNS = "http://www.w3.org/1999/xhtml";

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;
} // isBlank()

function addErrorMsg(errBx, msg) {
// IE  var newP = document.createElementNS(xhtmlNS, "p");
  var newP = document.createElement("p");
  // IE  newP.setAttributeNS(null, "class", "FormErrors");
  newP.setAttribute("class", "FormErrors");
  var txt = document.createTextNode(msg);
  newP.appendChild(txt);
  errBx.appendChild(newP);
  return true;
} // addErrorMsg()

// Verification function.
// Returns TRUE if the form may be submitted, false if there is an
// error.  Error messages are written to a div tag named "ErrorBox".
function validate(f) {
   var msg;
   var emptyFields = new Array();  // Array of field nodes
   var numericErrors = new Array(); // Array of error messages
   var emailErrors = new Array(); // Array of field nodes
   var errorBox = document.getElementById("ErrorBox");
   if (errorBox == null) {
     alert("Could not find ErrorBox Div.");
     return false;
   }

   // Clear the error box
   // IE   errorBox.setAttributeNS(null, "class", "NoError");
   errorBox.setAttribute("class", "NoError");
   var cn=errorBox.firstChild;
   while (cn != null) {
     errorBox.removeChild(cn);
     cn = errorBox.firstChild;
   }

   // Loop through the elements of the form, looking for all text and 
   // textarea elements that don't have an "optional" attribute
   // set to "true", then check the fields tha are empty and make a list of
   // them.  Also, if any of these elements have a "min" or "max"
   // attribute defined, then verify that the values are numbers and in
   // range.  If  element has a "numeric" attribute defined, verify
   // that it is a number, but don't check it's range.  If element has
   // an "email" attribute on it, check that it looks like a valid
   // E-mail address.
   for (var i=0; i < f.length; i++) {
     var e = f.elements[i];
     if (((e.type == "text") || e.type == "textarea")) {
       // Check for empty field
       if ((e.value == null) || (e.value == "") || isBlank(e.value)) {
         if (e.getAttribute("optional") != "true") {
           // add to list of blank fields
           emptyFields[emptyFields.length] = e;
           continue;
         }
       }
       else if ( (e.getAttribute("numeric") == "true") || 
                 (e.getAttributeNode("min") != null) || 
                 (e.getAttributeNode("max") != null)) {
         // Check for valid number
         var v = parseFloat(e.value);
         if (isNaN(v) ||
             (v < parseFloat(e.getAttribute("min"))) ||
             (v > parseFloat(e.getAttribute("max"))) ) {
           var m = "The field " + e.name + " must be a number";
           if (e.getAttributeNode("min") != null) {
             m += " that is greater than " + e.getAttribute("min");
             if (e.getAttributeNode("max") != null)
               m += " and is less than " + e.getAttribute("max");
           }
           else if (e.getAttributeNode("max") != null)
             m += " that is less than " + e.getAttribute("max");
           numericErrors[numericErrors.length] = m;
         }
       }
       else if (e.getAttribute("email") == "true") {
         // Check for reasonable E-mail address.
         // We're just going to check that we've got an '@' in
         // there with a '.' after it.  It would be nice to be
         // able to check for a valid domain name, but we won't
         // go that far.
         var atFound=0;
         var goodEmail = false;
         for (var i=0; i < e.value.length; i++) {
           if (atFound == 0) {
             if (e.value.charAt(i) == '@')
               atFound = i;
           }
           else {
             if ( (e.value.charAt(i) == '.') &&
                  (i > atFound+2) )
               goodEmail = true;
           }
         }
         if (!goodEmail)
           emailErrors[emailErrors.length] = e;
       }
     }
   }

   // If there are errors, plug messages into the ErrorBox
   if ((emptyFields.length > 0) || (numericErrors.length > 0) ||
       (emailErrors.length > 0)) {
//   IE   errorBox.setAttributeNS(null, "class", "Error");
     errorBox.setAttribute("class", "Error");
     for (var i=0; i < emptyFields.length; i++)
       addErrorMsg(errorBox, "The '"+emptyFields[i].getAttribute("label")+"' field is required.");
     for (var i=0; i < numericErrors.length; i++)
       addErrorMsg(errorBox, numericErrors[i]);

     for (var i=0; i < emailErrors.length; i++)
       addErrorMsg(errorBox, "The field '"+emailErrors[i].getAttribute("label")+"' does not contain a valid E-mail address.");
     return false;
   }

   return true;
} // validate()


