/*
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:
Observações!
Mensagem
...
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];// MUDEI AQUI
// 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
*
*
Observações!
*
*
Mensagem
*
*
*
* @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();
}
};