<HTML>
<HEAD>
<TITLE></TITLE>
<script language="javascript">
//############### Validator code ###############
var whichform;
var vmask='None';
function formvalidate(objForm) {
whichform = objForm;
var elArr = objForm.elements;
var outerrstr = false;
for(var i=elArr.length-1; i>=0; i--) {
//Looping backwards so focus will go to first field on form that contains an error.
with(elArr[i]) {
var v = elArr[i].validator;
var clrchg=(elArr[i].clrchg)?elArr[i].clrchg:'';
var fldtested = (elArr[i].istested)?elArr[i].istested:'';
var fldblank = (elArr[i].isblank)?is_blank(elArr[i].isblank):'none';
if (clrchg) colorchange(clrchg, 'white', '');
//Below version tests all fields without an istested value and all fields where istested value matches value in vmask.
if (!v || elArr[i].readOnly == true || elArr[i].disabled == true || fldblank == false || (vmask != 'None' && (fldtested != '' && fldtested.indexOf(vmask) == -1))) continue; //Ignore elements that do not have a validator tag or have readOnly or disabled set.
arrvalidator = v.split("|");
fldpassed = true;
for (var outloop=0;outloop<arrvalidator.length;outloop++) {
var parms = arrvalidator[outloop].split(",");
var which = (parms.length>0)?parms[0]:"";
var parm1 = (parms.length>1)?parms[1]:"";
var parm2 = (parms.length>2)?parms[2]:"";
var parm3 = (parms.length>3)?parms[3]:"";
if (!runfunction(value,which,parm1,parm2,parm3))
fldpassed = false;
}
if (!fldpassed) {
if (clrchg != '')
colorchange(clrchg, "red");
setfieldfocus(elArr[i].name, elArr[i].type);
outerrstr = true;
}
}
}
if (outerrstr) {
alert('One or more required fields were not completed or have incomplete information. Please correct or complete sections highlighted in red.');
return false;
}
alert("Passed");
return true;
}
function runfunction(value,which,parm1,parm2,parm3)
{
switch (which) {
//Dependence tests - Use these tests to check state of a different field.
case '1': stat = radio_checked(parm1); break; //Requires name of field passed as parameter
case '2': stat = chkbox_checked(parm1); break; //Requires name of field passed as parameter
case '3': stat = is_blank(parm1); break; //Requires name of field passed as parameter
//Use multi_funce to chain multiple field validations to the state of a specific field.
case '4': stat = multi_func(parm1,parm2,parm3); break;
//Standard Tests
case '5': stat = alpha_numeric_dot_dash_undrscr_squot(value); break;
case '6': stat = whole_positive_number(value); break;
case '7': stat = any_whole_number(value); break;
case '8': stat = any_real_number_with_decimal(value); break;
case '9': stat = any_real_number_with_or_without_decimal(value); break;
case '10': stat = any_real_number_with_set_number_decimals(value,parm1,parm2); break;
case '11': stat = valid_integer(value); break;
case '12': stat = zip_code(value); break;
case '13': stat = phone_number(value); break;
case '14': stat = international_phone_number(value); break;
case '15': stat = date_format(value); break;
case '16': stat = ssn(value); break;
case '17': stat = email(value); break;
case '18': stat = time_12hr(value); break;
case '19': stat = ip_address(value); break;
case '20': stat = state_abbrv(value); break;
case '21': stat = not_empty(value); break;
case '22': stat = set_length(value,parm1,parm2); break;
case '23': stat = credit_card(value); break;
case '24': stat = alpha_only(value); break;
case '25': stat = not_blank(value); break;
case '26': stat = persons_name(value); break;
}
return stat
}
function radio_checked(fldname) {
//Tests if radio button is checked. If a group of related radio buttons, it returns true if ANY of them are checked.
var myradio = whichform.elements[fldname];
for (var loop=0;loop<myradio.length;loop++)
if (myradio[loop].checked)
return true;
return false;
}
function chkbox_checked(fldname) {
//Tests if checkbox is checked.
var re=(whichform(fldname).checked)?true:false;
return re;
}
function is_blank(fldname) {
//Validates that a string IS blank
var re=(whichform(fldname).value == '')?true:false;
return re;
}
function multi_func(parm1, parm2, parm3) {
//This function allows chaining validation of other fields to current field.
var fldvalue = document.getElementById(parm1).value;
re = runfunction(fldvalue, parm2, parm3);
return re;
}
function alpha_numeric_dot_dash_undrscr_squot(value) {
//Accepts a-z, A-Z, 0-9 . ' - _
var re = /^[\w.\'-]+$/;
return re.test(value);
}
function whole_positive_number(value) {
var re = /^\d+$/;
return re.test(value);
}
function any_whole_number(value) {
var re = /^-?\d+$/;
return re.test(value);
}
function any_real_number_with_decimal(value) {
var re = /^-?\d+\.\d+$/;
return re.test(value);
}
function any_real_number_with_or_without_decimal(value) {
var re = /^-?\d+(\.\d+)?$/;
return re.test(value);
}
function any_real_number_with_set_number_decimals(value,min,max) {
//Accepts number without decimal but if decimal exists it must have at least the min and at most the max.
var re = new RegExp("^-?\\d+(\\.\\d{" + min + "," + max + "})?$");
return re.test(value);
}
function valid_integer(value) {
var re = /(^-?\d\d*$)/;
return re.test(value);
}
function zip_code(value) {
//xxxxx or xxxxx-xxxx
var re = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
return re.test(value);
}
function phone_number(value) {
//Only accepts patter of (xxx) xxx-xxxx
var re = /^\([1-9]\d{2}\)\s?\d{3}\-\d{4}$/;
return re.test(value);
}
function international_phone_number(value) {
//########This function has not yet been tested for validity
var re = /^\d(\d|-){7,20}/;
return re.test(value);
}
function date_format(value) {
//Accepts x/x/xxxx, xx/xx/xxxx, x-x-xxxx, xx-xx-xxxx
var re = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
return re.test(value);
}
function ssn(value) {
//Tests for xxxxxxxxx or xxx-xx-xxxx It will accept xxx-xxxxxx and xxxxx-xxxx as well.
var re = /^(\d{3})-?\d{2}-?\d{4}$/;
return re.test(value);
}
function email(value) {
//Requires minimum two characters before @, two chars after and two chars after.
var re = /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/;
return re.test(value);
}
function time_12hr(value) {
//HH:MM or HH:MM:SS or HH:MM:SS.mmm (.mmm is milliseconds as used in SQL Server datetime datatype. AcceptS 1 to 3 digits after the period)
var re = /^([1-9]|1[0-2]):[0-5]\d(:[0-5]\d(\.\d{1,3})?)?$/;
return re.test(value);
}
function ip_address(value) {
//Matches xxx.xxx.xxx.xxx 1-3 numbers per group
var re = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
return re.test(value);
}
function state_abbrv(value) {
//Case insensitive
var re = /^(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NB|NC|ND|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VT|WA|WI|WV|WY)$/;
return re.test(value);
}
function not_empty(value) {
//Strips leading and trailing whitespace and tests if anything remains.
var re = (value.replace(/^\s+|\s+$/g,'').length > 0)?true:false;
return re;
}
function set_length(value, min, max) {
//Test number of characters in value against min and max values. If no value set for min it defaults 0 if no value for max it defaults to the length of value.
var vmin=(min == '')?0:min;
var vmax=(max == '')?value.length:max;
var re=((value.length < vmin) || (value.length > vmax))?false:true;
return re;
}
function credit_card(s) {
//Uses the Luhn formula to test checksum digit on card to verify correct number format.
//Card Type Prefix Length
//American Express 34, 37 15
//MasterCard 51-55 16
//Visa 4 13, 16
var i, n, c, r, t;
// First, reverse the string and remove any non-numeric characters.
r = "";
for (i = 0; i < s.length; i++) {
c = parseInt(s.charAt(i), 10);
if (c >= 0 && c <= 9)
r = c + r;
}
// Check for a bad string.
if (r.length <= 1)
return false;
// Now run through each single digit to create a new string. Even digits are multiplied by two, odd digits are left alone.
t = "";
for (i = 0; i < r.length; i++) {
c = parseInt(r.charAt(i), 10);
if (i % 2 != 0)
c *= 2;
t = t + c;
}
// Finally, add up all the single digits in this string.
n = 0;
for (i = 0; i < t.length; i++) {
c = parseInt(t.charAt(i), 10);
n = n + c;
}
// If the resulting sum is an even multiple of ten (but not zero), the card number is good.
if (n != 0 && n % 10 == 0)
return true;
else
return false;
}
function alpha_only(value) {
var re = /^[a-zA-Z]*$/;
return re.test(value);
}
function not_blank(value) {
//Validates that a string IS blank
var re=(trim(value) != '')?true:false;
return re;
}
function persons_name(value) {
//ALlows Upper and lower case letters, hyphen, period and single quote. Length constrained to 60 characters.
var re = /^[a-zA-Z'-.\s]{1,60}$/;
return re.test(value);
}
//###### End Validation functions ######
function trim(value) {
return value.replace(/^\s+|\s+$/g, '');
}
function colorchange(divid, color) {
var colchg = document.all.item(divid);
colchg.style.color = (color);
}
function setfieldfocus(focusto, type) {
if (type == "checkbox" || type == "radio")
whichform.elements[focusto][0].focus();
else
whichform.elements[focusto].focus();
}
</script>
</HEAD>
<BODY>
<!--
NOTES: Validation is performed as follows.
Upon clicking the Submit button of the formvaliation function is executed.
If a field contains a tag named validator, the content of that tag is used to determine what type of validation to perform
on that field.
The format for the validation tag is as follows:
validator="number of validation function, parameter1, parameter2, parameter3"
Examples:
validator="2" - Sets the field to validate as a whole positive number, no parameters passed.
validator="6,1,3" - Sets to validate as a real number with a set number of decimal places. Minimum set as 1, max as 3.
validator="22,Res247" - Tests that the Radio group named Res247 has at least one radio button selected.
To perform multiple separate validations on the same field you separate the command/parameter groups with the | (pipe) symbol.
Example:
validator="2|18,5,5" - This first tests that the field contains a whole positive number then tests that the field
contains exactly 5 characters by setting the minimum to 5 and the maximum to 5.
To chain the validation of a different field to the current one you use the multi_func validation.
Example:
validator="2|21,CallStartM,2|21,CallStartAP,20" - This first performs validation function 2 then it performs validation
function 21 (multi_func) passing the name of the field to test followed by the validation function number to perform
on that field. In this case it tests CallStartM contains a whole positive number, then tests that CallStartAP contains
only alpha characters. CallStartH and CallStartAP do not need their own validator tags as all three fields are tested in
one location. This is useful when a group of fields are all related and all must be validated successfully.
VALIDATION MASKS
When the list of required fields on the form changes dramatically based on a single form field you can set up a mask to
control which fields validate under a given condition. For instance, if you want to validate fields A, B, C and G if
field A has been checked then set an event in field A so that when it is checked it sets that fields name value into
the variable vmask. Then in each field that is dependent upon field A being checked add an istested tag with that
fields name. For example fields A, B, C and G will have the tag: istested="A"
When the validation function is called, if there is a value stored in vmask and that value is also contained in the
istested tag for that field then that field will be tested. Any fields with an istested tag that does not contain the
same value as stored in vmask will be ignored while all fields that do not contain an istested tag will be processed under
their own rules.
Masks may be combined. Simply not having an istested tag will allow fields to be validated regardless of what the current
mask is set to. If however you need to have a field that is tested under some circumstances but not others you may combine
masks. For instance, if you have masks named Host, Recipient and Sender you can make the field validate in more than one
of the masks by combining the names in the istested tag separated by the pipe symbol (|).
Example: istested="Host|Sender" would validate if the vmask was set to Host, Sender or vmask was None, but would not be
validated if vmask was set to Recipient or any other value.
Example: istested="Recipient|Sender" would validate if vmask was None or set to Recipient or Sender but not if set to Host.
Again, if a field does not contain an istested tag it will be validated to the rules of it's validator tag providing it is
not set to readonly or disabled. If the field does not have a validator tag it will be ignored.
NOTE: Using validation masks means you must set an event that will set the value of vmask when the condition becomes true.
You must also set an event that sets the value of vmask to None if that condition becomes false.
For instance, if you have a pair of radio buttons and you want a mask applied if the first button is checked then you
add an event to that radio button so that if the first button is clicked the value of vmask changes to the name of the
mask you wish to use but if the right button is clicked you must set the value of vmask to None again so that the mask
will no longer apply to the page.
If you are using a mask you must have an istested="None" in all fields that should be ignored when the mask event is true.
Otherwise all fields that have a validator tag but no istested tag WILL be evaluated regardless of the current mask.
Exceptions for validation are as follows:
1. The field being checked has the readonly or disabled properties set.
Fields set readonly or disabled are not validated regardless of any other tags within them.
2. The field has the isblank tag and it evaluates false.
The isblank tag specifies the name of another field on the form. If the isblank tag exists in a field then the
field name specified by the isblank tag is tested to see if it is blank and if it is then processing continues,
if it is not blank then the current field is tested according to it's validator tag. This allows us to say that if
field X is filled in then field Y is not required but if it is NOT filled in then validate field Y.
3. The value of vmask is not blank and the field has the istested tag set to a value matching that of vmask.
If the field has an istested tag that matches a non-blank value of vmask the field will be validated.
Any fields with an istested value not matching vmask will be ignored.
Fields without istested tags will be tested according to their validator tag except under exceptions 1 and 2.
Setting Focus.
Focus is automatically moved to the first field on the form that fails validation.
Fields are tested in reverse order than they appear on the form.
Changing colors on fields that fail validation.
The text beside each form field is contained within uniquely named SPAN tags. Each field that requires validation also
has a custom tag called clrchg. If a field fails validation then the text color of the SPAN named in the clrchg tag is
set to red to show visually where fields need correction. If a field passes validation the SPAN named in the clrchg tag
is set to white. If it had previously been changed to red this will change it back again so that it no longer indicates
an error for that field. Future upgrades will allow different options in the handling of errors including custom messages,
choices on what item on the form is altered if any and how error messages are displayed.
-->
<form name="myform" id="myform" action="" method="post" onsubmit="return formvalidate(myform)">
<span id="dFirst">First Field: </span><input type="text" name="First" id="First" validator="6" clrchg="dFirst"> Whole positive number <br>
<span id="dSecond">Second Field:</span> <input type="text" name="Second" id="Second" validator="6" clrchg="dSecond"> Whole positive number<br>
<span id="dThird">Third Field:</span> <input type="text" name="Third" id="Third" validator="5" clrchg="dThird"> Alpha/Numeric including . ' - _<br>
<span id="dFourth">Fourth Field:</span> <input type="text" name="Fourth" id="Fourth" validator="8" clrchg="dFourth"> Any Real number with decimal<br>
<span id="dFifth">Fifth Field:</span> <input type="text" name="Fifth" id="Fifth" validator="22,5,10" clrchg="dFifth"> Alpha/Numeric from 5-10 characters only.<br>
<br>
<input type="submit" name="Submit" value="Submit"><br><br>
</form>
</BODY>
</HTML>