var FormCheck = new Class({
Implements: [Options, Events],
options : {
tipsClass: 'tipsbox', //tips error class
errorClass: 'error_f', //div error class
fieldErrorClass: 'fc-field-error', //error class for elements
submitByAjax : false, //false : standard submit way, true : submit by ajax
ajaxResponseDiv : false, //element to inject ajax response into (can also use onAjaxSuccess) [cronix]
ajaxEvalScripts : false, //use evalScripts in the Request response [cronix]
onAjaxRequest : $empty, //Function to fire when the Request event starts
onAjaxSuccess : $empty, //Function to fire when the Request receives . Args: response [the request response] - see Mootools docs for Request.onSuccess
onAjaxFailure : $empty, //Function to fire if the Request fails
display : {
showErrors : 1,
errorsLocation : 1,
indicateErrors : 1,
keepFocusOnError : 0,
checkValueIfEmpty : 1,
addClassErrorToField : 0,
fixPngForIe : 1,
replaceTipsEffect : 1,
flashTips : 0,
closeTipsButton : 1,
tipsPosition : "right",
tipsOffsetX : -45,
tipsOffsetY : 0,
listErrorsAtTop : false,
scrollToFirst : true,
fadeDuration : 300
},
alerts : {
required: "Bu alan gerekli.",
alpha: "Bu alanda sadece alfabetik karakterler kabul edilmektedir.",
alphanum: "Bu alanda sadece alfanumerik karakterler kabul edilmektedir.",
nodigit: "Basamaklar kabul edilmemektedir.",
digit: "Lütfen geçerli bir tam sayı girin.",
digitmin: "Sayı en az %0 olmalıdır",
digitltd: "Değer %0 ve %1 arasında olmalıdır",
number: "Lütfen geçerli bir numara girin.",
email: "Lütfen geçerli bir E-mail girin..",
phone: "Lütfen geçerli bir telefon numarası girin.",
domain: "Geçersiz Domain formatı, sadece rakam ve harf kabul edilmektedir ve - space, boşluk türkçe karakterler vb., kabul edilmemektedir.",
url: "Lütfen geçerli bir url girin.",
confirm: "Bu alan %0 dan farklıdır",
differs: "Bu değer %0 dan farklı olmalıdır",
length_str: "Uzunluk hatalı, %0 ve %1 arasında olmalıdır",
lengthmax: "Uzunluk hatalı, maksimum %0 olmalıdır",
lengthmin: "Uzunluk hatalı, en az %0 olmalıdır",
checkbox: "Lütfen kutucuğu kontrol edin",
radios: "Lütfen kutucuğu kontrol edin",
select: "Lütfen bir değer seçin"
},
regexp : {
required : /[^.* ]/,
alpha: /^(?! +$)[a-z.,_ -]+$/i,
alphanum : /^(?! +$)[a-z\d,_ -]+$/i,
digit : /^(?! +$)[\dd.,_ -]+$/,
nodigit : /^(?! +$)\D+$/,
number : /^(?! $)[-+]?\d*\.?\d+$/,
phone : /^(?! $)[\d\s ().-]+$/,
domain: /^[a-z\d\-]+$/i,
email : /^(?! $)[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i,
url : /^(?! $)(http|https|ftp)\:\/\/[a-z0-9\-\.]+\.[a-z]{2,3}(:[a-z0-9]*)?\/?([a-z0-9\-\._\?\,\'\/\\\+&%\$#\=~])*$/i
}
},
/*
Constructor: initialize
Constructor
Add event on formular and perform some stuff, you now, like settings, ...
*/
initialize : function(form, options) {
if (this.form = document.id(form)) {
this.form.isValid = true;
this.regex = ['length'];
this.setOptions(options);
//internalization
if (typeof(formcheckLanguage) != 'undefined') this.options.alerts = formcheckLanguage;
this.validations = [];
this.alreadyIndicated = false;
this.firstError = false;
var regex = new Hash(this.options.regexp);
regex.each(function(el, key) {
this.regex.push(key);
}, this);
this.form.getElements("*[class*=validate]").each(function(el) {
el.validation = [];
var classes = el.getProperty("class").split(' ');
classes.each(function(classX) {
if(classX.match(/^validate(\[.+\])$/)) {
var validators = eval(classX.match(/^validate(\[.+\])$/)[1]);
for(var i = 0; i < validators.length; i++) {
el.validation.push(validators[i]);
}
this.register(el);
}
}, this);
}, this);
this.form.addEvents({
"submit": this.onSubmit.bind(this)
});
if(this.options.display.fixPngForIe) this.fixIeStuffs();
document.addEvent('mousewheel', function(){
this.isScrolling = false;
}.bind(this));
}
},
/*
Function: register
Private method
Add listener on fields
*/
register : function(el) {
this.validations.push(el);
el.errors = [];
if (el.validation[0] == 'submit') {
el.addEvent('click', function(e){
this.onSubmit(e);
}.bind(this));
return true;
}
if (this.isChildType(el) == false) el.addEvent('blur', function(e) {
if((el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value)) this.manageError(el, 'blur');
}.bind(this))
//We manage errors on radio
else if (this.isChildType(el) == true) {
//We get all radio from the same group and add a blur option
var nlButtonGroup = $ES('input[name="'+ el.getProperty("name") +'"]', this.form);
nlButtonGroup.each(function(radio){
radio.addEvent('blur', function(){
if((el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value)) this.manageError(el, 'click');
}.bind(this))
},this);
}
},
/*
Function: validate
Private method
Dispatch check to other methods
*/
validate : function(el) {
el.errors = [];
el.isOk = true;
//On valide l'lment qui n'est pas un radio ni checkbox
el.validation.each(function(rule) {
if(this.isChildType(el)) {
if (this.validateGroup(el) == false) {
el.isOk = false;
}
} else {
var ruleArgs = [];
if(rule.match(/^.+\[/)) {
var ruleMethod = rule.split('[')[0];
ruleArgs = eval(rule.match(/^.+(\[.+\])$/)[1].replace(/([A-Z\.]+)/i, "'$1'"));
} else var ruleMethod = rule;
if (this.regex.contains(ruleMethod) && el.get('tag') != "select") {
if (this.validateRegex(el, ruleMethod, ruleArgs) == false) {
el.isOk = false;
}
}
if (ruleMethod == 'confirm') {
if (this.validateConfirm(el, ruleArgs) == false) {
el.isOk = false;
}
}
if (ruleMethod == 'differs') {
if (this.validateDiffers(el, ruleArgs) == false) {
el.isOk = false;
}
}
if (el.get('tag') == "select" || (el.type == "checkbox" && ruleMethod == 'required')) {
if (this.simpleValidate(el) == false) {
el.isOk = false;
}
}
}
}, this);
if (el.isOk) return true;
else return false;
},
/*
Function: simpleValidate
Private method
Perform simple check for select fields and checkboxes
*/
simpleValidate : function(el) {
if (el.get('tag') == 'select' && (el.options[el.selectedIndex].text == el.options[0].text)) {
el.errors.push(this.options.alerts.select);
return false;
} else if (el.type == "checkbox" && el.checked == false) {
el.errors.push(this.options.alerts.checkbox);
return false;
}
return true;
},
/*
Function: validateRegex
Private method
Perform regex validations
*/
validateRegex : function(el, ruleMethod, ruleArgs) {
var msg = "";
if (ruleArgs[1] && ruleMethod == 'length') {
if (ruleArgs[1] == -1) {
this.options.regexp.length = new RegExp("^[\\s\\S]{"+ ruleArgs[0] +",}$");
msg = this.options.alerts.lengthmin.replace("%0",ruleArgs[0]);
} else if(ruleArgs[0] == ruleArgs[1]) {
this.options.regexp.length = new RegExp("^[\\s\\S]{"+ ruleArgs[0] +"}$");
msg = this.options.alerts.length_fix.replace("%0",ruleArgs[0]);
} else {
this.options.regexp.length = new RegExp("^[\\s\\S]{"+ ruleArgs[0] +","+ ruleArgs[1] +"}$");
msg = this.options.alerts.length_str.replace("%0",ruleArgs[0]).replace("%1",ruleArgs[1]);
}
} else if (ruleArgs[0] && ruleMethod == 'length') {
this.options.regexp.length = new RegExp("^.{0,"+ ruleArgs[0] +"}$");
msg = this.options.alerts.lengthmax.replace("%0",ruleArgs[0]);
} else {
msg = this.options.alerts[ruleMethod];
}
if (ruleArgs[1] && ruleMethod == 'digit') {
var regres = true;
if (!this.options.regexp.digit.test(el.value)) {
el.errors.push(this.options.alerts[ruleMethod]);
regres = false;
}
if (ruleArgs[1] == -1) {
if (el.value >= ruleArgs[0]) var valueres = true; else var valueres = false;
msg = this.options.alerts.digitmin.replace("%0",ruleArgs[0]);
} else {
if (el.value >= ruleArgs[0] && el.value <= ruleArgs[1]) var valueres = true; else var valueres = false;
msg = this.options.alerts.digitltd.replace("%0",ruleArgs[0]).replace("%1",ruleArgs[1]);
}
if (regres == false || valueres == false) {
el.errors.push(msg);
return false;
}
} else if (this.options.regexp[ruleMethod].test(el.value) == false) {
el.errors.push(msg);
return false;
}
return true;
},
/*
Function: validateConfirm
Private method
Perform confirm validations
*/
validateConfirm: function(el,ruleArgs) {
if (el.validation.contains('required') == false) {
el.validation.push('required');
}
var confirm = ruleArgs[0];
if(el.value != this.form[confirm].value){
msg = this.options.alerts.confirm.replace("%0",ruleArgs[0]);
el.errors.push(msg);
return false;
}
return true;
},
/*
Function: validateDiffers
Private method
Perform differs validations
*/
validateDiffers: function(el,ruleArgs) {
var confirm = ruleArgs[0];
if(el.value == this.form[confirm].value){
msg = this.options.alerts.differs.replace("%0",ruleArgs[0]);
el.errors.push(msg);
return false;
}
return true;
},
/*
Function: isChildType
Private method
Determine if the field is a group of radio or not.
*/
isChildType: function(el) {
var elType = el.type.toLowerCase();
if((elType == "radio")) return true;
return false;
},
/*
Function: validateGroup
Private method
Perform radios validations
*/
validateGroup : function(el) {
el.errors = [];
var nlButtonGroup = this.form[el.getProperty("name")];
el.group = nlButtonGroup;
var cbCheckeds = false;
for(var i = 0; i < nlButtonGroup.length; i++) {
if(nlButtonGroup[i].checked) {
cbCheckeds = true;
}
}
if(cbCheckeds == false) {
el.errors.push(this.options.alerts.radios);
return false;
} else {
return true;
}
},
/*
Function: listErrorsAtTop
Private method
Display errors
*/
listErrorsAtTop : function(obj) {
if(!this.form.element) {
this.form.element = new Element('div', {'id' : 'errorlist', 'class' : this.options.errorClass}).injectTop(this.form);
}
if ($type(obj) == 'collection') {
new Element('p').set('html',"" + obj[0].name + " : " + obj[0].errors[0]).injectInside(this.form.element);
} else {
if ((obj.validation.contains('required') && obj.errors.length > 0) || (obj.errors.length > 0 && obj.value && obj.validation.contains('required') == false)) {
obj.errors.each(function(error) {
new Element('p').set('html',"" + obj.name + " : " + error).injectInside(this.form.element);
}, this);
}
}
},
/*
Function: manageError
Private method
Manage display of errors boxes
*/
manageError : function(el, method) {
var isValid = this.validate(el);
if ((!isValid && el.validation.contains('required')) || (!el.validation.contains('required') && el.value && !isValid)) {
if(this.options.display.listErrorsAtTop == true && method == 'submit')
this.listErrorsAtTop(el, method);
if (this.options.display.indicateErrors == 2 ||this.alreadyIndicated == false || el.name == this.alreadyIndicated.name)
{
if(!this.firstError) this.firstError = el;
this.alreadyIndicated = el;
if (this.options.display.keepFocusOnError && el.name == this.firstError.name) (function(){el.focus()}).delay(20);
this.addError(el);
return false;
}
} else if ((isValid || (!el.validation.contains('required') && !el.value)) && el.element) {
this.removeError(el);
return true;
}
return true;
},
/*
Function: addError
Private method
Add error message
*/
addError : function(obj) {
if(this.options.display.showErrors == 1 && (!obj.element && this.options.display.indicateErrors != 0)) {
if (this.options.display.errorsLocation == 1) {
var pos = (this.options.display.tipsPosition == 'left') ? obj.getCoordinates().left : obj.getCoordinates().right;
var options = {
'opacity' : 0,
'position' : 'absolute',
'float' : 'left',
'left' : pos + this.options.display.tipsOffsetX
}
obj.element = new Element('div', {'class' : this.options.tipsClass, 'styles' : options}).injectInside(document.body);
this.addPositionEvent(obj);
} else if (this.options.display.errorsLocation == 2){
obj.element = new Element('div', {'class' : this.options.errorClass, 'styles' : {'opacity' : 0}}).injectBefore(obj);
} else if (this.options.display.errorsLocation == 3){
obj.element = new Element('div', {'class' : this.options.errorClass, 'styles' : {'opacity' : 0}});
if ($type(obj.group) == 'object' || $type(obj.group) == 'collection')
obj.element.injectAfter(obj.group[obj.group.length-1]);
else
obj.element.injectAfter(obj);
}
}
if (obj.element) {
obj.element.empty();
if (this.options.display.errorsLocation == 1) {
var errors = [];
obj.errors.each(function(error) {
errors.push(new Element('p').set('html', error));
});
var tips = this.makeTips(errors).injectInside(obj.element);
if(this.options.display.closeTipsButton) {
tips.getElements('a.close').addEvent('click', function(){
this.removeError(obj);
}.bind(this));
}
var offset = (Browser.Engine.trident) ? this.options.display.tipsOffsetY + 10 : this.options.display.tipsOffsetY;
obj.element.setStyle('top', obj.getCoordinates().top - tips.getCoordinates().height + offset);
} else {
obj.errors.each(function(error) {
new Element('p').set('html',error).injectInside(obj.element);
});
}
if (!Browser.Engine.trident5 && obj.element.getStyle('opacity') == 0)
new Fx.Morph(obj.element, {'duration' : this.options.display.fadeDuration}).start({'opacity':[1]});
else
obj.element.setStyle('opacity', 1);
}
if (this.options.display.addClassErrorToField && this.isChildType(obj) == false)
{
obj.addClass(this.options.fieldErrorClass);
}
},
/*
Function: addPositionEvent
Update tips position after a browser resize
*/
addPositionEvent : function(obj) {
if(this.options.display.replaceTipsEffect) {
obj.event = function(){
new Fx.Morph(obj.element, {
'duration' : this.options.display.fadeDuration
}).start({
'left':[obj.element.getStyle('left'), obj.getCoordinates().right + this.options.display.tipsOffsetX],
'top':[obj.element.getStyle('top'), obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY]
});
}.bind(this);
} else {
obj.event = function(){
obj.element.setStyles({
'left':obj.getCoordinates().right + this.options.display.tipsOffsetX,
'top':obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY
});
}.bind(this)
}
window.addEvent('resize', obj.event);
},
/*
Function: removeError
Private method
Remove the error display
*/
removeError : function(obj) {
this.firstError = false;
this.alreadyIndicated = false;
obj.errors = [];
obj.isOK = true;
window.removeEvent('resize', obj.event);
if (this.options.display.errorsLocation == 2)
new Fx.Morph(obj.element, {'duration' : this.options.display.fadeDuration}).start({ 'height':[0] });
if (!Browser.Engine.trident5) {
new Fx.Morph(obj.element, {
'duration' : this.options.display.fadeDuration,
'onComplete' : function() {
if (obj.element) {
obj.element.destroy();
obj.element = false;
}
}.bind(this)
}).start({ 'opacity':[1,0] });
} else {
obj.element.destroy();
obj.element = false;
}
if (this.options.display.addClassErrorToField && !this.isChildType(obj))
{
obj.removeClass(this.options.fieldErrorClass);
}
},
/*
Function: focusOnError
Private method
Create set the focus to the first field with an error if needed
*/
focusOnError : function (obj) {
if (this.options.display.scrollToFirst && !this.alreadyFocused && !this.isScrolling) {
if (this.alreadyIndicated.element) {
switch (this.options.display.errorsLocation){
case 1 :
var dest = obj.element.getCoordinates().top;
break;
case 2 :
var dest = obj.element.getCoordinates().top-30;
break;
case 3 :
var dest = obj.getCoordinates().top-30;
break;
}
this.isScrolling = true;
} else if (!this.options.display.indicateErrors) {
var dest = obj.getCoordinates().top-30;
}
if (window.getScroll.y != dest) {
new Fx.Scroll(window, {
onComplete : function() {
this.isScrolling = false;
obj.focus();
}.bind(this)
}).start(0,dest);
} else {
this.isScrolling = false;
obj.focus();
}
this.alreadyFocused = true;
}
},
/*
Function: fixIeStuffs
Private method
Fix png for IE6
*/
fixIeStuffs : function () {
if (Browser.Engine.trident4) {
//We fix png stuffs
var rpng = new RegExp('url\\(([\.a-zA-Z0-9_/:-]+\.png)\\)');
var search = new RegExp('(.+)formcheck\.css');
for (var i = 0; i < document.styleSheets.length; i++){
if (document.styleSheets[i].href.match(/formcheck\.css$/)) {
var root = document.styleSheets[i].href.replace(search, '$1');
var count = document.styleSheets[i].rules.length;
for (var j = 0; j < count; j++){
var cssstyle = document.styleSheets[i].rules[j].style;
var bgimage = root + cssstyle.backgroundImage.replace(rpng, '$1');
if (bgimage && bgimage.match(/\.png/i)){
var scale = (cssstyle.backgroundRepeat == 'no-repeat') ? 'crop' : 'scale';
cssstyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=\'' + bgimage + '\', sizingMethod=\''+ scale +'\')';
cssstyle.backgroundImage = "none";
}
}
}
}
}
},
/*
Function: makeTips
Private method
Create tips boxes
*/
makeTips : function(txt) {
var table = new Element('table');
table.cellPadding ='0';
table.cellSpacing ='0';
table.border ='0';
var tbody = new Element('tbody').injectInside(table);
var tr1 = new Element('tr').injectInside(tbody);
new Element('td', {'class' : 'tl'}).injectInside(tr1);
new Element('td', {'class' : 't'}).injectInside(tr1);
new Element('td', {'class' : 'tr'}).injectInside(tr1);
var tr2 = new Element('tr').injectInside(tbody);
new Element('td', {'class' : 'l'}).injectInside(tr2);
var cont = new Element('td', {'class' : 'c'}).injectInside(tr2);
var errors = new Element('div', {'class' : 'err'}).injectInside(cont);
txt.each(function(error) {
error.injectInside(errors);
});
if (this.options.display.closeTipsButton) new Element('a',{'class' : 'close'}).injectInside(cont);
// new Element('div', {'style' : "clear:both"}).injectInside(cont);
new Element('td', {'class' : 'r'}).injectInside(tr2);
var tr3 = new Element('tr').injectInside(tbody);
new Element('td', {'class' : 'bl'}).injectInside(tr3);
new Element('td', {'class' : 'b'}).injectInside(tr3);
new Element('td', {'class' : 'br'}).injectInside(tr3);
return table;
},
/*
Function: reinitialize
Private method
Reinitialize form before submit check
*/
reinitialize: function() {
this.validations.each(function(el) {
if (el.element) {
el.errors = [];
el.isOK = true;
if(this.options.display.flashTips == 1) {
el.element.destroy();
el.element = false;
}
}
}, this);
if (this.form.element) this.form.element.empty();
this.alreadyFocused = false;
this.firstError = false;
this.alreadyIndicated = false;
this.form.isValid = true;
},
/*
Function: submitByAjax
Private method
Send the form by ajax, and replace the form with response
*/
submitByAjax: function() {
var url = this.form.getProperty('action');
this.fireEvent('ajaxRequest');
new Request({
url: url,
method: this.form.getProperty('method'),
data : this.form.toQueryString(),
evalScripts: this.options.ajaxEvalScripts,
onFailure: function(instance){
this.fireEvent('ajaxFailure', instance);
}.bind(this),
onSuccess: function(result){
this.fireEvent('ajaxSuccess', result);
if(this.options.ajaxResponseDiv) document.id(this.options.ajaxResponseDiv).set('html',result);
}.bind(this)
}).send();
},
/* Function: onSubmit should be disabled for AWBS */
onSubmit: function(event) { }
/*
Function: onSubmit
Private method
Perform check on submit action
onSubmit: function(event) {
new Event(event).stop();
this.reinitialize();
this.validations.each(function(el) {
if(!this.manageError(el,'submit')) this.form.isValid = false;
}, this);
if(this.form.isValid){
if(this.options.submitByAjax){
this.submitByAjax()
} else {
if (Get_Cookie('ddc26eb46bd6f59d37848ac9bdbc59eb')) { Delete_Cookie('ddc26eb46bd6f59d37848ac9bdbc59eb'); }
else { this.form.submit() }
}
} else {
this.focusOnError(this.firstError);
this.form.submit()
}
}
*/
});