//--------------------------------------------------------------
// FormIsGood
//--------------------------------------------------------------
// Inputs:
//    frm           form object to process
// Output:
//    boolean       false if user neglected any fields, otherwise true
//--------------------------------------------------------------
// Intended Use:
//    <form onSubmit="return FormIsGood(this);">
//--------------------------------------------------------------
// Dependencies:
//    function RadioChecked()
//    function Trim()
//--------------------------------------------------------------
// Notes:  This function was written specifically to be a general
//         purpose form validater.  It checks every element
//         of the form to make sure it was not missed - ignoring
//         those the user cannot alter and those that do not make
//         sense to check (checkbox, submit, reset).
//         This function *only* checks for the absence of data.
//         It does not validate the data itself.
//--------------------------------------------------------------
  function FormIsGood(frm)
  {
//alert("Entering FormIsGood()...");
    var missingAnswer = new Array();  //keep list of missed fields
    var oInputTag; //current form element
    var idx = 0;  //generic counter
    var nNumMissed = 0; //number of missed fields
    var sTagType = "";  //form element's type attribute
    var bRadioElements = new Array(); //list of radio sets we've already processed
    
    // Note:  Form elements are processed in reverse order and then reversed again
    // (putting them back in their expected order) when the user message string
    // is built later on.
    for (var i = (frm.elements.length - 1); i >= 0; i--)
    {
      oInputTag = frm.elements[i];
      sTagType = oInputTag.type;
      
      // special cases
      if ( "radio" == sTagType ) //radio buttons need special attention
      {
        var sRadioName = oInputTag.name
      
        if ( !(bRadioElements[sRadioName]) ) //skip over sets we've already done
        {
          // remember this set
          bRadioElements[sRadioName] = true;
          
          if ( !(RadioChecked(frm.elements[sRadioName])) ) {
            missingAnswer[idx++] = oInputTag.id
          }
        }
      } // end if type == radio
      
      // everything else - ignoring elements that don't make any sense
      else if ( "submit" != sTagType && "reset" != sTagType  &&
                "hidden" != sTagType && "button" != sTagType &&
                "checkbox" != sTagType)
      {
        //anything not a special case above can be handled the same way
        // Note: Trim() is a user function that trims the whitespace from
        // the beginning and ending of a string.
//alert("Checking for spaces in ["+oInputTag.value+"] ("+oInputTag.name+")");
        if ( "" == Trim(oInputTag.value) ) {
          missingAnswer[idx++] = oInputTag.id;
        }
      }
    } // end for loop
    
    if ( (nMaxMissed = missingAnswer.length) > 0 )
    {
      // some fields were missed by the user.
      var msg = "Please enter the following information:\n\n";
      
      // compile a list of which ones.
      // (missingAnswer is in reverse order, which gets reversed here)
      for (var i = (nMaxMissed - 1); i >= 0; i--) {
        msg += ("\t" + missingAnswer[i] + "\n");
      }
    
      alert(msg); //scold the user
      
      return false; //don't submit the form
    } else {
      // no fields were missed!
      return true;
    }
  } // end FormIsGood()
  
//--------------------------------------------------------------
// RadioChecked
//--------------------------------------------------------------
// Inputs:
//    rad           radio button element array
// Output:
//    boolean       whether or not any buttons were checked
//--------------------------------------------------------------
  function RadioChecked(rad) // rad is a radio button element array
  {
//alert("Entering RadioChecked("+rad[0].name+")...");
    var i = 0;

//    while ( undefined != rad[i] )
    while ( i < rad.length)
    {
//alert("...checking button "+(i)+"...");
      // celebrate and rejoice if any of the radio buttons are clicked
      if ( rad[i].checked ) {
//alert("...is checked - bail...");
        return true;
      }
      i++;
    }
    
//alert("no radios checked - return false...");
    return false; //sadness - no buttons were chosen
  } // end RadioChecked

//--------------------------------------------------------------
// Trim
//--------------------------------------------------------------
// Inputs:
//    str           string to trim whitespace from
// Output:
//    string        with whitespace removed from the beginning and end
//--------------------------------------------------------------
  function Trim(str)
  {
//alert("Entering Trim("+str+")");
    //remove leading whitespace
    str = str.replace(/^\s*/,"");
//alert("...leading trimmed: ["+str+"]...");
    //remove trailing whitespace
    str = str.replace(/\s*$/,"");
//alert("...trailing trimmed: ["+str+"]...");

    return str;
  } // end Trim

