<!--hide it 

//======================================================================
// File:	     	 validation.js  
// Copyright:        (c) SalientPoint AB 2002, all rights reserved.
// Comments:         This file contains javascript validation functions.
//                   This field should be located in a location so that
//                    its reachable by the webserver bu the path 
//                    /eyes/javascript/common.js 
// Public methods:   validateDate    Validates dates
//                   validateNumber   Validates numbers
//======================================================================

//----------------------------------------------------------------------
// Public methods:
//----------------------------------------------------------------------

//---------------------------------
// Name:       validateDate
// Purpose:    Validates dates
// Parameter1: element, the element object to validate. Use "this" as parameter to ensure the right element is invoked and in focus after an error input
// Parameter2: mask, the format msk for the dateformat, ie  'yyyymmdd' , 'yymmdd hh24:mi' , 'hh24:mi yyyymmdd' etc
// Parameter3: errorMsg, the error message to send in an alert window if the elements value was not a valid date in the given dateformat.
// Example:    .... ONCHANGE="validateDatum(this,'yyyymmdd','Ang din fådelseår i formatet yyyymmdd')"
//

// alert("validation.js");

function validateDateOld (element, mask, errorMsg) {
    	

	thisManad = 0;
      	thisDag = 0;
      	thisAr = 0;
      	k = 0;
      	st = new stromKlass(element.value);
      	maskSt  = new stromKlass(mask);
      	
      	while( !(st.peekNext() == "") ) {
		if ( !( parseGrupp(st, maskSt) && parseDelimiter(st, maskSt) )) {
			alert (errorMsg);
			
        	goToElement(element)
			 return (false);
		}
		
	}
        if ( ((thisManad != 0) && (thisDag <= dagarPerManad[thisManad])) || (thisDag == 0) ){ 
        	return(true) 
        } 
        else {
        	alert (errorMsg);
			
        	goToElement(element)
		 return (false);
	}
}

function validateDate (element, mask, errorMsg) {
	thing = parseDate(element.value, mask);
	if (thing) {
		return thing;
	} else {
		alert(errorMsg);
		goToElement(element);
		return (false);
	}
}

function dateAfter(date1, date2) {
	return ( 
		date1.getFullYear() > date2.getFullYear() ||
		(date1.getFullYear() == date2.getFullYear() && date1.getMonth() > date2.getMonth()) ||
		(date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth() &&  date1.getDate() >  date2.getDate())
	)
}

function dateSameDay(date1, date2) {
	return (
		date2.getFullYear() == date1.getFullYear() && 
		date2.getMonth() == date1.getMonth() && 
		date2.getDate() == date1.getDate() 	
	)
}

function dateSameOrAfter(date1, date2) {
	return ( 
		dateSameDay(date1, date2) ||
		dateAfter(date1, date2)
	)
}

function dateTodayOrAfter(date) {

	today = new Date();	

	// alert("dateTodayOrAfter : today.getFullYear() = " + today.getFullYear());
	// alert("dateTodayOrAfter : date.getFullYear() = " + date.getFullYear());
	// alert("dateTodayOrAfter : today.getMonth() = " + today.getMonth());
	// alert("dateTodayOrAfter : date.getMonth() = " + date.getMonth());
	// alert("dateTodayOrAfter : today.getDate() = " + today.getDate());
	// alert("dateTodayOrAfter : date.getDate() = " + date.getDate());
	
	return dateSameOrAfter(date, today);
}

function validateDateAfter(element, date1, date2, eMessage) {
	if (dateAfter(date1, date2)) {
		return (true)	
	} else {
		alert(eMessage);
		goToElement(element);
		return(false);
	}	
}

function validateDateSameOrAfter(element, date1, date2, eMessage) {
	if (dateSameOrAfter(date1, date2)) {
		return (true)	
	} else {
		alert(eMessage);
		goToElement(element);
		return(false);
	}	
}


function validateDateTodayOrAfter(element, date, eMessage) {
	if (dateTodayOrAfter(date)) {
		return (true)	
	} else {
		alert(eMessage);
		goToElement(element);
		return(false);
	}	
}


