/*
JavaScript Form Checker
Ou comment arrêter définitivement les ennuis avec la vérification automatique des formulaires en javascript

Version : 
0.1.1

Date de la première version :
10.05.2006

Date de dernière modification : 
13.05.2006

Source de téléchargement :
http://quentinc.net/javascript/javascript-form-checker/

Copyright : 
© 2006, QuentinC http://quentinc.net/
Paternité - Pas d'Utilisation Commerciale - Partage des Conditions Initiales à l'Identique 2.0 
En outre, veuillez s'il vous plaît garder le présent commentaire de début de fichier intact.
Pour plus de détails, le contrat creative common est disponible à l'adresse : http://creativecommons.org/licenses/by-nc-sa/2.0/fr/

Le forum http://quentinc.net/forum/  se fera une joie d'accueillir vos questions, remarques, critiques, suggestions à propos de JavaScript Form Checker.

Contributeurs :
Aucun contributeur pour le moment. Vous êtes le bienvenu si cela vous tente.
*/

// Messages d'alerte
var MSGS = {
'start':"Veuillez s'il vous plaît ",
'email':"vérifier l'adresse e-mail que vous avez saisie.",
'url':"Vérifier l'adresse URL que vous avez saisie.",
'strminmax':"saisir entre %min et %max %strs.",
'strmin':"saisir au moins %strs.",
'str':"saisir %strs.",
'pwdminmax':"saisir un mot de passe contenant entre %min et %max caractères.",
'pwdcheck':"vérifier le mot de passe que vous avez saisi.",
'intminmax':"saisir un nombre entier compris entre %min et %max.",
'intmin':"saisir un nombre entier supérieur à %min.",
'int':"saisir un nombre entier.",
'floatminmax':"saisir un nombre compris entre %min et %max.",
'floatmin':"saisir un nombre supérieur à %min.",
'float':"saisir un nombre.",
'time':"saisir une heure valide au format %format.",
'date':"saisir une date valide au format %format.",
'datemin':"saisir une date valide au format %format et postérieure à %min.",
'dateminmax':"saisir une date valide au format %format et comprise entre %min et %max.",

'str-all':'votre nom',
'str-alpha':'votre nom alphabétiques',
'str-num':'chiffres',
'str-alphanum':'caractères alphanumériques',
'str-alphanumext':'chiffres, lettres, tirets et soulignés',
'str-nospace':'caractères. L\'espace est interdit',

'date-format6':"AAAA-MM-JJ",
'date-format5':"JJ/MM/AAAA",
'date-format14':"AAAA-MM-JJ HH:MM",
'date-format13':"JJ/MM/AAAA HH:MM",
'time-hm':"HH:MM",
'time-hms':"HH:MM:SS"
}; 


// Ajout de la fonction trim, fonctionnement similaire à la fonction du même nom en php ou en java.
String.prototype.trim = function () {
return this.replace(/^\s*/g,'').replace(/\s*$/g,'');
}

// Fonction de contrôle mail, date et url
function jsfcCheckMail (str) {
return /^[-a-z0-9_\.]{2,}@[-a-zA-Z0-9_]{2,}\.[a-z]{2,4}$/g .test(str);
}
function jsfcCheckURL (str) {
return (new RegExp("^http://[-a-zA-Z_0-9\\\\\\?\\!'\"&%\\+\\.]+$", "g")).test(str);
}
function jsfcCheckDateValue (str, fmt) {
var reg1 = new RegExp("^(\\d{2})[\\./](\\d{2})[\\./](\\d{4})$", "g");
var reg2 = new RegExp("^(\\d{4})-(\\d{2})-(\\d{2})$", "g");
// var reg3 = new RegExp("^[\\+-]\\d+ (year|month|week|day|hour|minute|second)s?$", "g");
var val = 0;
if ((fmt&1)!=0) val += (reg1.test(str)? 1:0);
if ((fmt&2)!=0) val += (reg2.test(str)? 2:0);
//if ((fmt&4)!=0) val += (reg3.test(str)? 4:0);

var d, m, y;
if (val == 0) return false;
//else if (val == 4) return true;
else if (val == 1) {
reg1 = new RegExp("^(\\d{2})[\\./](\\d{2})[\\./](\\d{4})$", "g");
var t = reg1.exec(str);
d = parseInt(t[1].replace(/^0+/g, ''));
m = parseInt(t[2].replace(/^0+/g, ''));
y = parseInt(t[3]);
}
else if (val == 2) {
reg2 = new RegExp("^(\\d{4})-(\\d{2})-(\\d{2})$", "g");
var t = reg2.exec(str);
d = parseInt(t[3].replace(/^0+/g, ''));
m = parseInt(t[2].replace(/^0+/g, ''));
y = parseInt(t[1]);
}


var date = new Date(y, m -1, d, 0, 0, 0, 0);
if (date.getFullYear()==y && date.getMonth() == m -1 && date.getDate() == d) return date;
else return false;
}

