/*	w3FormValidation (2.3) - 02/02/2007	Por Leandro Vieira Pinho - http://leandro.w3invent.com.br		Para informações de uso deste add-on visite:	http://leandro.w3invent.com.br/addons/w3FormValidation/	Parâmetros que podem ser utilizados para ATIVAR ou DESATIVAR recursos deste add-on	var valida = new w3FormValidation(param1,param2,param3,param4,param5);	param1 {Array}    = Campos a serem validados.	param2 {string}   = Título do box das mensagens de erro. Padrão: Observações!	param3 {integer}  = Distância que o box terá em relação ao topo da página. Padrão: 0	param4 {boolean}  = Coloque false para não utilizar o "overlay" sobre o body. Padrão: true	param5 {boolean}  = Coloque false para o box não acompanhar a rolagem da página. Padrão: true	O código HTML gerado para exibir o box com as mensagens é o seguinte:		<div id="w3ShowMsgToUser">		<h3>Observações!</h3>		<ol>			<li>Mensagem</li>			<li>...</li>		</ol>		<input id="w3ShowMsgToUserBtnOk" value="Ok" type="button">	</div>		Você pode estilizá-lo através das CSS e deixá-lo como desejar.		Funções de terceiros utlizadas neste add-on		Função: getPageSize Autor: PPK	Função: getScrollingPosition Autor: James Edwards/Cameron Adams		Tipos de validação inspirado no JS Validation de Beenjamin Keen (.com)*//** * * @param {array} arrInfoVal informações sobre os campos a serem validados; tipo de validação * @param {string} strTitleMsgToUser título que será utilizado no box da mensagem * @param {int} intPageTopDistance valor que será concedido a propriedade top do box da mensagem * @param {boolean} boolEncobrirBody se usará um overlay sobre o body (TRUE) ou não * @param {boolean} boolFixMsgToUserInViewPort se o box irá acompanhar (TRUE) ou não o scrolling da página * */function w3FormValidation(arrInfoVal,strTitleMsgToUser,intPageTopDistance,boolEncobrirBody,boolFixMsgToUserInViewPort) {	// arrInfoVal informações sobre os campos a serem validados; tipo de validação	this.arrInfoVal = arrInfoVal;		// Mensagem que será utilizada com o título da box da mensagem - H3	if ( typeof strTitleMsgToUser == "undefined" ) {		this.strTitleMsgToUser = 'Observações!';	} else {		this.strTitleMsgToUser = strTitleMsgToUser;	}		// Se nenhum valor for informado para o parâmetro pageTopDistance, definimos-o como 0	if ( typeof intPageTopDistance == "undefined" ) {		intPageTopDistance = 0;	}	this.top = intPageTopDistance;		// Se nada for definido para o parâmetro boolEncobrirBody o valor padrão será TRUE	if ( typeof boolEncobrirBody == "undefined" ) {		this.boolEncobrirBody = true;	}		// Pegamos um Array com a localização do usuário na página, assim exibiremos o box da Mensagem no mesmo local em que ele está :)	var arrAtualScrollingPosition = this.getScrollingPosition();	// Pegamos apenas a localização do eixo Y, ou seja, a distância do local até o topo da página	this.atualScrollingPositionY = arrAtualScrollingPosition[1];		// Se nada for definido para o parâmetro boolFixMsgToUserInViewPort o valor padrão será TRUE	if ( typeof boolFixMsgToUserInViewPort == "undefined" ) {		boolFixMsgToUserInViewPort = true;		}	if ( boolFixMsgToUserInViewPort ) {		// Adicionamos a função fixMsgToUserInViewPort para o box da mensagem acompanhar o scrolling do usuário pela página		addEvent(window, 'scroll', this.fixMsgToUserInViewPort, false, [this.top]);	}};/** * Função que fixa o box da mensagem no viewport do browser * * @param {array} paraTopDistance valor que será concedido ao style.top */w3FormValidation.prototype.fixMsgToUserInViewPort = function(paramTopDistance) {	// Pegamos um Array com a localização do usuário na página, assim exibiremos o box da Mensagem no mesmo local em que ele está :)	var arrCorrenteScrollingPosition = w3FormValidation.prototype.getScrollingPosition();	// Pegamos apenas a localização do eixo Y, ou seja, a distância do local até o topo da página	var correnteScrollingPositionY = arrCorrenteScrollingPosition[1];	// Somente se o objeto - o box da mensagem - estiver na página	if ( $('w3ShowMsgToUser') ) {		$('w3ShowMsgToUser').style.top = correnteScrollingPositionY + parseInt(paramTopDistance,'') + 'px';	}};/** * Chama a função que validará os dados informados. Retorna TRUE se os dados forem válidos ou FALSE caso contrário. */w3FormValidation.prototype.start = function() {	// Atribui à varíavel VALIDA o resultado da validação TRUE/FALSE	var valida = this.validation(this.arrInfoVal);	// valor de retorno - TRUE/FALSE	return valida;};w3FormValidation.prototype.validation = function(arrParams) {	// Array que conterá as mensagens a serem exibidas ao usuário	var arrMsgToUser = [];	// Array que conterá o atributo ID dos campos informados	var arrFields = [];	// Booleano sobre o resultado da validação	var boolResultVal = true;	// Loop entre o Array - arrParams - passado como param da função	for ( i = 0; i < arrParams.length; i++ ) {			// O parâmetro é recebido da seguinte forma: tipo-de-validação,id-do-campo,mensagem		var arrFieldVal = arrParams[i].split(',');		var if_typeVal = true;		// Variáveis utilizados pelo tipo de validação condicional		var strCondition, arrCondition, strFieldToCheck, strValueToCheck, strFieldToCheckValue;		// Verificamos se o primeiro item do Array contém a condição if, mais precisamente: if:		while ( arrFieldVal[0].match("^if:") ) {			// Pegamos a condição informada e Retiramos a partícula if:			strCondition = arrFieldVal[0].replace("if:",""); 			// Verificamos se o tipo de campo será um radio button			// Para os radion buttons não é informado o ID do campo como os outros, mas sim o atributo NAME			// Precisamos também do ID do formulário em que o radio group se encontra			// Então, esta regra será informada assim: 'if:frmID:radioButtonName=valor,req,id do campo requerido,mensagem'			if ( strCondition.match(":") ) {				var arrFieldInfo = strCondition.split(":");				var strFormID = arrFieldInfo[0];				arrCondition = arrFieldInfo[1].split("=");				strFieldToCheck = arrCondition[0];				strValueToCheck = arrCondition[1];				for ( var r = 0; r < $(strFormID)[strFieldToCheck].length; r++) {					if ( $(strFormID)[strFieldToCheck][r].checked ) {						strFieldToCheckValue = $(strFormID)[strFieldToCheck][r].value;					}				}			} else {				// Separamos o campo e o valor				arrCondition = strCondition.split("=");				strFieldToCheck = arrCondition[0];				strValueToCheck = arrCondition[1];				// pegamos o valor do campo informado (para compará-lo ao valor informado)				strFieldToCheckValue = $(strFieldToCheck).value;			}			if ( strFieldToCheckValue != strValueToCheck ) {				if_typeVal = false;				break;			} else {				arrFieldVal.shift();			}		} // Fim do while match:^if				if ( !if_typeVal ) {			continue;		}		// tipo de validação para o campo		var typeVal   = arrFieldVal[0]; 		// id do campo a ser validado		var field     = arrFieldVal[1]; 		// mensagem a ser exibida ao usuário		var msgToUser = '';		// Se for uma validação do tipo: igual (dois campos com o mesmo valor)		// igual,campo-1,campo-2,mensagem		if ( arrFieldVal.length == 4 ) { 			// id do segundo campo a ser validado			var field2 = arrFieldVal[2];			// mensagem a ser exibida ao usuário			// Neste caso - tipo: igual - a mensagem é o 4º índice do Array			msgToUser = arrFieldVal[3];		} else {			// mensagem a ser exibida ao usuário			// Neste caso - para todos - a mensagem é o 2º índice do Array			msgToUser = arrFieldVal[2]; 		}		// Verificamos se há algum tipo de validação especial		// Validações especiais: length,range,...		if ( typeVal.match("^length=") ) {			var strLength_typeVal = typeVal;			typeVal = "length";		}		if ( typeVal.match("^range=") ) {			var strRange_typeVal = typeVal;			typeVal = "range";		}		// Verifica o tipo de validação e a realiza		switch(typeVal) {			// Valida os campos requeridos			case 'req' :				// Validação específica para os radion button				// Por que as coisas às vezes é tão chata?				// Para os radion buttons não é informado o ID do campo como os outros mas sim o atributo NAME				// Precisamos também do ID do formulário em que o radio group se encontra				// Então, esta regra será informada assim: 'req,formID:radioName,mensagem'				// Foi a melhor solução até o momento				if ( field.match(":") ) {					var arrFieldInfo = field.split(":");					var strFormID = arrFieldInfo[0];					var strRadioName = arrFieldInfo[1];					if ( typeof($(strFormID)[strRadioName].type) == "undefined" ) {						var boolRadioChecked = false;						for ( var r = 0; r < $(strFormID)[strRadioName].length; r++) {							if ( $(strFormID)[strRadioName][r].checked ) {								boolRadioChecked = true;							}						}						if ( !boolRadioChecked ) {							arrMsgToUser.push(msgToUser);							boolResultVal = false;						}					}				// Validação para os demais campos				} else {					// Remove a classe de erro. Se o campo tiver errado depois ela é inserida de novo.					removeClass($(field),'w3FieldError');					if ( !$(field).value ) {						arrMsgToUser.push(msgToUser);						arrFields.push($(field));						boolResultVal = false;					}				}			break;			// Valida os campos de e-mail			case 'email' :				// Remove a classe de erro. Se o carro tiver errado depois ela é inserida de novo.				removeClass($(field),'w3FieldError');				if ( !this.isEmail($(field).value) ) {					arrMsgToUser.push(msgToUser);					arrFields.push($(field));					boolResultVal = false;				}			break;			// Valida os campos de URL			case 'url' :				// Remove a classe de erro. Se o carro tiver errado depois ela é inserida de novo.				removeClass($(field),'w3FieldError');				if ( !this.isURL($(field).value) ) {					arrMsgToUser.push(msgToUser);					arrFields.push($(field));					boolResultVal = false;				}			break;			// O valor de dois campos devem ser iguais			case 'same' :				// Remove a classe de erro. Se o carro tiver errado depois ela é inserida de novo.				removeClass($(field),'w3FieldError');				if ( $(field).value != $(field2).value ) {					arrMsgToUser.push(msgToUser);					arrFields.push($(field));					boolResultVal = false;				}			break;			// O campo não pode ficar vazio e aceitará somente digítos [0-9]			// Não pode ficar vazio por que vazio não é um dígito :)			case 'digits' :				removeClass($(field),'w3FieldError');				if ( !$(field).value || $(field).value.match(/\D/) ) {					arrMsgToUser.push(msgToUser);					arrFields.push($(field));					boolResultVal = false;				}			break;			// O valor total de caracteres contidos no campo precisará ser igual ao valor informado			// ou poderá estar entre dois valores (x-y)			case 'length' :				removeClass($(field),'w3FieldError');				var strLength = strLength_typeVal.replace("length=","");				var arrLengthOrRange = strLength.match(/[^_]+/);				var arrLength = arrLengthOrRange[0].split("-");				// Se for especificado dois valores, verificamos se o total de caracteres está ente esses dois valors informados.				if ( arrLength.length == 2 ) {					if ( ( $(field).value.length < arrLength[0] ) || ( $(field).value.length > arrLength[1] ) ) {						arrMsgToUser.push(msgToUser);						arrFields.push($(field));						boolResultVal = false;					}				// Se for especificado um valor, verificamos se o total de caracteres é igual ao valor informado				} else {					if ( $(field).value.length != arrLength ) {						arrMsgToUser.push(msgToUser);						arrFields.push($(field));						boolResultVal = false;					}				}			break;			case 'range' :				// O campo precisa conter apenas dígitos [0-9]. Uma vez que será um range entre um número X e Y				// O valor do campo não poderá ser menor que primeiro número (X) e nem maior do que o segundo (Y)				removeClass($(field),'w3FieldError');				var strRange = strRange_typeVal.replace("range=","");				var arrRange = strRange.split("-");				if ( ( $(field).value.match(/\D/) ) || ( $(field).value <  Number(arrRange[0]) ) || ( $(field).value > Number(arrRange[1]) ) ) {					arrMsgToUser.push(msgToUser);					arrFields.push($(field));					boolResultVal = false;						}			break;			default :				alert('O tipo de validação desejado não é suportado ou desconhecido pelo w3FormValidation.\n\n-------------------------\nTipo de validação: ' + typeVal + '\n-------------------------\n\nConsulte a documentação do programa para maiores detalhes em:\n\nhttp://leandro.w3invent.com.br.');				return false;		} // fim do switch(typeVal);	} // fim do loop for	// Retorna TRUE se a validação foi bem sucedida	if ( boolResultVal ) {		return true;	} else {				// Os campos que não foram validados receberão a classe w3FieldError		for ( var x = 0; x < arrFields.length; x++ ) {			addClass(arrFields[x],'w3FieldError');		}				// Exibimos as mensagens sobre os erros de cada validação		this.showMsgToUser(arrMsgToUser);				// Retorna FALSE false para o bloquear o formulário		return false;	}}; // Validation/** * --------------------------------------------------------------------------------------------------------------------------  * Funções de validação  * --------------------------------------------------------------------------------------------------------------------------  *//** * Verifica se o e-mail é valido * @param {string} strEmail */w3FormValidation.prototype.isEmail = function(strEmail) {	return strEmail.search(/(\w[\w\.\+]+)@(.+)\.(\w+)$/) == 0;	};/** * Verifica se a URL é valida * @param {string} strURL */w3FormValidation.prototype.isURL = function(strURL) {	return strURL.search(/http(s)?:\/\/(www.)?([\w.]+)(\.\w{2,4})+$/) == 0;};/** * --------------------------------------------------------------------------------------------------------------------------  * Fim das Funções de validação  * --------------------------------------------------------------------------------------------------------------------------  *//** * Exibe todas as mensagens que deverão ser exibidas, gerando o seguinte código HTML * <div id="w3ShowMsgToUser"> *	<h3>Observações!</h3> *	<ol> *		<li>Mensagem</li> *	</ol> *	<input id="w3ShowMsgToUserBtnOk" value="Ok" type="button"> * </div> * @param {Array} arrMsgToUserParam */w3FormValidation.prototype.showMsgToUser = function(arrMsgToUserParam) {	// Caso já tenha o "box" com as mensagens, removemos.	this.closeMsgToUser('noFade');	// Correção do bug que exibe as tags select sobre o overlay no body	var arrTagSelect = $tags("select");	for ( var i = 0; i < arrTagSelect.length; i++ ) {		arrTagSelect[i].style.visibility = "hidden";	}		if ( this.boolEncobrirBody ) {		this.encobrirBody();		}		// Array de tags LI com a mensagem de erro como seu conteúdo	var arrTagsLi = [];	for ( i = 0; i < arrMsgToUserParam.length; i++ ) {		arrTagsLi.push($new('li',arrMsgToUserParam[i]));	}	// Inserimos o HTML desejado na página	$append($new('div','id=w3ShowMsgToUser',[$new('h3',this.strTitleMsgToUser),$new('ol',arrTagsLi),$new('form',$new('input',["type=button","value=Ok","id=w3ShowMsgToUserBtnOk"],""))]));	// Inicia o w3FadingOpacity para o box da mensagem	var fadeBox = new w3FadingOpacity('w3ShowMsgToUser',0,100,100);	fadeBox.start();	// Fixa o box da mensagem exatamente onde o usuário estiver na página	// Uma vez que o valor foi pego quando ele clicou no botão (chamou esta classe)	$('w3ShowMsgToUser').style.top = this.atualScrollingPositionY + this.top + 'px';	// Ao clicar no botão de Ok chama a função this.closeMsgToUser para remover o "box"	addEvent($('w3ShowMsgToUserBtnOk'),'click',this.closeMsgToUser, false);	// Focus no botão de OK		$('w3ShowMsgToUserBtnOk').focus();};w3FormValidation.prototype.encobrirBody = function() {	var sizesPage = getPageSize();	$append($new("div","id=w3BodyOverlay",''));	//$('w3BodyOverlay').style.width = arrayPageSize[0] + 'px';	$('w3BodyOverlay').style.height = arrayPageSize[1] + 'px';	var fadeOverlay = new w3FadingOpacity('w3BodyOverlay',0,80,100);	fadeOverlay.start();};/** * Remove as mensagens exibidas ao usuário e o código HTML gerado * @param {} */w3FormValidation.prototype.closeMsgToUser = function(strFade) {	if ( strFade != 'noFade' ) {		var fadeBox = new w3FadingOpacity('w3ShowMsgToUser',100,0,100,removerBoxes);		fadeBox.start();	}	function removerBoxes() {		$remove($('w3ShowMsgToUser'));		$remove($('w3BodyOverlay'));		// Correção do bug que exibe as tags select sobre o overlay no body		var arrTagSelect = $tags("select");		for ( var i = 0; i < arrTagSelect.length; i++ ) {			arrTagSelect[i].style.visibility = "visible";		}	}};/** * Retorna a localização do formulário na página * @return {array} scrollLeft,scrollTop * @author The JavaScript Anthology 101 Essential Tips, Tricks & Hacks */w3FormValidation.prototype.getScrollingPosition = function() {	// Variável que será retornada com os valores	var position = [0, 0];	// pageYOffset is used by Firefox and other Mozilla browsers, Safari, Konqueror, and Opera	if (typeof window.pageYOffset != 'undefined') {		position = [window.pageXOffset, window.pageYOffset];	}	// documentElement.scrollTop is used by IE 6 in standards-compliant mode	else if (typeof document.documentElement.scrollTop != 'undefined' && document.documentElement.scrollTop > 0) {		position = [document.documentElement.scrollLeft, document.documentElement.scrollTop];	}	// body.scrollTop is used by IE 5, and IE 6 in “Quirks” mode.	else if (typeof document.body.scrollTop != 'undefined') {		position = [document.body.scrollLeft, document.body.scrollTop];	}	return position;	/**	 * Notes	 * More recent Mozilla browsers (such as Firefox) also support documentElement.scrollTop and body.scrollTop, 	 * by the same render-ing mode rules as IE 6. Safari and Konqueror support body.scrollTop in either mode. 	 * Opera supports all three properties in any mode!	 */};//// getPageSize()// Returns array with page width, height and window width, height// Core code from - quirksmode.org// Edit for Firefox by pHaez//function getPageSize(){		var xScroll, yScroll;		if (window.innerHeight && window.scrollMaxY) {			xScroll = document.body.scrollWidth;		yScroll = window.innerHeight + window.scrollMaxY;	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac		xScroll = document.body.scrollWidth;		yScroll = document.body.scrollHeight;	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari		xScroll = document.body.offsetWidth;		yScroll = document.body.offsetHeight;	}		var windowWidth, windowHeight;	if (self.innerHeight) {	// all except Explorer		windowWidth = self.innerWidth;		windowHeight = self.innerHeight;	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode		windowWidth = document.documentElement.clientWidth;		windowHeight = document.documentElement.clientHeight;	} else if (document.body) { // other Explorers		windowWidth = document.body.clientWidth;		windowHeight = document.body.clientHeight;	}			// for small pages with total height less then height of the viewport	if(yScroll < windowHeight){		pageHeight = windowHeight;	} else { 		pageHeight = yScroll;	}	// for small pages with total width less then width of the viewport	if(xScroll < windowWidth){			pageWidth = windowWidth;	} else {		pageWidth = xScroll;	}	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight);};/** * --------------------------------------------------------------------------------------------------------------------------  * Inclusão do add-on w3FadingOpacity  * --------------------------------------------------------------------------------------------------------------------------  */function w3FadingOpacity(strID, intOpacityStart, intOpacityEnd, intFadeDuration, fnAfterFaded) {		this.intOffset = 10;	this.strID = strID; // String contendo o atributo ID do objeto desejado	this.intOpacityStart = intOpacityStart; // Valor - inteiro - inicial para o Fade	this.intOpacityEnd = intOpacityEnd; // Valor - inteiro - final para o Fade	this.intFadeDuration = intFadeDuration; // Valor - inteiro - para a duração do ciclo do Fade	this.fnAfterFaded = fnAfterFaded; // Nome da função a ser chamado após a conclusão do ciclco do Fade	this.intInterval = 0;	};/*** Aqui iniciamos todo o processo. A chamada inicial*/w3FadingOpacity.prototype.start = function() {	var thisClass = this;		this.intInterval = setInterval(function() { thisClass.fadeCycle(); }, (this.intFadeDuration / this.intOffset));	};/*** Aqui definimos o cliclo de vida do processo de Fading*/w3FadingOpacity.prototype.fadeCycle = function() {	if ( this.intOpacityEnd < this.intOpacityStart ) {		if ( this.intOpacityStart > this.intOpacityEnd ) {			this.intOpacityStart -= this.intOffset;		} else {			this.finalize();		}	} else {		if ( this.intOpacityStart < this.intOpacityEnd ) {			this.intOpacityStart += this.intOffset;		} else {			this.finalize();		}	}		this.setOpacity(this.intOpacityStart / 100);};w3FadingOpacity.prototype.setOpacity = function(intOpacity) {	if ( $(this.strID) ) {		$(this.strID).style.opacity = intOpacity;		$(this.strID).style.filter = "alpha(opacity=" + (intOpacity*100) + ")";	}};w3FadingOpacity.prototype.finalize = function() {	this.intOpacityStart = this.intOpacityEnd;	clearInterval(this.intInterval);	if ( this.fnAfterFaded ) {		this.fnAfterFaded();	}};