function parseDate (dateString, mask) {
	thisManad = 0;
    thisDag = 0;
    thisAr = 0;
    k = 0;
    st = new stromKlass(dateString);
    maskSt  = new stromKlass(mask);
      	
    while( !(st.peekNext() == "") ) {
		if ( !( parseGrupp(st, maskSt) && parseDelimiter(st, maskSt) )) {
			 return (false);
		}
	}
    if ( ((thisManad != 0) && (thisDag <= dagarPerManad[thisManad])) || (thisDag == 0) ){ 
		return new Date(thisAr, thisManad -1 , thisDag); 
	} 
	else {
		return (false);
	}
}


function validateInteger(thing, errorMsg, suppressMessage) {
	if(!isNaN(thing.value) && thing.value == Math.abs(thing.value)) {
		return true;	
	} else {
		if (!suppressMessage){
			// alert("value = :" + thing.value);
			alert(errorMsg);
		}
		return false;
	}		
}

function validatePositiveInteger(thing, errorMsg, suppressMessage) {
	if (validateInteger(thing, errorMsg, true) && thing.value >= 0) {
		return true;
	} else {
		thing.value = "";
		alert(errorMsg);
	}
}


function validateNumberAndLength (element, errorMsg, n, suppressMessage) {
	if(element.value==null) {
		return true;
	} else if(element.value.length!=n) {
		if(!suppressMessage) {		
			alert(errorMsg);
		}
		goToElement(element);
		return false;
	} else {
		return validateNumber(element, errorMsg, suppressMessage);
	}
}

/**Validates Swedish 5-nr Zip code*/
function validateZipCode(element, errorMsg, suppressMessage) {
	element.value = removeAllSpaces(element.value);
	if(element.value.length==5 && isNumeric(element.value)) {
		return true;
	} else {
		if(!suppressMessage) {
			alert(errorMsg);
		}
		goToElement(element);
		return false;
	}
}

function isNumeric(sText) {
	var validChars = "0123456789";
	for (i = 0; i < sText.length; i++) { 
		var c = sText.charAt(i); 
		if (validChars.indexOf(c) == -1) {
			return false;
		}
	}
	return true;
}

function removeAllSpaces(theString) {
	var temp = theString.split(' ');
	theString = '';
	for(i=0; i<temp.length; i++) {
		theString += temp[i];
	}
	return theString;
}

//---------------------------------
// Name:       validateNumber
// Purpose:    Validates numbers
// Parameter1: element, the element object to validate. Use "this" as parameter to ensure the right element is invoked and in focus after an error input
// Parameter2: errorMsg, the error message to send in an alert window if the elements value wasn't a number.
// Example:    .... ONCHANGE="validateNumber(this,'Incorrect salary, please use only numbers')"
//
function validateNumber (element, errorMsg, suppressMessage) {
	tal = new stromKlass(element.value);


	if( tal.peekNext() == "-") {
		tal.getNext();
	}

	foundDelimeter = false;

	while ( !(tal.peekNext() == "") ) {
		if( arSiffra(tal.peekNext()) ) {
			tal.getNext();
		}
		else {
			if( (tal.peekNext() == "." || tal.peekNext() == ",") && foundDelimeter == false ) {
				foundDelimeter = true;
				tal.getNext();
			}
			else {
				if(!suppressMessage)
					alert(errorMsg);

				goToElement(element)
				return false;
			}
		}
	}

	return true;
}

function validateIntegerMinVal(element, minVal, errorMsg) {
	if(parseInt(element.value) <= minVal) {
		goToElement(element);
		alert(errorMsg);
		return false;
	}
	return true;
}

function validatePositiveInteger(element, errorMsg) {
	
	var val = element.value;

	var isIntegerRegExp  = /(^-?\d\d*$)/;

	//check for integer characters
	var valid = isIntegerRegExp.test(val);

	if(valid && val <= 0) {
		valid = false;
	}
	
	if(!valid) {
		goToElement(element);
		alert(errorMsg);
	}
	
	return valid;
}

function validatePositiveIntegerOrZero(element, errorMsg) {
	
	var val = element.value;

	var isIntegerRegExp  = /(^-?\d\d*$)/;

	//check for integer characters
	var valid = isIntegerRegExp.test(val);

	if(valid && val < 0) {
		valid = false;
	}
	
	if(!valid) {
		goToElement(element);
		alert(errorMsg);
	}
	
	return valid;
}

