/* 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!

  1. Mensagem
  2. ...
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!

*
    *
  1. Mensagem
  2. *
* *
* @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(); } };