function validate_required(field,alerttxt)
{
  if (field.value==null||field.value=="") {
    alert(alerttxt); return false;
  } else {
    return true;
  }
}

// Check if the content has the general syntax of an email: the input data must contain at least an @ sign and a dot (.), and the @ must not be the first character of the email address, and the last dot must at least be one character after the @ sign.
// CAN modify the field, by deleting leading or trailing whitespace (which might otherwise trigger a syntax error)
function validate_email(field,alerttxt)
{
// First eliminate leading or traling whitespace (cautiously - replacing only when the length has been reduced).
  var stringToTrim = field.value;
  stringToTrim = stringToTrim.replace(/^\s+|\s+$/g,"");
  if (stringToTrim.length < field.value.length) { field.value = stringToTrim; }
  apos=field.value.indexOf("@");
  dotpos=field.value.lastIndexOf(".");
  if (apos<1 || dotpos-apos<2 || dotpos >= (field.value.length-1) || apos!=field.value.lastIndexOf("@") || field.value.indexOf(' ')>0)
    {alert(alerttxt);return false;}
  else {return true;}
}

// Allow cut and paste of city-state-zip field
// This version designed for real-time operation, so it does only limited validation
//  (namely, it only looks for the NE states)
function multicsz(city,state,zip)
{
  var NEsz = /,?\s*(CT|MA|ME|NH|RI|VT)(\s+((\d{5})(-\d{4})?))?$/;
  var state_zip = NEsz.exec(city.value);
// See if we have the whole package in the city field. If so, overwrite the other fields
  if (state_zip) {
  	city.value = city.value.substr(0,state_zip.index);
  	state.value = state_zip[1];
  	if (state_zip[3]) { zip.value = state_zip[3]; }
  	zip.focus();
// Change the focus to the element AFTER the zip (if any). Need to figure this out!!
// if (el.value.length < el.getAttribute('maxlength')) return;
//	var nextEl = zip.form.elements[zip.tabIndex+1];
//	if (nextEl && nextEl.focus) { nextEl.focus(); }
  }
  return true;
}

// The tough one: city, state and zip validation
// Allow cut-and-paste into the address field: we'll parse and distribute if it matches
function citystatezip(city,state,zip)
{
  var NEstates = /^(CT|MA|ME|NH|RI|VT)$/i;
  var ZIP4 = /(\d{5})(-\d{4})?$/;
  var NEsz = /,?\s*(CT|MA|ME|NH|RI|VT)(\s+((\d{5})(-\d{4})?))?$/;
  var state_zip = NEsz.exec(city.value);
// See if we have the whole package in the city field. If so, overwrite the other fields
  if (state_zip) {
  	city.value = city.value.substr(0,state_zip.index);
  	state.value = state_zip[1];
  	zip.value = state_zip[3];
  }
// Continue to check, even if we filled in from the city field (which might still be incorrect)
  if (NEstates.exec(state.value) == null) {
  	if (state.value) { alert (state.value+" is not a New England state!"); }
  	else { alert("Please enter state"); }
  	state.focus();
  	return false;
  }
// Allow a null/blank ZIP code
  if (zip.value && ZIP4.exec(zip.value) == null) {
  	alert (zip.value+" is not a valid ZIP code!");
  	zip.focus();
  	return false;
  }
  return true;
}

// Check the first arg field for "City, State Zip" format & supply state & zip from 2nd & 3rd args if necessary
// Does nothing if entry is blank or if defaults are blank or invalid
function defaultstate(entry,default_state,default_zip) {
  var NEstates = /^(CT|MA|ME|NH|RI|VT)$/i;
  var ZIP4 = /(\d{5})(-\d{4})?$/;
  var NEsz = /,?\s*(CT|MA|ME|NH|RI|VT)(\s+((\d{5})(-\d{4})?))?$/;
  if (!entry.value) { return true; }
// See if we have state and/or ZIP, and if so see if we need to supply the ZIP
  var state_zip = NEsz.exec(entry.value);
  if (state_zip) {
   if (ZIP4.exec(default_zip.value) && !state_zip[3]) {
    entry.value += " "+default_zip.value;
    alert("I supplied ZIP code for listing town; please check");
    return false;
   }
   return true;
  }
// Missing state and ZIP, so supply them, if possible
  var return_value = false;
  if (NEstates.exec(default_state.value)) {
   entry.value += " "+default_state.value;
   return_value = true;
  }
  if (ZIP4.exec(default_zip.value)) {
   entry.value += " "+default_zip.value;
   return_value = true;
  }
  if (!return_value) {
   alert("Town for listing must have state!");
  } else {
   alert("I supplied state/zip for listing town; please check");
  }
  return false;
}
// Validate and reformat a telephone number into dashed form (e.g., 888-888-8888)
//  Sample input: (603) 742-0675 or 7037420675 or 603.742.5643; whitespace may be added.
// ALLOW ARBITRARY TEXT AFTER THE MATCHING NUMBER, to allow for extensions (e.g. "ext 504").
// The only reasonable way to do this is with regular expressions!
function telfmt(theField) {
  var tnum = theField.value;
// Allow a blank field without syntax checking (if so, clear it)
  if (!/\S/.test(tnum)) {
   theField.value = "";
   return true;
  }
// If nonblank, match against regular expresson
  var tmatch = /^\s*\(?(\d\d\d)\)? *[.-]? *(\d\d\d) *[.-]? *(\d\d\d\d)\b/;
  if (tmatch.test(tnum)) {
   theField.value = tnum.replace(tmatch,"$1-$2-$3");
   return true;
  } else {
   alert("For phone number, please use aaa-xxx-xxxx format");
// Need timeout because tab-select works AFTER the onchange script has acted
   setTimeout(function () { theField.select() }, 10);
   return false;
  }
}
