//***************onsubmit="return validator(this,1,1,0,0)"*******************//
//*****************LOOK AT THE BOTTOM FOR EXPLANATIONS***********************//

var debugRegExpAlert		= true,
	debugFuncNameAlert		= true,
	validPatternAttr		= "validpattern",
	validMessageAttr		= "validmessage",
	validFuncAttr 			= "validfunction",
	validHLParentAttr		= "validhlparent",
	highlightInvalid		= true,
	alertGlobalInvalidMsg	= true,
	alertEachInvalidWithMsg	= false,
	alertCompiledInvalidMsg = false,
	firstFocus 				= null,
	compiledInvalidMsg		= ""

function doFinalyIfInvalid()
{
	if(alertGlobalInvalidMsg)
		alert("Several entries are invalid.\nPlease enter appropriate values in highlighted fields.")
	if(alertCompiledInvalidMsg && compiledInvalidMsg.length>3)
		alert("Several entries are invalid:\n\n" + compiledInvalidMsg + "\nPlease enter appropriate values in highlighted fields.")
	firstFocus.focus()
	return false
}

function doFinalyIfValid(formRef)
{
	formRef.submitted = true
	for(i=0;i<formRef.length;i++)
	{
		if((formRef[i].nodeName.toLowerCase()=="input" || formRef[i].nodeName.toLowerCase()=="button") && formRef[i].type.toLowerCase()=="submit")
			formRef[i].disabled = true
	}
	return true
}

function findParent(objRef)
{
	var
		HLParrentTag = objRef.getAttribute(validHLParentAttr),
		HLParrentRef = objRef
	while(HLParrentRef.nodeName.toLowerCase()!=HLParrentTag)
		HLParrentRef = HLParrentRef.parentNode

	return(HLParrentRef)
}

function doIfInvalid(objRef)
{
	if(highlightInvalid)
	{
		if(objRef.getAttribute(validHLParentAttr))
		{
			var HLParrentRef = findParent(objRef)
			if(!HLParrentRef.backgroundColor_old)
			{
				if(HLParrentRef.currentStyle) //IE
				{
					HLParrentRef.backgroundColor_old = HLParrentRef.currentStyle.backgroundColor
					HLParrentRef.color_old = HLParrentRef.currentStyle.color
				}
				else if(window.getComputedStyle) //MOZ
				{
					HLParrentRef.backgroundColor_old = window.getComputedStyle(HLParrentRef,null).backgroundColor
					HLParrentRef.color_old = window.getComputedStyle(HLParrentRef,null).color
				}
				else
				{
					HLParrentRef.backgroundColor_old = "#ffffff"
					HLParrentRef.color_old = "#000000"
				}
			}
			HLParrentRef.style.backgroundColor="#dcffa8"
			HLParrentRef.style.color="#000000"

			if(!firstFocus)
			{
				if(objRef.length)
					firstFocus = objRef[0]
				else
					firstFocus = objRef
			}
		}
		else
		{
			if(!objRef.backgroundColor_old)
			{
				if(objRef.currentStyle) //IE
				{
					objRef.backgroundColor_old = objRef.currentStyle.backgroundColor
					objRef.color_old = objRef.currentStyle.color
				}
				else if(window.getComputedStyle) //MOZ
				{
					objRef.backgroundColor_old = window.getComputedStyle(objRef,null).backgroundColor
					objRef.color_old = window.getComputedStyle(objRef,null).color
				}
				else
				{
					objRef.backgroundColor_old = "#ffffff"
					objRef.color_old = "#000000"
				}
			}
			objRef.style.backgroundColor="#dcffa8"
			objRef.style.color="#000000"
		}
	}
	if(alertEachInvalidWithMsg && objRef.getAttribute(validMessageAttr))
		alert(objRef.getAttribute(validMessageAttr))
	if(alertCompiledInvalidMsg && objRef.getAttribute(validMessageAttr))
		compiledInvalidMsg +=  objRef.getAttribute(validMessageAttr) + "\n"
	if(!firstFocus)
		firstFocus = objRef
}

