
/* ======= start configurações gerais ======= */

// limite de caracteres:
var max_textarea = 4000;
//var max_text = ;


// function generic validation:
// tipo de alerta:
// modo = 1; // caixa 'alert' comum do javascript;
// modo = 2; // caixa de alerta mediante um 'layer';
var modo = 1; // variável global;

// globais:
var set_black1;
var set_black2;

/* OBS: o modo 'layer' está inacabado devido a alguns bugs: a) dependendo do tamanho da página, o layer pode posicionar-se mais acima e ficar escondido (vide funções para pegar o scroll da página em www.howtocreate.co.uk/tutorials/javascript/browserwindow); b) algumas propriedades dos layer (como o z-index) não são compatíveis com alguns browser, como o WebTV. */

// define se black is 'on' ou 'off':
if(modo == 1){ set_black1 = ''; set_black2 = ''; }
else { set_black1 = '<b>'; set_black2 = '</b>'; }

/* ======= end configurações gerais ======= */



/* ======= start function myReplace ======= */

// Script: myReplace 1.0 - Data: 26.11.2006

// Em 'getString', pegamos o valor (sua string) enviada para a função;
function myReplace(getString){

// Criamos uma variável 'workString' para trabalhar a string;
workString = getString;

/* Criamos um array contendo todos os caracteres indesejados. Alguns deles exigem que sejam 'escapados' com uma barra invertida. */
replaceArray = new Array(' ', '\\', '/', '(', ')', ',', ';', '.', '-', '+', '/', '[', ']', ':', '*', '=');

/* Primeiramente, abrimos um loop 'for' para percorrer todos os caracteres do nosso replaceArray: */
for (aa=0; aa < replaceArray.length; aa++)
{

/* Pegamos seletivamente cada caractere do replaceArray: */
checkCharacter = replaceArray[aa];

/* Agora, abrimos um segundo loop, para percorrer todos os caracteres da nossa string: */
for(ff=0; ff < workString.length; ff++)
// o 'ff' acima deve-se que 'f' já é utilizado na função principal;
{

// Pega a posição do caractere indesejado na string:
position = workString.indexOf(checkCharacter);

// Verifica se a posição foi obtida com sucesso (caractere encontrado):
if(position != "-1")
	{
	// Faz o replace;
	// Importante: a variável workString é "atualizada":
	workString = workString.replace(checkCharacter,"");
	}
else false; // se o caractere não foi encontrada, retorna false;

}// fecha o segundo loop;
}// fecha o primeiro loop;

// A instrução 'return' devolve a string limpada;
return workString;

}// fecha a função;

/* ======= end function myReplace ======= */



/* ======= start function generic validation ======= */

/* (rascunho) linha do form usada anteriormente:	<form name="formulario" action="teste.php"  method="post" onSubmit="return validateForm()"> */

/* Este script está em desenvolvimento e está adotando as propostas e "padrões" sugeridas por Er Galvão Abbot, articulista do iMasters.com.br . Leia seus artigos, em:
http://www.imasters.com.br/artigo/4585/php/validacao_de_formularios_-_parte_01_o_planejamento/

Dúvidas: Fabiano Donato, fabianodonato@gmail.com
*/

/*	var fValida (primeiros 8 caracteres) and var fLabel (últimos)

	Fiz algumas poucas alterações na sua proposta:

	1 : (R)equerido ou não
	2 : (L)etras, (N)úmeros ou (A)mbos
	3 e 4 : Mínimo de caracteres exigido
	5 a 8 : Tipo de Validação - TELE (Telefone), DTNS (Data de Nascimento), DTFT (Data Futura), MAIL (Email), PWD1 (Senha), PWD2 (Senha Consistência)
			Outros: validação específica - usando o mesmo setor (5.º ao 8.º), poderemos usar outro "código" (número ou letras), destinado a incrementar no script alguma validação específica para um determinado site.
	9.º caractere em diante : Rótulo do campo
*/