function validateNoTags(obj, title, maxLength) {
	//alert('validateNoTags 1' +
		//	'\nobj=' + obj);
	if( !validateNotEmpty(obj, title + ' saknas.', true) ) {
		return false;
	}
	if( !validateMaxLength(maxLength, obj, title + ' f\u00e5r h\u00f6gst vara ' + maxLength + ' tecken l\u00e5ng.') ) {
		return false;
	}
	
	var msg = title + ' innehåller otillåtna tecken. (\'<\' eller \'>\')';
	var str = obj.value.toLowerCase();
	
	if(str.indexOf('<') != -1) {
		var temp = new Array();
		temp = str.split('<');
		for(var i=1; i<temp.length; i++) {
			if(		temp[i].indexOf('i')==0 || temp[i].indexOf('/i')==0 || 
					temp[i].indexOf('b')==0 || temp[i].indexOf('/b')==0 ||
					temp[i].indexOf('strong')==0 || temp[i].indexOf('/strong')==0 || 
					temp[i].indexOf('a ')==0 || temp[i].indexOf('/a')==0 || 
					temp[i].indexOf('br')==0 || temp[i].indexOf('/br')==0) {
				continue;
			} else {
				alert(msg);
				return false;
			}
		}
	}
	return true;
}

//---------------------------------
// Name:       validateInterval
// Purpose:    Validates numbers for an specific interval 
// Parameter1: min, the min value for the interval
// Parameter2: max. the max value for the interval 
// Parameter3: element, the element object to validate. Use "this" as parameter to ensure the right element is invoked and in focus after an error input
// Parameter4: errorMsg, the error message to send in an alert window if the elements value wasn't a number.or not in interval
// Example:    .... ONCHANGE="validateInterval(0,10,this,'Please use an number inte interval 0 to 10')"

function validateInterval( min, max, element, errorMsg) {
	validateNumber (element, errorMsg);
	if((element.value < min || element.value > max) && element.value.length > 0) {
		alert (errorMsg);

		goToElement(element)
		return (false);
	}
	return (true);
}


//---------------------------------
// Name:       validateMaxLength
// Purpose:    Validates max length for an elements value   
// Parameter1: max. the max text length
// Parameter2: element, the element object to validate. Use "this" as parameter to ensure the right element is invoked and in focus after an error input
// Parameter3: errorMsg, the error message to send in an alert window if the elements value exceeded max length
// Example:    .... ONCHANGE="validateMaxLength(10, this, 'Text length exceeded!')"
//
function validateMaxLength( max, element, errorMsg) {
	if(element.value.length > max) {
		alert (errorMsg);

		goToElement(element)
		return (false);
	}
	return (true);
}

//---------------------------------
// Name:       validateMinLength
// Purpose:    Validates min length for an elements value   
// Parameter1: max. the min text length
// Parameter2: element, the element object to validate. Use "this" as parameter to ensure the right element is invoked and in focus after an error input
// Parameter3: errorMsg, the error message to send in an alert window if the elements value was shorter than min length
// Example:    .... ONCHANGE="validateMaxLength(10, this, 'Text length exceeded!')"
//
function validateMinLength( min, element, errorMsg) {
	if(element.value.length < min) {
		alert (errorMsg);
		goToElement(element)
		return (false);
	}
	return (true);
}


//---------------------------------
// Name:       validateNotEmpty
// Purpose:    Validates that an elements value isn't empty   
// Parameter1: element, the element object to validate.  Use "this" as parameter to ensure the right element is invoked and in focus after an error input
// Parameter2: errorMsg, the error message to send in an alert window if the elements value is null
// Example:    .... ONCHANGE="validateNotEmpty(this, 'You must enter a value!')"
//

function validateNotEmpty(element, errorMsg, displayError) {

	valid = true;
	// alert("validateNotEmpty element = " + element + ", errorMsg = " + errorMsg + ",  displayError = " + displayError);
	if ( element.type.indexOf('select') != -1 ) {
		if (element.selectedIndex < 0) {
			valid = false;
		} else { 
			theSelectedValue = element.options[element.selectedIndex].value;
			if (theSelectedValue == -1 | theSelectedValue == "") {
				valid = false;
			}
		}
	} else if (element.value.length <= 0) {
		valid = false;
	}
	if (!valid) {
		if (displayError) {
			alert (errorMsg);
			goToElement(element);
		}
		return false;
	} else {
		return true;
	}
}