function doIfValid(objRef)
{
	if(highlightInvalid)
	{
		if(objRef.getAttribute(validHLParentAttr))
		{
			var HLParrentRef = findParent(objRef)

			HLParrentRef.style.backgroundColor = HLParrentRef.backgroundColor_old
			HLParrentRef.style.color = HLParrentRef.color_old
		}
		else
			objRef.style.backgroundColor = objRef.backgroundColor_old
	}
}

function validStringField(objRef)
{
	strToValid = objRef.value.replace(/(^\s+)|(\s+$)/gi,"")
	sPattern = objRef.getAttribute(validPatternAttr)
	try
	{
		var rgxp = new RegExp(sPattern,"gi")
	}
	catch(e)
	{
		if(debugRegExpAlert)
		{
			errmsg ="Validator Function Error:\n" +
			"    " + e.description +
			"\n\nPattern String:\n" +
			"    "  + sPattern +
			"\n\nForm Control Name:\n" +
			"    "  + objRef.name +
			"\n\nForm Control Id:\n" +
			"    "  + objRef.id
			alert(errmsg)
		}
		return(false)
	}
	return(rgxp.test(strToValid))
}

function validSinglCheckField(objRef)
{
	if(objRef.getAttribute(validPatternAttr)==1)
		return(objRef.checked)
}

function validMultiCheckField(objRef,patternIn)
{
	patternIn = patternIn || objRef[0].getAttribute(validPatternAttr)
	var strToValid=""
	for(j=0;j<objRef.length;j++)
		if(objRef[j].checked){strToValid+="v"}
	sPattern = "^v" + patternIn + "$"
	var rgxp = new RegExp(sPattern,"gi")
	return(rgxp.test(strToValid))
}

function validSinglSelectField(objRef,notValidIdexes)
{
	notValidIdexes = notValidIdexes || objRef.getAttribute(validPatternAttr)
	selectedIndx=objRef.selectedIndex
	var rgxp = new RegExp("(^|\\|)" + selectedIndx + "(\\||$)")
	return(!rgxp.test(notValidIdexes))
}

function validMultiSelectField(objRef)
{
	var strToValid=""
	for(j=0;j<objRef.options.length;j++)
		if(objRef.options[j].selected){strToValid+="v"}
	sPattern = "^v" + objRef.getAttribute(validPatternAttr) + "$"
	var rgxp = new RegExp(sPattern,"gi")
	return(rgxp.test(strToValid))
}

function validator(formRef,hi,agim,aeiwm,acim)
{
	if(formRef.submitted) return false
	compiledInvalidMsg		= ""
	highlightInvalid		= hi
	alertGlobalInvalidMsg	= agim
	alertEachInvalidWithMsg	= aeiwm
	alertCompiledInvalidMsg = acim

	firstFocus = null
	for(i=0;i<formRef.length;i++)
	{
		invalid = false
		if(formRef[i].getAttribute(validFuncAttr))
		{
			funcName = formRef[i].getAttribute(validFuncAttr)
			if(typeof(window[funcName])=="function")
			{
				if(!window[funcName]())
				{
					doIfInvalid(formRef[i])
					invalid = true
				}
				else
					doIfValid(formRef[i])
			}
			else if(debugFuncNameAlert)
			{
				errmsg ="Validator Function Error:\n" +
				"    function name was NOT evaluated as function object" +
				"\n\nFunction Name:\n" +
				"    "  + funcName +
				"\n\nForm Control Name:\n" +
				"    "  + formRef[i].name +
				"\n\nForm Control Id:\n" +
				"    "  + formRef[i].id +
				"\n\n*Do NOT include \"( )\" in function name"
				alert(errmsg)
			}
		}
		if(formRef[i].getAttribute(validPatternAttr) && !invalid)
		{
			switch(formRef[i].nodeName.toLowerCase())
			{
				case "input":
					var sType = formRef[i].type.toLowerCase()
					if(sType=="text" || sType=="password" || sType=="hidden" || sType=="file")
					{
						if(!validStringField(formRef[i]))
							doIfInvalid(formRef[i])
						else
							doIfValid(formRef[i])
					}
					else if(sType=="checkbox" || sType=="radio")
					{
						if(formRef[formRef[i].name].length)
						{
							if(!validMultiCheckField(formRef[formRef[i].name]))
								doIfInvalid(formRef[i])
							else
								doIfValid(formRef[i])
							i+=formRef[formRef[i].name].length-1
						}
						else
						{
							if(!validSinglCheckField(formRef[i]))
								doIfInvalid(formRef[i])
							else
								doIfValid(formRef[i])
						}
					}
				break
				case "textarea":
						if(!validStringField(formRef[i]))
							doIfInvalid(formRef[i])
						else
							doIfValid(formRef[i])
				break
				case "select":
					if(formRef[i].getAttribute("multiple"))
					{
						if(!validMultiSelectField(formRef[i]))
							doIfInvalid(formRef[i])
						else
							doIfValid(formRef[i])
					}
					else
					{
						if(!validSinglSelectField(formRef[i]))
							doIfInvalid(formRef[i])
						else
							doIfValid(formRef[i])
					}
				break
			}
		}
	}
	if(firstFocus)
		return doFinalyIfInvalid()
	else
		return doFinalyIfValid(formRef)
}