/*
Mantive os 2 loops iniciais, que checam e recolhem os elements forms.
Do script original, eliminei: a requisição Ajax para a data; as mensagens de erro; o bloqueio dos inputs preenchidos; entre outros detalhes.

No padrão de codificação do atributo 'name', alterei de EMIL para MAIL, e deixo o script montado de forma a se acrescentar facilmente novos códigos de validação específica, caso surja a necessidade.

Adotei uma simplificação: depois dos loops, o que faço é partir "diretamente" para a validação; a cada validação negativa, jogo a mensagem de erro (específica em cada caso) num array.
No fim, então, pego o array e exibo o alerta.

OBS: acrescentei um rápido debug (array fDebug), para checagem da tríade type-rótulo_name-value.

O que falta - planos para a continuação deste script:
	- melhorar a validação dos campos 'text' (restringir caracteres inválidos, etc);
	- validação de email, cpf, cnpj, cidade, etc;
	- checagem dos campos 'select' (normalmente dentro do loop);
*/

function validateForm(){


/* necessário usar um counter, porque ao selecionar um radio, o outro ficará 'desmarcado' e resultará num alerta */
/*
for (i=0;i<document.forms[0].RL03xxxxEspécie.length;i++){
if (document.forms[0].RL03xxxxEspécie[i].type == "radio"){
if (document.forms[0].RL03xxxxEspécie[i].checked == false){
alert("ENFIM!");
}
}
}
*/


/*

function validaForm(){
var controle = 0;
for (i=0;i<document.enquete.elements.length;i++){
if (document.enquete.elements[i].type == "radio"){
if (document.enquete.elements[i].checked == true){
controle++;
}
}
}
if (controle <= 0){
alert("Selecione uma das opções");
return false;
}
}

*/





/* Funcionou assim:

for (i=0;i<document.forms[0].elements.length;i++){
if (document.forms[0].elements[i].type == "radio"){
if (document.forms[0].elements[i].checked == false){
alert("ENFIM!");
}
}
}

for (i=0;i<document.forms[0].RL03xxxxEspécie.length;i++){
if (document.forms[0].RL03xxxxEspécie[i].type == "radio"){
if (document.forms[0].RL03xxxxEspécie[i].checked == false){
alert("ENFIM!");
}
}
}

*/





/* Array que vai recolher os principais objetos para debug: type ('type'), rótulo (parte de 'name') e value (digitado pelo usuário). */
// var fDebug = new Array();

/* Array que vai recolher os campos não preenchidos corretamente pelo usuário e as mensagens de alerta: */
var fAlert = new Array();

/* setamos se o alerta deve ser disparado, caso a validação de algum campo não tenha sido cumprida: */
var alerta = false;

/* Declaração de uma variável para economizar tempo e prováveis erros de digitação. A variável 'f' aqui representa o objeto DOM HTML form */

//d = document.formulario; ANTERIOR, onde 'formulario' era o nome do form;

f=document.forms[0]; // 'f' de form;
// ALERTA: forms (800 mil no Google) ou form (400 mil);

/* ALERTA 2: o "perigo" de se estabelecer variáveis de "uma" só letra é que esta mesma letra pode, por descuido, ser usada depois num loop for, resultado num bug de difícil identificação. */

// String que conterá a(s) mensagem(ens) de erro;
// errMsg=''; // NÃO USEI POR ENQUANTO;

// Contagem de erros;
// errCnt=0; // NÃO USEI POR ENQUANTO;

// Campos que não devem ser checados;
dontCheck = new Array('submit', 'reset', 'button', 'image');
/* before:
dontCheck = new Array('hidden', 'submit', 'reset', 'button', 'image', 'radio', 'select-one', 'select-multiple', 'checkbox'); */

for(e=0; e < f.elements.length; e++)
/* Com 'elements.length', obtém-se o tamanho exato do array. Isso é importante, porque sem fixar o limite exato no loop 'for', pode dar erro se o JS tentar por exemplo dar um echo sobre um elemento inexistente, tipo:  alert(f.elements[20].type);  */

/* ALERTA: 'length' (ao contrário de 'right') termina com 'th': caso seja digitado errado, o debug do Console de JS do Firefox NÃO aponta-o! */

{

/* setamos a validacao de cada elemento, em cada ciclo do loop: */
var validacao = true;

/* 'skip': definimos uma variável booleana (uma variável de controle aqui) que informará ao loop se o elemento deve ser ignorado (true) ou validado (false).
Isso por que o loop varre todos os elementos do form (text, select, submit, etc) e atribui um índice para cada um deles, incluindo aqueles que não desejamos que passem pela rotina de validação. */

skip = false;

/* o comando 'type' identifica o tipo de elemento que foi setado no campo do input, como: <input type="text"... >

Outra possibilidade de identificação, no código, seria algo como:
if ((document.formx.elements.type == 'text')...	*/

fType = f.elements[e].type;


// checa o array de types que não devem ser validados:
for (d=0; d < dontCheck.length; d++)
	{
	if (fType == dontCheck[d]) { skip = true; }
	}

/* Verificamos se o tipo do elemento está definido e se a variável boolena (skip) é falsa (não ignorar o elemento, mas validá-lo). */

// if(skip == false)...
if (fType && !skip)
	{
	/* Armazenamos em fLabel o 'rótulo' do campo, pegando uma substring do atributo 'name' que iniciará no 9.º caractere. Dependendo da forma como faremos os alertas de preenchimento, talvez essa informação deva merecer depois um outro tipo de tratamento. */
	fLabel = f.elements[e].name.substr(8);

/* Pegamos os primeiros 8 caracteres (o código completo de validação). Creio que, para enxugar o script, essa variável poderia ser suprimida. */
	fValida = f.elements[e].name.substr(0,8);

// 1.º caractere de controle: se é ou não campo (R)equerido;
	isReq = fValida.substr(0,1);

/* 2.º caractere de controle: tipo do valor esperado, se (L)etras, (N)úmeros ou (A)mbos; */
	vTypeExpected = fValida.substr(1,1);

/* 3.° a 4.° caractere de controle: número mínimo de caracteres;
  (a classe Number serve para criar objetos que têm dados numéricos como valor: pega uma string que contém números e converte em números.) */
	rLen = Number(fValida.substr(2,2));

/* 5.° a 8.° caractere de controle: tipo (código) de validação; */
	vType = fValida.substr(4,4);

// Valor do campo (informado pelo usuário no input ="value"):
fVal = f.elements[e].value;

// Número de caracteres do valor acima:
fLen = fVal.length; // cuidado: 'fLen' não é 'rLen';

// fim da captura de variáveis e parâmetros;



// debug:
/* Em JS, o array não pode receber valores automaticamente, como:
	meuArray[]= "valor 1";
	meuArray[]= "valor 2"; // adicionando direto como em PHP;
Então, usamos o método push (os índices são criados automaticamente):
OBS: também é possível adicionar vários valores simultaneamente:
	meuArray.push(var1, var2, var3, var4);
*/
// fDebug.push(fType); // adicionando o "type";
// fDebug.push(fLabel); // adicionando o "rótulo" name;
// fDebug.push(fVal); // adicionando o "value" digitado;



// Armazena a primeira senha digitada:
/* pulei */


// start: começa a validação;



/*
//<input type="file"
if(fType == 'file')
{
alert ("file");
exit;
}
*/


// Campos para validação (acrescidos por garantia):
if(fType == 'text' || fType == 'textarea' || fType == 'file' || fType == 'password' || fType == 'radio' || fType == 'select-one' || fType == 'select-multiple')
{

// Validação do email:
// se contém arroba (onde fVal=value e vType=código):
var arroba = fVal.indexOf("@");
if(vType == "MAIL" && arroba == -1)
{ arroba = 0; validacao = false; }
else
{ arroba = 1; }

// se campo não é obrigatório, mas "digitou" um valor inválido:
// != Diferente
/* vou retirar abaixo provisoriamente, porque DDD e Fone são checados separadamente... */
if(fLen < rLen && fLen != ""){ validacao = false; } else false;

// se campo é obrigatório e deixou vazio:
if(isReq == 'R' && fLen == "") { validacao = false; } else false;

// se campo é obrigatório e exige somente números:
/* envia value para a função (que retira caracteres selecionados) */

if(isReq == 'R' && vTypeExpected == 'N')
{
	stringClean = myReplace(fVal);
	if(isNaN(stringClean))
	{
	validacao = false;
	}
	else false;
//	else { validacao1 = "Ok, é número!"; fAlert.push(stringClean); }
}
else false;

// por garantia (checar depois):
// if(fLen < rLen || arroba == 0)



    // novo (maio/2009): limite de caracteres do textarea:

    if(fType == 'textarea' && fLen > max_textarea)
    {
   	validacao = false;
    alert_textarea = true;
    }
    else
    {
    alert_textarea = false;
    }



// fim da validação;


// Definimos as mensagens de erro:

/* NÃO USEI ESTAS!
reqMsg = "> O campo" + fLabel + " é obrigatório.\n";
minMsg = "> O campo" + fLabel + " deve conter no mínimo" + rLen + " caractere(s).\n";
invMsg = "> O campo" + fLabel + " não contém um valor válido.\n";
alfMsg = "> O campo" + fLabel + " deve conter apenas letras.\n";
numMsg = "> O campo" + fLabel + " deve conter apenas números.\n";
pncMsg = "> As senhas digitadas não conferem.\n";
*/

if (validacao == false)
{

// seta o alerta para true:
alerta = true;

if(fLen == "")
{
adiciona = "O campo " + set_black1 + fLabel + set_black2 + " deve ser preenchido.";
}
else if(fLen != "" && arroba == 0)
{
adiciona = "O campo " + set_black1 + fLabel + set_black2 + " não contém um valor válido.";
}

//novo: textarea:
else if(alert_textarea === true)
{
adiciona = "O campo " + set_black1 + fLabel + set_black2 + " ultrapassou o limite de caracteres permitido (" + max_textarea + ").";
}

else
{
adiciona = "O campo " + set_black1 + fLabel + set_black2 + " não contém um valor válido.";
}

// Jogamos então no array as mensagens de erro:
fAlert.push(adiciona);

}// fim das mensagens de erro;
else false;

// errCnt++; // não estou usando;
}

} // fecha o if !skip;
} // fecha o loop for: array elements;


/* debug opcional:
if(alerta == true){ alert ("Validação Off !")}
else { alert ("Validação OK!")};
*/


/* debug final: exibe um alert com a tríade type-name_rótulo-value */
/*
ATENÇÃO: para este debug, funcionar, descomentar as linhas:

119:	// var fDebug = new Array(); // logo no início da função;
213:	// fDebug.push(fType); // adicionando o "type";
	// fDebug.push(fLabel); // adicionando o "rótulo" name;
	// fDebug.push(fVal);

temp = "Relação:";
for (d=0; d < fDebug.length; d=d+3)
	{
temp += "\n";
temp += fDebug[d];
temp += " - ";
temp += fDebug[d+1];
temp += " - ";
temp += fDebug[d+2];
	}
alert(temp);
*/


// Parte final:


// Debug: descomentar, para SUPRIMIR a validação e o alerta:
//alerta = false;



if (alerta == false)
{
// submete o form:
document.forms[0].submit();
}
else
{
// exibe o alerta:

// tipo de alerta (descrição no topo deste script):
if(modo == 1)
{
var mensagem = "Formulário:\n";

for (d=0; d < fAlert.length; d++)
	{
	mensagem += "\n";
	mensagem += fAlert[d];
	}
	mensagem += "\n";
alert(mensagem);
}

else // modo == 2;
{

var mensagem = ""; // necessário, para concatenar depois;
for (d=0; d < fAlert.length; d++)
	{
	mensagem += "<div style='line-height: 20px;'>";
	mensagem += fAlert[d];
	mensagem += "</div>";
	}

// formatação do layer - início:
var code1 = '<div class="super_layer">\
\<table border="0" align="center" width="100%" height="100%"><tr><td valign="middle" height="100%">\
\<table border="0" align="center" width="250"><tr><td valign="middle" height="120" class="cell_alert">\
\<div style="font-family: arial; font-size: 12px; letter-spacing: 1px; text-align: center; padding-top: 10px;"><b>Formulário:</b></div>\
\<br>';

// formatação do layer - final:
var code2 = '<div style="font-size: 17px; ">&nbsp;</div>\
\<div align="center"><a href="javascript:Ok()" class="button_ok"><b>OK</b></a></div>\
\<div style="font-size: 10px;">&nbsp;</div>\
\</td>\
\</tr></table>\
\</td></tr></table>\
\</div>'; // fecha o super_layer;

	var exibeLayer = code1 + mensagem + code2;
	var x=document.getElementById("layer_alert")
	// adicionei o 'return':
	x.innerHTML=exibeLayer
}

} // fecha condicional da "Parte final";

} // fecha a função validateForm();


// FUNÇÃO 'OK', para fechar o layer de alerta:
function Ok()
{
	var o=document.getElementById("layer_alert")
	o.innerHTML=''
}


/* ======= end function generic validation ======= */