function jsfcCheckTimeValue (str, withSec) {
var t = str.split(':');
var h, m, s = 0;
if (withSec && t.length != 3) return false;
if (t.length < 2 || t.length > 3) return false;
h = parseInt(t[0].replace(/^0+/g,''));
m = parseInt(t[1].replace(/^0+/g,''));
if (t.length >= 3) s = parseInt(t[2].replace(/^0+/g,''));

if (s < 0 || s > 59 || m < 0 || m > 59 || h < 0 || h > 23) return false;
return new Array(h,m,s);
}

function jsfcCheckDate (str, format, tsMin, tsMax) {

if (!tsMin || tsMin<0) tsMin = null;
else tsMin = new Date(tsMin);
if (!tsMax || tsMax<0) tsMax = null;
else tsMax = new Date(tsMax);


if ((format&12)==8) {
var t = jsfcCheckTimeValue(str, ((format&16)!=0));
return !!t;
}
else if ((format&12)==4) {
var d = jsfcCheckDateValue(str, format);
if (!d) return false;
if (tsMin &&  d.getTime()<tsMin.getTime()) return false;
if (tsMax && d.getTime()>tsMax.getTime()) return false;
return true;
}
else if ((format&12)==12) {
var s = str.split('\\s+');
if (s.length != 2) return false;
return jsfcCheckDate(s[0], (format&3)+(format&16)+4, tsMin.getTime(), tsMax.getTime()) | jsfcCheckDate(s[1], (format&3)+(format&16)+8, tsMin.getTime(), tsMax.getTime());
}
}

function jsfcCheckNumber (str, floatval, min, max) {
if (floatval) {
var reg2 = new RegExp("^(\\d+|\\d+\\.\\d+)$", "g");
if (!reg2.test(str)) return false;
var n = parseFloat(str);
if (typeof(min)=="number" && n < min) return false;
if (typeof(max)=="number" && n > max) return false;
return true;
}
else {
var reg1 = new RegExp("^\\d+$", "g");
if (!reg1.test(str)) return false;
var n = parseInt(str);
if (typeof(min)=="number" && n < min) return false;
if (typeof(max)=="number" && n > max) return false;
return true;
}

}
function jsfcCheckString (str, format, min, max) {
if (min && min>0 && str.length<min) return false;
if (max && max>0 && str.length>max) return false;
if (!format || format == "all") return true;
else if (format == "alpha") return (new RegExp("^[a-zA-Z]+$","g")).test(str);
else if (format == "alphanum") return (new RegExp("^[a-zA-Z0-9]+$","g")).test(str);
else if (format == "num") return (new RegExp("^[0-9]+$","g")).test(str);
else if (format == "alphanumext") return (new RegExp("^[-a-zA-Z0-9_\\.]+$","g")).test(str);
else if (format == "nospace") return (new RegExp("^\\S+$","g")).test(str);
//else if (format == "serialnum" || format == "serialnumber") return (new RegExp("^\\d+(-\\d+)+$","g")).test(str);
}