// AB
function validateEmpty(element, errorMsg) {
  return !validateNotEmpty(element, errorMsg, false);
}

// TE

function validIdentifier(thing) {
	var letters = "abcdefghijklmnopqrstuvwxyz";
	var numbers = "0123456789";
	var delimiters = "-_.";
	var legalChars = letters + letters.toUpperCase() + numbers + delimiters;
  
    for (var i = 0; i<thing.length; i++){
		theChar = thing.charAt(i);
      	if (legalChars.indexOf(theChar) == -1) {
			return false;
		}
    }
    return true;
}


//---------------------------------
// Name:       validateEmail
// Purpose:    Validates that an elements value is a valid email.   
// Parameter1: element, the element object to validate. Use "this" as parameter to ensure the right element is invoked and in focus after an error input
// Example:    .... ONCHANGE="validateEmail(this)"
//
function validateEmail(element) {
  var emailStr = element.value;
  var emailPat=/^(.+)@(.+)$/;
  var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]åäöÅÄÖ";
  var validChars="\[^\\s" + specialChars + "\]";
  var firstChars=validChars;

  var quotedUser="(\"[^\"]*\")";
  var atom="(" + firstChars + validChars + "*" + ")";
  var word="(" + atom + "|" + quotedUser + ")";
  var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
  var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");


  /* Finally, let's start trying to figure out if the supplied address is valid. */
  var matchArray=emailStr.match(emailPat);
  
  if (matchArray==null) {
    /* Too many/few @'s or something; basically, this address doesn't even fit the general mould of a valid e-mail address. */
    alert("Ogiltig emailaddress (kontrollera @, placering av punkter etc). Du f\u00e5r heller inte skriva in fler \u00e4n EN emailadress.");
			
        goToElement(element)
    return false;
  }
  var user=matchArray[1];
  var domain=matchArray[2];// See if "user" is valid
  
  if (user.match(userPat)==null) {
    // user is not valid
    alert("Ett fel i emailadressen f\u00f6re @.");
	goToElement(element)
    return false;
  } else {
  
  // Make sure User has legal characters in it...
  
  	if (!validIdentifier(user)) {
		alert("Emailadressen inneh\u00e5ller otill\u00e5tna tecken");
		goToElement(element);
		return false;
	}
  
  }

  // Domain is symbolic name
  var domainArray=domain.match(domainPat);
  if (domainArray==null) {
    alert("Ett fel i email adressen efter  @.");
    goToElement(element)
    return false;
  } else {
  
  // Make sure Domain name has legal characters in it...
  
  	if (!validIdentifier(domain)) {
		alert("Dom\u00e4nnamnet inneh\u00e5ller otill\u00e5tna tecken");
		goToElement(element);
		return false;
	}
  
  }

  /* Now we need to break up the domain to get a count of how many atoms it consists of. */
  var atomPat=new RegExp(atom,"g");
  var domArr=domain.match(atomPat);
  var len=domArr.length;
  if (domArr[domArr.length-1].length<2 ||
    domArr[domArr.length-1].length>4) {
    // the address must end in a two letter or three letter word.
    alert("Emailadressen m\u00e5ste avslutas med ett ord p\u00e5 2-4 bokst\u00e4ver.");
			
        	goToElement(element)
    return false;
  }

  if (emailStr.lastIndexOf(".")==emailStr.length-1) {
    // the address must not end with a .
    alert("Emailadressen f\u00e5r inte avslutas med en punkt!");
			
        	goToElement(element)
    return false;
  }
  if (emailStr.lastIndexOf(".")<emailStr.lastIndexOf("@")) {
    // the address must have a . after @
    alert("Dom\u00e4nnamnet i epost-addressen (det efter @) m\u00e5ste ha minst en punkt.");
			
    goToElement(element)
    return false;
  }

  // If we've gotten this far, everything's valid!
  return true;
}


