var FormCheck = new Class({ Implements: [Options, Events], options: { tipsClass: 'fc-tbx', errorClass: 'fc-error', fieldErrorClass: 'fc-field-error', trimValue: false, validateDisabled: false, submitByAjax: false, ajaxResponseDiv: false, ajaxEvalScripts: false, onAjaxRequest: $empty, onAjaxSuccess: $empty, onAjaxFailure: $empty, display: { showErrors: 0, titlesInsteadNames: 0, errorsLocation: 1, indicateErrors: 1, indicateErrorsInit: 0, 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: "This field is required.", alpha: "This field accepts alphabetic characters only.", alphanum: "This field accepts alphanumeric characters only.", nodigit: "No digits are accepted.", digit: "Please enter a valid integer.", digitltd: "The value must be between %0 and %1", number: "Please enter a valid number.", email: "Please enter a valid email.", phone: "Please enter a valid phone.", url: "Please enter a valid url.", confirm: "This field is different from %0", differs: "This value must be different of %0", length_str: "The length is incorrect, it must be between %0 and %1", length_fix: "The length is incorrect, it must be exactly %0 characters", lengthmax: "The length is incorrect, it must be at max %0", lengthmin: "The length is incorrect, it must be at least %0", checkbox: "Please check the box", radios: "Please select a radio", select: "Please choose a value"
}, regexp: { required: /[^.*]/, alpha: /^[a-z ._-]+$/i, alphanum: /^[a-z0-9 ._-]+$/i, digit: /^[-+]?[0-9]+$/, nodigit: /^[^0-9]+$/, number: /^[-+]?\d*\.?\d+$/, email: /^[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i, phone: /^[\d\s ().-]+$/, url: /^(http|https|ftp)\:\/\/[a-z0-9\-\.]+\.[a-z]{2,3}(:[a-z0-9]*)?\/?([a-z0-9\-\._\?\,\'\/\\\+&amp;%\$#\=~])*$/i
}
}, initialize: function(form, options) {
    if (this.form = $(form)) {
        this.form.isValid = true; this.regex = ['length']; this.setOptions(options); if (typeof (formcheckLanguage) != 'undefined') this.options.alerts = $merge(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) { this.register(el); }, 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));
    }
}, register: function(el) {
    el.validation = []; el.getProperty("class").split(' ').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]); if (validators[i].match(/^confirm\[/)) {
                    var field = eval(validators[i].match(/^.+(\[.+\])$/)[1].replace(/([A-Z0-9\._-]+)/i, "'$1'")); if (this.form[field].validation.contains('required')) { el.validation.push('required'); }
                }
            }
            this.addListener(el);
        }
    }, this);
}, dispose: function(element) { this.validations.erase(element); }, addListener: function(el) {
    this.validations.push(el); el.errors = []; if (this.options.display.indicateErrorsInit) { this.validations.each(function(el) { if (!this.manageError(el, 'submit')) this.form.isValid = false; }, this); return true; }
    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() {
        (function() {
            if (!this.fxRunning && (el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value))
                this.manageError(el, 'blur')
        } .bind(this)).delay(100);
    } .bind(this))
    else if (this.isChildType(el) == true) {
        var nlButtonGroup = this.form.getElements('input[name="' + el.getProperty("name") + '"]'); nlButtonGroup.each(function(radio) {
            radio.addEvent('blur', function() { (function() { if ((el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value)) this.manageError(el, 'click'); } .bind(this)).delay(100); } .bind(this))
        }, this);
    }
}, validate: function(el) {
    el.errors = []; el.isOk = true; if (!this.options.validateDisabled && el.get('disabled')) return true; if (this.options.trimValue && el.value) el.value = el.value.trim(); 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-Z0-9\._-]+)/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; }
            }
            if (rule.match(/%[A-Z0-9\._-]+$/i) || (el.isOk && rule.match(/~[A-Z0-9\._-]+$/i))) {
                if (eval(rule.slice(1) + '(el)') == false) { el.isOk = false; }
            }
        }
    }, this); if (el.isOk) return true; else return false;
}, simpleValidate: function(el) {
    if (el.get('tag') == 'select' && el.selectedIndex <= 0) { 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;
}, 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;
}, validateConfirm: function(el, ruleArgs) {
    var confirm = ruleArgs[0]; if (el.value != this.form[confirm].value) {
        if (this.options.display.titlesInsteadNames)
            var msg = this.options.alerts.confirm.replace("%0", this.form[confirm].getProperty('title')); else
            var msg = this.options.alerts.confirm.replace("%0", confirm); el.errors.push(msg); return false;
    }
    return true;
}, validateDiffers: function(el, ruleArgs) {
    var differs = ruleArgs[0]; if (el.value == this.form[differs].value) {
        if (this.options.display.titlesInsteadNames)
            var msg = this.options.alerts.differs.replace("%0", this.form[differs].getProperty('title')); else
            var msg = this.options.alerts.differs.replace("%0", differs); el.errors.push(msg); return false;
    }
    return true;
}, isChildType: function(el) { return ($defined(el.type) && el.type == 'radio') ? true : false; }, 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; }
}, 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', "<span>" + obj[0].name + " : </span>" + 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', "<span>" + obj.name + " : </span>" + error).injectInside(this.form.element); }, this); }
    }
}, manageError: function(el, method) {
    var isValid = this.validate(el); if ((!isValid && el.validation.flatten()[0].contains('confirm[')) || (!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;
}, addError: function(obj) {
    if (!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 != true) {
        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('mouseup', function() { this.removeError(obj); } .bind(this)); }
            obj.element.setStyle('top', obj.getCoordinates().top - tips.getCoordinates().height + this.options.display.tipsOffsetY);
        } else { obj.errors.each(function(error) { new Element('p').set('html', error).injectInside(obj.element); }); }
        if (!this.options.display.fadeDuration || Browser.Engine.trident && Browser.Engine.version == 5 && this.options.display.errorsLocation < 2) { obj.element.setStyle('opacity', 1); } else {
            obj.fx = new Fx.Tween(obj.element, { 'duration': this.options.display.fadeDuration, 'ignore': true, 'onStart': function() { this.fxRunning = true; } .bind(this), 'onComplete': function() {
                this.fxRunning = false; if (obj.element && obj.element.getStyle('opacity').toInt() == 0) { obj.element.destroy(); obj.element = false; }
            } .bind(this)
            })
            if (obj.element.getStyle('opacity').toInt() != 1) obj.fx.start('opacity', 1);
        }
    }
    if (this.options.display.addClassErrorToField && this.isChildType(obj) == false) { obj.addClass(this.options.fieldErrorClass); obj.element = obj.element || true; }
}, 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);
}, removeError: function(obj) {
    this.alreadyIndicated = false; obj.errors = []; obj.isOK = true; window.removeEvent('resize', obj.event); if (this.options.display.errorsLocation >= 2 && obj.element) {
        new Fx.Tween(obj.element, { 'duration': this.options.display.fadeDuration
        }).start('height', 0);
    }
    if (!this.options.display.fadeDuration || Browser.Engine.trident && Browser.Engine.version == 5 && this.options.display.errorsLocation == 1 && obj.element) { this.fxRunning = true; obj.element.destroy(); obj.element = false; (function() { this.fxRunning = false } .bind(this)).delay(200); } else if (obj.element && obj.element != true) { obj.fx.start('opacity', 0); }
    if (this.options.display.addClassErrorToField && !this.isChildType(obj))
        obj.removeClass(this.options.fieldErrorClass);
}, focusOnError: function(obj) {
    if (this.options.display.scrollToFirst && !this.alreadyFocused && !this.isScrolling) {
        if (!this.options.display.indicateErrors || !this.options.display.errorsLocation) { var dest = obj.getCoordinates().top - 30; } else 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;
        }
        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;
    }
}, fixIeStuffs: function() {
    if (Browser.Engine.trident4) {
        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"; }
                }
            }
        }
    }
}, 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('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; }, 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.elementToRemove = this.alreadyIndicated; this.alreadyIndicated = false; this.form.isValid = true;
}, 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) $(this.options.ajaxResponseDiv).set('html', result); } .bind(this)
    }).send();
}, onSubmit: function(event) {
    this.reinitialize(); this.validations.each(function(el) { var validation = this.manageError(el, 'submit'); if (!validation) this.form.isValid = false; }, this); if (this.form.isValid) {
        if (this.options.submitByAjax) { new Event(event).stop(); this.submitByAjax(); }
    } else {
        new Event(event).stop(); if (this.elementToRemove && this.elementToRemove != this.firstError && this.options.display.indicateErrors == 1) { this.removeError(this.elementToRemove); }
        this.focusOnError(this.firstError)
    }
}
}); 