// Interpréteur de commande JSFC
function jsfcCreate (name, param) {
var nget = "e = this.elements['"+name+"'];\r\n";
var rndvar = "jsfcTmpvar" + Math.floor(16777215 * Math.random());

var tab = param.toLowerCase().split('_');

if (tab[0] == "email") 
return nget + "if (!jsfcCheckMail(e.value)) { alert(\""+MSGS['start']+MSGS['email']+"\"); e.focus(); e.select(); return false; }\r\n";

else if (tab[0] == "passwordcheck")
return nget + " if (e.value != this.elements['"+tab[1]+"'].value) { alert(\""+MSGS['start']+MSGS['pwdcheck']+"\"); e.focus(); e.select(); return false; }\r\n";

else if (tab[0] == "url")
return nget + "if(!jsfcCheckURL(e.value)) { alert(\""+MSGS['start']+MSGS['url']+"\"); e.focus(); e.select(); return false; }\r\n";

else if (tab[0] == "string") {
var format = "all";
var min = 1, max = -1;
for (var i=1; i < tab.length; i++) {
if (isNaN(tab[i])) format = tab[i];
else {
if (max != -1) min = parseInt(tab[i]);
else max = parseInt(tab[i]);
}}
if (max != -1 && min != -1 && min>max) { var x = min; min=max; max=x; }

var msg = MSGS['start'];
if (min == 1 && max == -1) msg += MSGS['str'];
else if (max == -1) msg += MSGS['strmin'];
else msg += MSGS['strminmax'];
var fmtstr = (MSGS['str-'+format]? MSGS['str-'+format]:MSGS['str-all']);
msg = msg.split('%min').join(min).split('%max').join(max).split('%strs').join(fmtstr);

return nget + ' if (!jsfcCheckString(e.value, "'+format+'", '+min+', '+max+')) { alert("'+msg+'"); e.focus(); e.select(); return false; } ';
}

else if (tab[0] == "number" || tab[0] == "integer" || tab[0] == "float") {
var min = null, max = null, float = (tab[0]=="float");
for (var i=1; i < tab.length; i++) {
if (tab[i] == "float") float = true;
if (!isNaN(tab[i])) {
if (min == null) min = parseFloat(tab[i]);
else max = parseFloat(tab[i]);0
}}
if (min!=null && max!=null &&  min>max) { var x = min; min=max; max=x; }

var msg = MSGS['start'];
var nm = (float? 'float':'int');
if (min!=null && max == null)  nm += 'min';
else if (min != null && max != null) nm += 'minmax';
msg += MSGS[nm];
msg = msg.split('%min').join(min).split('%max').join(max);
return nget + ' if (!jsfcCheckNumber(e.value, '+float+', '+min+', '+max+')) { alert("'+msg+'"); e.focus(); e.select(); return false; } ';
}

else if (tab[0] == "password") {
var min = 5, max = 20;
var mindef = false;
for (var i=1; i < tab.length; i++) {
if (!isNaN(tab[i])) {
if (mindef) { min = parseInt(tab[i]); mindef = true; }
else max = parseInt(tab[i]);
}}
if (min>max) { var x = min; min=max; max=x; }

var msg = MSGS['start']+MSGS['pwdminmax'].split('%min').join(min).split('%max').join(max);
//var x = nget + ' if (e.value.length < '+min+' || e.value.length > '+max+')) { alert("'+msg+'"); e.focus(); e.select(); return false; } ';
return nget + ' if (e.value.length < '+min+' || e.value.length > '+max+') { alert("'+msg+'"); e.focus(); e.select(); return false; } ';
}

else if (tab[0] == "time") {
var ws = false;
if (tab.length >=2 && tab[1]=="withseconds") ws = true;
var msg = MSGS['start']+MSGS['time'].split('%format').join((ws? MSGS['time-hms']:MSGS['time-hm']));
var val = 8 + (ws? 16:0);
return nget + ' if (!jsfcCheckDate(e.value, '+val+', -1, -1)) { alert("'+msg+'"); e.focus(); e.select(); return false; } ';
}

else if (tab[0] == "date" || tab[0] == "datetime") {
var format = "fr";
var val = 4;
if (tab[0] == "datetime") val = 12;
var min = -1, max = -1;
for (var i=1; i < tab.length; i++) {
if (tab[i] == "now") { tab[i] = (new Date()).getTime(); }

if (isNaN(tab[i])) {
format = tab[i];
}
else {
if (min == -1) min = parseInt(tab[i]);
else max = tab[i];
}}
if (min!=-1 && max!=-1 && min>max) { var x = min; min=max; max=x; }
if (format == "us") val += 2;
else val += 1;

format = MSGS['date-format'+val];
var msg = MSGS['start'];
if (min != -1 && max != -1) msg += MSGS['dateminmax'];
else if (min != -1) msg += MSGS['datemin'];
else msg += MSGS['date'];
msg = msg.split('%format').join(format).split('%min').join((new Date(min)).toLocaleString()).split('%max').join((new Date(max)).toLocaleString());

return nget + ' if (!jsfcCheckDate(e.value, '+val+', '+min+', '+max+')) { alert("'+msg+'"); e.focus(); e.select(); return false; } ';
}


else if (tab[0].substring(0,7)=="emptyor") 
return nget + "if (e.value.length >0) { " + jsfcCreate(name, param.substring(7)) + " }\r\n";

alert("ERREUR : JavaScript Form Checker : Commande JSFC inconnue pour le champ " + name + " : " + param);
return "";
}



// Fonction d'initialisation JSFC
function jsfcInit () {
if (!document.forms) document.forms=document.getElementsByTagName('form');
for (var k = 0; k < document.forms.length; k++) {
var tab = document.forms[k].elements;
var checkCode = "";

for (var i=0; i < tab.length; i++) {
if (tab[i] ) {
var tag = tab[i].tagName.toLowerCase();
if ((tag == "input" || tag == "textarea" || tag=="select") && tab[i].className) {
var tab2 = tab[i].className.split(' ');
for (var n = 0; n < tab2.length; n++) {
if (tab2[n].substring(0,4).toLowerCase()=="jsfc") {
checkCode += jsfcCreate(tab[i].name, tab2[n].substring(4));
}}}}}

if (checkCode) {
//alert(checkCode);
document.forms[k].onsubmit = new Function("event", "var e;\r\n\r\n" + checkCode + "\r\n\r\nreturn true;");
}}

}



// Traitement de l'évènement onload automatique
if (window.addEventListener)
window.addEventListener('load', jsfcInit, false);
else if (window.attachEvent)
window.attachEvent('onload', jsfcInit);
else if (!window.onload)
window.onload = jsfcInit;
else
alert("ERREUR :  l'initialisation du module JavaScript Form Checker a échoué.");