function validateSocialSecNr(nr, errorMsg, displayError){
	valid = false;
	if(!nr.match(/^(\d{2})(\d{2})(\d{2})\-(\d{4})$/)) {
		return false;
	}
	this.now = new Date();
	this.nowFullYear = this.now.getFullYear()+"";
	this.nowCentury = this.nowFullYear.substring(0,2);
	this.nowShortYear = this.nowFullYear.substring(2,4);
	this.year = RegExp.$1;
	this.month=RegExp.$2;
	this.day=RegExp.$3;
	this.controldigits=RegExp.$4;
	this.fullYear = (this.year*1<=this.nowShortYear*1)?(this.nowCentury+this.year)*1:((this.nowCentury*1-1)+this.year)*1;
	var months = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	if(this.fullYear%400==0 || this.fullYear%4==0&&this.fullYear%100!=0) {
		months[1]=29;
	}
	if(this.month*1<1 || this.month*1>12 || this.day*1<1 || this.day*1>months[this.month*1-1]) {
		return false;
	}
	this.alldigits = this.year + this.month + this.day + this.controldigits;
	var nn = "";
	for(var n=0;n<this.alldigits.length;n++) {
		nn += ((((n+1)%2)+1)*this.alldigits.substring(n,n+1));
	}
	this.checksum = 0;
	for(var n=0;n<nn.length;n++) {
		this.checksum+=nn.substring(n,n+1)*1;
	}
	valid = (this.checksum%10==0) ? true:false;
	this.sex = parseInt(this.controldigits.substring(2,3))%2;
	
	if (!valid) {
		if (!displayError) {
			alert (errorMsg);
			goToElement(element);
		}
		return false;
	} else {
  		return true;
  	}
}


//----------------------------------------------------------------------
// Private help functions
//----------------------------------------------------------------------
// Kludge får en bug i Navigator 2.0.2

function goToElement(element) {
	// element.focus();
	if ( element.type.indexOf('select') != -1) {
		element.focus();
	} else{
		element.select();
	}
}

function charInString (c, s) {
    for (i = 0; i < s.length; i++)
    {   if (s.charAt(i) == c) return true;
    }
    return false
}

function strippaTecken (s,s2) {
    var i = 0;
    while ((i < s.length) && charInString (s.charAt(i), s2))i++;
    return s.substring (i, s.length);
}

function stromKlass (s){
    this.string = s;
    this.index = 0;
    this.getNext = getNextMethod;
    this.peekNext = peekNextMethod;
    this.peekSecondNext = peekSecondNextMethod;
}

function getNextMethod() {
    if (this.index >= this.string.length) {return("")}
    else
    {this.index += 1;
     return(this.string.charAt(this.index-1));
     }
}

function peekNextMethod() {
    if (this.index >= this.string.length) {return("")}
    else
    { return(this.string.charAt(this.index)); }
}


function peekSecondNextMethod() {
   if (this.index >= this.string.length) {return("")}
    else
    { return(this.string.charAt( this.index + 1 )); }
}


// Dum bug som parsar alla strångar som bårjar med "0" till 0

function myParseInt (s) {
  if (arHeltal(s)) {return(parseInt(strippaTecken(s,"0")))}
  else {return(false)}
  }


//----------------------------------------------------------------------
// Funktioner får felmeddelanden
//----------------------------------------------------------------------

//function prompt (s) { window.status = s }


//----------------------------------------------------------------------
// Domåndeklarationer och typtester
//----------------------------------------------------------------------

var siffror = "0123456789"

function arSiffra(s) { return(siffror.indexOf(s) != -1) }

function arHeltal (s){
    for (var i = 0; i < s.length; i++){
      if (!arSiffra(s.charAt(i))) return false;
    }
    return true;
}

//----------------------------------------------------------------------
// Valideringsmetoder - en per typ.
//----------------------------------------------------------------------
// Enkel validering av datumstrång enligt: åå/MM/DD

var dagarPerManad = new Array();
dagarPerManad[1] = 31;  dagarPerManad[2] = 29;  dagarPerManad[3] = 31;
dagarPerManad[4] = 30;  dagarPerManad[5] = 31;  dagarPerManad[6] = 30;
dagarPerManad[7] = 31;  dagarPerManad[8] = 31;  dagarPerManad[9] = 30;
dagarPerManad[10] = 31; dagarPerManad[11] = 30; dagarPerManad[12] = 31;
//------------------------------------------
function parseAr (st, stMask) {
    var iMask = 0;
    while (stMask.peekNext() == "y") {stMask.getNext();iMask += 1};
    ar = "";
    for (var i = 0; i < iMask; i++) {ar = ar + st.getNext()}
	thisAr = myParseInt (ar);
    return (arHeltal(ar) && ar.length == iMask);
    }