function comparePass()
{
	return(document.getElementById("p1").value==document.getElementById("p2").value)
}

function compareEmail()
{
	return(document.getElementById("e1").value==document.getElementById("e2").value)
}

function numsOnly(objRef)
{
	var pattern = "[^\\d"
	if(numsOnly.arguments.length>1)
	{
		for(i=1;i<numsOnly.arguments.length;i++)
			pattern += numsOnly.arguments[i]
	}
	pattern += "]"
	var rgxp = new RegExp(pattern,"gi")
	objRef.value = objRef.value.replace(rgxp,"")
}

function validDayOfMonth(yid,mid,did)
{
	var y = document.getElementById(yid).selectedIndex,
		m = document.getElementById(mid).selectedIndex,
		d = document.getElementById(did).selectedIndex

	if(m==2 && d>=29 && document.getElementById(yid).options[y].value%4==0)
		d = 29
	else if(m==2 && d>28)
		d = 28
	else if((m==4 || m==6 || m==9 || m==11) && d>30)
		d = 30
	document.getElementById(did).selectedIndex = d
}
function checkLengthOnInput(objRef, maxLength)
{
	if(objRef.value.length > maxLength)
	{
		objRef.value = objRef.value.substr(0,maxLength)
		document.getElementById(objRef.name + "_charsLeft").value = 0
		alert("You have reached maximum allowed length for this field.")
		objRef.focus()
	}
	else
	{
		document.getElementById(objRef.name + "_charsLeft").value  = maxLength - objRef.value.length
	}

}
/******************************************************************************
===================================================================validator===

validator(this,highlightInvalid, alertGlobalInvalidMsg, alertEachInvalidWithMsg, alertConpiledInvalidWithMsg)
Add to FORM tag:
	onsubmit="return validator(this,1,1,0,0)"
if CONFIRM used:
	if(ifdo('confirm text')){return validator(this,1,1,0,0)}else{return false}
-------------------------------------------------------------------------------
validPatternAttr - HTML attribute name - contains RegExp validation pattern
-------------------------------------------------------------------------------
validMessageAttr - HTML attribute name - contains message displayed to user if invalid
-------------------------------------------------------------------------------
validFuncAttr - HTML attribute name - contains additional validation function
-------------------------------------------------------------------------------
highlightInvalid - HTML attribute name - if true invalid controls will be highlighted
-------------------------------------------------------------------------------
alertGlobalInvalidMsg - HTML attribute name - if true general invalid alert will be displayed
-------------------------------------------------------------------------------
alertEachInvalidWithMsg - HTML attribute name - if true for each invalid control alert with <validMessage> will be displayed
-------------------------------------------------------------------------------
alertCompiledInvalidMsg - HTML attribute name - if true single alert with all <validMessage> will be displayed
-------------------------------------------------------------------------------
validHLParentAttr - HTML attribute name - contains HTML TAG which will be highlighted if invalid
-------------------------------------------------------------------------------
debugRegExpAlert - set to FALSE to cancel RegExp compilation error ALERT in text fields
-------------------------------------------------------------------------------
debugFuncNameAlert - set to FALSE to cancel additional function call error ALERT
-------------------------------------------------------------------------------
firstFocus - at end off validation contains first invalid field to set focus to
-------------------------------------------------------------------------------
formRef.submitted - custom property set to true in doFinalyIfValid function
 					at first submit to prevent multiple submits
-------------------------------------------------------------------------------
*Set validpattern to 1 to make SINGLE RADIO, CHECKBOX REQUIRED
*For SINGLE SELECT validpattern to numbers of invalid option indexes
	separated by | (pipe character)
	To set first option as invalid selection set validpattern to 0
*In collection of radios, checkboxes validpattern MUST be contained if FIRST control
*In MULTIPLE select, radio and checkbox set validpattern to "{num_1,num_2}"
	num_1 number of MINEMUM required selections
	num_2 number of MAXIMUM required selections
		not setting num_2 makes maximum infenitive: "{num_1,}"


=================================================================doIfInvalid===

What to do if SINGLE CONTROL IS NOT valid.
-------------------------------------------------------------------------------
	objRef - current control reference
-------------------------------------------------------------------------------
*This function may be changed to serve your needs
	by default the background color of INVALID control changed to #dcffa8

===================================================================doIfValid===

What to do if SINGLE CONTROL IS valid. Used to reset changes made by doIfInvalid()
-------------------------------------------------------------------------------
	objRef - current control reference
-------------------------------------------------------------------------------
*This function may be changed to serve your needs
	by default the background color of VALID control changed to #ffffff

===========================================================doFinalyIfInvalid===

What to do AT THE END of validation if INVALID control found

===========================================================doFinalyIfInvalid===

What to do AT THE END of validation if all controls validated to true
	By default nothing. Just return true to enable submit.

++================================================================findParent===

Helper function to find parent tag reference for highlighting invalid control

===========================================================compare(Pass | Email)===

Compare 2 TEXT fields for new user (pass, mail)

====================================================================numsOnly===

onkeyup="return numsOnly(this)" - Add to TEXT type INPUTs to block all but numeric data
To add additional characters add them as arguments to function call
if a char need to be escaped in REGEXP  double escape it:
onkeyup="return numsOnly(this,'\\.','@')"

=============================================================validDayOfMonth===

onchange="validDayOfMonth('yid','mid','did')" - Add to 3 - SELECT tags
Used to set correct day in dates when 3 SELECTs used (year, month, day)
-------------------------------------------------------------------------------
	yid - year SELECT tag id
-------------------------------------------------------------------------------
	mid - month SELECT tag id
-------------------------------------------------------------------------------
	did - day SELECT tag id

=====================================================================REGEXPs===

-------------------------------------------------------------------------------
EMAIL	^\w[-._\w]*\w.?@\w[-._\w]*\w\.\w{2,4}$
		RFC 822: ^([^\[\]()<>@,;:\\".]+|\"([^"\\\r]|\\.)*\")(\.([^\[\]()<>@,;:\\".]+|\"([^"\\\r]|\\.)*\"))*@(\[([^\\\[\]\r]|\\.)*\]|[^\[\]()<>@,;:\\".]+)(\.(\[([^\\\[\]\r]|\\.)*\]|[^\[\]()<>@,;:\\".]+))*$
-------------------------------------------------------------------------------
NIC		^[A-Za-z0-9]{4,12}$
-------------------------------------------------------------------------------
PASS	^[A-Za-z0-9]{4,12}$
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------

******************************************************************************/