//-------------------------------------------
function parseMan (st, stMask) {
    var iMask = 0;
    while (stMask.peekNext() == "m") {stMask.getNext();iMask += 1};
    man = "";
    for (var i = 0; i < iMask; i++) {man = man + st.getNext()}
    thisManad = myParseInt (man);
    return (thisManad && arHeltal(man) && man.length == 2 && thisManad >  0 && thisManad < 13);
    }
//-------------------------------------------
function parseDag (st, stMask) {
    var iMask = 0;
    while (stMask.peekNext() == "d") {stMask.getNext(); iMask += 1};
    dag = "";
    for (var i = 0; i < iMask; i++) {dag = dag + st.getNext()}
    thisDag = myParseInt (dag);
    return (thisDag && arHeltal(dag) && dag.length == 2 && thisDag >  0 && thisDag <= 31);
 }

//-------------------------------------------
function parseTime (st, stMask) {
    //Get hh
    var iMask = 0;
    while (stMask.peekNext() == "h") {stMask.getNext(); iMask += 1};
    hour = "";
    for (var i = 0; i < iMask; i++) {
    	hour = hour + st.getNext()
    }
    thisHour = parseInt (hour);
        
    //If there are no number after "hh" then it is 12 hour
    if( stMask.peekNext() == ":" ) {
    	// alert('Aboo');
    	return (arHeltal(hour) && thisHour >= 1  && thisHour <= 12 );
    }  
    
    //See if it 12 our 24 hours
    hourMask = "";
    hourMask = hourMask + stMask.peekNext();
    hourMask = hourMask + stMask.peekSecondNext(); 
    
    //If the mask is hh:24
    if(hourMask == "24") {
    	stMask.getNext();
    	stMask.getNext();
    	return (arHeltal(hour) && thisHour >= 0  && thisHour < 24 );
    }  
    
    //If he mask is hh:12
    if(hourMask == "12") {
    	stMask.getNext();
    	stMask.getNext();
    	return (arHeltal(hour) && thisHour >= 1 && thisHour <= 12);
    }    
    else {
    	return (false);
    }
}

//-------------------------------------------
function parseMin (st, stMask) {
    var iMask = 0;
    min = "";
    if( (stMask.peekNext() == "m") && (stMask.peekSecondNext() == "i") ) {
    	stMask.getNext();
    	min = min + st.getNext();
    	stMask.getNext();
    	min = min + st.getNext(); 	
    }  
    thisMin = parseInt (min);   
    return (arHeltal(min) && min.length == 2 && thisMin >=  0 && thisMin <= 59);
}


function parseGrupp (st, maskSt) {
    mask1 = maskSt.peekNext(); mask2 = maskSt.peekSecondNext();
    if ((mask1 == "m") && (mask2 == "m") ) {return (parseMan(st, maskSt))};
    if (mask1 == "d") {return (parseDag(st, maskSt))};
    if (mask1 == "y") {return (parseAr(st, maskSt))};
    if (mask1 == "h") {return (parseTime(st, maskSt))};
    if ( (mask1 == "m") && (mask2 == "i") ) {return (parseMin(st, maskSt))};
}


function parseDelimiter(st, maskSt) {
    delT = maskSt.peekNext();
    if (delT == " " || delT == ";" || delT == "," || delT == "/" || delT == "-" || delT == ":") {
       return(st.getNext() == maskSt.getNext());
    } else {
    	return (true)
    }
}

/**
* Hinders input of '<' and '>' used in html tags and limits.
* Should be used on e.g. text areas, like onkeyup="checkStr(this, 512)".
* */
function checkStr(str, maxLength) {
	if(str.value.length>maxLength)
		str.value = str.value.substr(0, maxLength);
	if(str.value.match(/<|>/g) != null)
		str.value = str.value.replace(/<|>/g, '');
}

// end hide it -->

